Changes On Branch ttmrichter-skins
Not logged in

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

Changes In Branch ttmrichter-skins Excluding Merge-Ins

This is equivalent to a diff from 861a885c74 to 1a6876db8d

2010-11-07
10:23
Merge from trunk. Leaf check-in: 1a6876db8d user: michael tags: ttmrichter-skins
2010-11-06
23:59
Add an undocumented --noverify option to the rebuild command to skip the verify_before_commit() sanity check. check-in: 6a11af1782 user: drh tags: trunk
2010-10-08
17:08
EDITED www/server.wiki fixed formating and created ticket (I don't see the ticket in commit) check-in: 3f49a84995 user: navratil tags: ttmrichter-skins
2010-09-16
14:00
Committing a merge. check-in: be5fd10aaf user: michael tags: ttmrichter-skins
2010-08-13
07:07
Trying to figure out how to get merge conflicts to actually show up. check-in: d8f8932ff2 user: michael tags: ttmrichter-skins
03:49
Merged with trunk. Leaf check-in: 861a885c74 user: michael tags: ttmrichter
03:30
Added build for FreeBSD using clang. check-in: b775af5045 user: michael tags: ttmrichter
2010-08-12
19:39
Reimplement the reconstruct command that was removed in the GPL to BSD license change. This resolves ticket [dfe1fc608a]. check-in: 3332895df8 user: bcsmith tags: trunk

Changes to Makefile.

    14     14   #    intended to direct the compilation below.
    15     15   #
    16     16   -include config.mk				# Configure if present.
    17     17   ifndef CONFIG_MK_COMPLETE
    18     18     include $(MAKEDIR)/linux-gcc-config.mk	# Default to linux-gcc.
    19     19   endif
    20     20   
    21         -#### The Tcl shell to run for test suites.
           21  +#### C Compile and options for use in building executables that 
           22  +#    will run on the target platform.  This is usually the same
           23  +#    as BCC, unless you are cross-compiling.  This C compiler builds
           24  +#    the finished binary for fossil.  The BCC compiler above is used
           25  +#    for building intermediate code-generator tools.
           26  +#
           27  +#TCC = gcc -O6
           28  +#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
           29  +TCC = gcc -g -Os -Wall
           30  +
           31  +# To add support for HTTPS
           32  +TCC += -DFOSSIL_ENABLE_SSL
           33  +
           34  +#### Extra arguments for linking the finished binary.  Fossil needs
           35  +#    to link against the Z-Lib compression library.  There are no
           36  +#    other dependencies.  We sometimes add the -static option here
           37  +#    so that we can build a static executable that will run in a
           38  +#    chroot jail.
           39  +#
           40  +LIB = -lz $(LDFLAGS)
           41  +
           42  +# If using HTTPS:
           43  +LIB += -lcrypto -lssl
           44  +
           45  +#### Tcl shell for use in running the fossil testsuite.
    22     46   #
    23     47   TCLSH = tclsh
    24     48   
    25     49   # You should not need to change anything below this line
    26     50   ###############################################################################
           51  +#
           52  +# Automatic platform-specific options.
           53  +HOST_OS!= uname -s
           54  +
           55  +LIB.SunOS= -lsocket -lnsl
           56  +LIB += $(LIB.$(HOST_OS))
           57  +
           58  +TCC.DragonFly += -DUSE_PREAD
           59  +TCC.FreeBSD += -DUSE_PREAD
           60  +TCC.NetBSD += -DUSE_PREAD
           61  +TCC.OpenBSD += -DUSE_PREAD
           62  +TCC += $(TCC.$(HOST_OS))
           63  +
    27     64   include $(SRCDIR)/main.mk
    28     65   

Added skins/default1/footer.html.

            1  +<div class="footer">
            2  +Fossil version $manifest_version $manifest_date
            3  +</div>
            4  +</body></html>

Added skins/default1/header.html.

            1  +<html>
            2  +<head>
            3  +<title>$<project_name>: $<title></title>
            4  +<link rel="alternate" type="application/rss+xml" title="RSS Feed"
            5  +      href="$baseurl/timeline.rss">
            6  +<link rel="stylesheet" href="$baseurl/style.css?blackwhite" type="text/css"
            7  +      media="screen">
            8  +</head>
            9  +<body>
           10  +<div class="header">
           11  +  <div class="logo">
           12  +    <img src="$baseurl/logo" alt="logo">
           13  +  </div>
           14  +  <div class="title"><small>$<project_name></small><br>$<title></div>
           15  +  <div class="status"><nobr><th1>
           16  +     if {[info exists login]} {
           17  +       puts "Logged in as $login"
           18  +     } else {
           19  +       puts "Not logged in"
           20  +     }
           21  +  </th1></nobr></div>
           22  +</div>
           23  +<div class="mainmenu"><th1>
           24  +html "<a href=''$baseurl$index_page''>Home</a> "
           25  +if {[anycap jor]} {
           26  +  html "<a href=''$baseurl/timeline''>Timeline</a> "
           27  +}
           28  +if {[hascap oh]} {
           29  +  html "<a href=''$baseurl/dir?ci=tip''>Files</a> "
           30  +}
           31  +if {[hascap o]} {
           32  +  html "<a href=''$baseurl/leaves''>Leaves</a> "
           33  +  html "<a href=''$baseurl/brlist''>Branches</a> "
           34  +  html "<a href=''$baseurl/taglist''>Tags</a> "
           35  +}
           36  +if {[hascap r]} {
           37  +  html "<a href=''$baseurl/reportlist''>Tickets</a> "
           38  +}
           39  +if {[hascap j]} {
           40  +  html "<a href=''$baseurl/wiki''>Wiki</a> "
           41  +}
           42  +if {[hascap s]} {
           43  +  html "<a href=''$baseurl/setup''>Admin</a> "
           44  +} elseif {[hascap a]} {
           45  +  html "<a href=''$baseurl/setup_ulist''>Users</a> "
           46  +}
           47  +if {[info exists login]} {
           48  +  html "<a href=''$baseurl/login''>Logout</a> "
           49  +} else {
           50  +  html "<a href=''$baseurl/login''>Login</a> "
           51  +}
           52  +</th1></div>

Added skins/default1/info.txt.

            1  +Title:       Plain Gray
            2  +Description: A black-and-white theme with the project title in a bar across the
            3  +	     top and no logo image.
            4  +Author:      Unknown.
            5  +

Added skins/default1/style.css.

            1  +/* General settings for the entire page */
            2  +body {
            3  +  margin: 0ex 1ex;
            4  +  padding: 0px;
            5  +  background-color: white;
            6  +  font-family: sans-serif;
            7  +}
            8  +
            9  +/* The project logo in the upper left-hand corner of each page */
           10  +div.logo {
           11  +  display: table-row;
           12  +  text-align: center;
           13  +  /* vertical-align: bottom;*/
           14  +  font-size: 2em;
           15  +  font-weight: bold;
           16  +  background-color: #707070;
           17  +  color: #ffffff;
           18  +  min-width: 200px;
           19  +}
           20  +
           21  +/* The page title centered at the top of each page */
           22  +div.title {
           23  +  display: table-cell;
           24  +  font-size: 1.5em;
           25  +  font-weight: bold;
           26  +  text-align: center;
           27  +  padding: 0 0 0 10px;
           28  +  color: #404040;
           29  +  vertical-align: bottom;
           30  +  width: 100%;
           31  +}
           32  +
           33  +/* The login status message in the top right-hand corner */
           34  +div.status {
           35  +  display: table-cell;
           36  +  text-align: right;
           37  +  vertical-align: bottom;
           38  +  color: #404040;
           39  +  font-size: 0.8em;
           40  +  font-weight: bold;
           41  +  min-width: 200px;
           42  +}
           43  +
           44  +/* The header across the top of the page */
           45  +div.header {
           46  +  display: table;
           47  +  width: 100%;
           48  +}
           49  +
           50  +/* The main menu bar that appears at the top of the page beneath the header */
           51  +div.mainmenu {
           52  +  padding: 5px 10px 5px 10px;
           53  +  font-size: 0.9em;
           54  +  font-weight: bold;
           55  +  text-align: center;
           56  +  letter-spacing: 1px;
           57  +  background-color: #404040;
           58  +  color: white;
           59  +}
           60  +
           61  +/* The submenu bar that *sometimes* appears below the main menu */
           62  +div.submenu {
           63  +  padding: 3px 10px 3px 0px;
           64  +  font-size: 0.9em;
           65  +  text-align: center;
           66  +  background-color: #606060;
           67  +  color: white;
           68  +}
           69  +div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
           70  +  padding: 3px 10px 3px 10px;
           71  +  color: white;
           72  +  text-decoration: none;
           73  +}
           74  +div.mainmenu a:hover, div.submenu a:hover {
           75  +  color: #404040;
           76  +  background-color: white;
           77  +}
           78  +
           79  +/* All page content from the bottom of the menu or submenu down to the footer */
           80  +div.content {
           81  +  padding: 0ex 0ex 0ex 0ex;
           82  +}
           83  +/* Hyperlink colors */
           84  +div.content a { color: #604000; }
           85  +div.content a:link { color: #604000;}
           86  +div.content a:visited { color: #600000; }
           87  +
           88  +/* Some pages have section dividers */
           89  +div.section {
           90  +  margin-bottom: 0px;
           91  +  margin-top: 1em;
           92  +  padding: 1px 1px 1px 1px;
           93  +  font-size: 1.2em;
           94  +  font-weight: bold;
           95  +  background-color: #404040;
           96  +  color: white;
           97  +}
           98  +
           99  +/* The "Date" that occurs on the left hand side of timelines */
          100  +div.divider {
          101  +  background: #a0a0a0;
          102  +  border: 2px #505050 solid;
          103  +  font-size: 1em; font-weight: normal;
          104  +  padding: .25em;
          105  +  margin: .2em 0 .2em 0;
          106  +  float: left;
          107  +  clear: left;
          108  +}
          109  +
          110  +/* The footer at the very bottom of the page */
          111  +div.footer {
          112  +  font-size: 0.8em;
          113  +  margin-top: 12px;
          114  +  padding: 5px 10px 5px 10px;
          115  +  text-align: right;
          116  +  background-color: #404040;
          117  +  color: white;
          118  +}
          119  +
          120  +/* The label/value pairs on (for example) the vinfo page */
          121  +table.label-value th {
          122  +  vertical-align: top;
          123  +  text-align: right;
          124  +  padding: 0.2ex 2ex;
          125  +}

Added skins/default2/footer.html.

            1  +<div class="footer">
            2  +Fossil version $manifest_version $manifest_date
            3  +</div>
            4  +</body></html>

Added skins/default2/header.html.

            1  +<html>
            2  +<head>
            3  +<title>$<project_name>: $<title></title>
            4  +<link rel="alternate" type="application/rss+xml" title="RSS Feed"
            5  +      href="$baseurl/timeline.rss">
            6  +<link rel="stylesheet" href="$baseurl/style.css?tan" type="text/css"
            7  +      media="screen">
            8  +</head>
            9  +<body>
           10  +<div class="header">
           11  +  <div class="title">$<title></div>
           12  +  <div class="status">
           13  +    <div class="logo"><nobr>$<project_name></nobr></div><br/>
           14  +    <nobr><th1>
           15  +     if {[info exists login]} {
           16  +       puts "Logged in as $login"
           17  +     } else {
           18  +       puts "Not logged in"
           19  +     }
           20  +  </th1></nobr></div>
           21  +</div>
           22  +<div class="mainmenu"><th1>
           23  +html "<a href=''$baseurl$index_page''>Home</a> "
           24  +if {[anycap jor]} {
           25  +  html "<a href=''$baseurl/timeline''>Timeline</a> "
           26  +}
           27  +if {[hascap oh]} {
           28  +  html "<a href=''$baseurl/dir?ci=tip''>Files</a> "
           29  +}
           30  +if {[hascap o]} {
           31  +  html "<a href=''$baseurl/leaves''>Leaves</a> "
           32  +  html "<a href=''$baseurl/brlist''>Branches</a> "
           33  +  html "<a href=''$baseurl/taglist''>Tags</a> "
           34  +}
           35  +if {[hascap r]} {
           36  +  html "<a href=''$baseurl/reportlist''>Tickets</a> "
           37  +}
           38  +if {[hascap j]} {
           39  +  html "<a href=''$baseurl/wiki''>Wiki</a> "
           40  +}
           41  +if {[hascap s]} {
           42  +  html "<a href=''$baseurl/setup''>Admin</a> "
           43  +} elseif {[hascap a]} {
           44  +  html "<a href=''$baseurl/setup_ulist''>Users</a> "
           45  +}
           46  +if {[info exists login]} {
           47  +  html "<a href=''$baseurl/login''>Logout</a> "
           48  +} else {
           49  +  html "<a href=''$baseurl/login''>Login</a> "
           50  +}
           51  +</th1></div>

Added skins/default2/info.txt.

            1  +Title:       Khaki, No Logo
            2  +Description: A tan theme with the project title above the user identification
            3  +	     and no logo image.
            4  +Author:      Unknown

Added skins/default2/style.css.

            1  +/* General settings for the entire page */
            2  +body {
            3  +  margin: 0ex 0ex;
            4  +  padding: 0px;
            5  +  background-color: #fef3bc;
            6  +  font-family: sans-serif;
            7  +}
            8  +
            9  +/* The project logo in the upper left-hand corner of each page */
           10  +div.logo {
           11  +  display: inline;
           12  +  text-align: center;
           13  +  vertical-align: bottom;
           14  +  font-weight: bold;
           15  +  font-size: 2.5em;
           16  +  color: #a09048;
           17  +}
           18  +
           19  +/* The page title centered at the top of each page */
           20  +div.title {
           21  +  display: table-cell;
           22  +  font-size: 2em;
           23  +  font-weight: bold;
           24  +  text-align: left;
           25  +  padding: 0 0 0 5px;
           26  +  color: #a09048;
           27  +  vertical-align: bottom;
           28  +  width: 100%;
           29  +}
           30  +
           31  +/* The login status message in the top right-hand corner */
           32  +div.status {
           33  +  display: table-cell;
           34  +  text-align: right;
           35  +  vertical-align: bottom;
           36  +  color: #a09048;
           37  +  padding: 5px 5px 0 0;
           38  +  font-size: 0.8em;
           39  +  font-weight: bold;
           40  +}
           41  +
           42  +/* The header across the top of the page */
           43  +div.header {
           44  +  display: table;
           45  +  width: 100%;
           46  +}
           47  +
           48  +/* The main menu bar that appears at the top of the page beneath
           49  +** the header */
           50  +div.mainmenu {
           51  +  padding: 5px 10px 5px 10px;
           52  +  font-size: 0.9em;
           53  +  font-weight: bold;
           54  +  text-align: center;
           55  +  letter-spacing: 1px;
           56  +  background-color: #a09048;
           57  +  color: black;
           58  +}
           59  +
           60  +/* The submenu bar that *sometimes* appears below the main menu */
           61  +div.submenu {
           62  +  padding: 3px 10px 3px 0px;
           63  +  font-size: 0.9em;
           64  +  text-align: center;
           65  +  background-color: #c0af58;
           66  +  color: white;
           67  +}
           68  +div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
           69  +  padding: 3px 10px 3px 10px;
           70  +  color: white;
           71  +  text-decoration: none;
           72  +}
           73  +div.mainmenu a:hover, div.submenu a:hover {
           74  +  color: #a09048;
           75  +  background-color: white;
           76  +}
           77  +
           78  +/* All page content from the bottom of the menu or submenu down to
           79  +** the footer */
           80  +div.content {
           81  +  padding: 1ex 5px;
           82  +}
           83  +div.content a { color: #706532; }
           84  +div.content a:link { color: #706532; }
           85  +div.content a:visited { color: #704032; }
           86  +div.content a:hover { background-color: white; color: #706532; }
           87  +
           88  +/* Some pages have section dividers */
           89  +div.section {
           90  +  margin-bottom: 0px;
           91  +  margin-top: 1em;
           92  +  padding: 3px 3px 0 3px;
           93  +  font-size: 1.2em;
           94  +  font-weight: bold;
           95  +  background-color: #a09048;
           96  +  color: white;
           97  +}
           98  +
           99  +/* The "Date" that occurs on the left hand side of timelines */
          100  +div.divider {
          101  +  background: #e1d498;
          102  +  border: 2px #a09048 solid;
          103  +  font-size: 1em; font-weight: normal;
          104  +  padding: .25em;
          105  +  margin: .2em 0 .2em 0;
          106  +  float: left;
          107  +  clear: left;
          108  +}
          109  +
          110  +/* The footer at the very bottom of the page */
          111  +div.footer {
          112  +  font-size: 0.8em;
          113  +  margin-top: 12px;
          114  +  padding: 5px 10px 5px 10px;
          115  +  text-align: right;
          116  +  background-color: #a09048;
          117  +  color: white;
          118  +}
          119  +
          120  +/* Hyperlink colors */
          121  +div.footer a { color: white; }
          122  +div.footer a:link { color: white; }
          123  +div.footer a:visited { color: white; }
          124  +div.footer a:hover { background-color: white; color: #558195; }
          125  +
          126  +/* <verbatim> blocks */
          127  +pre.verbatim {
          128  +   background-color: #f5f5f5;
          129  +   padding: 0.5em;
          130  +}
          131  +
          132  +/* The label/value pairs on (for example) the ci page */
          133  +table.label-value th {
          134  +  vertical-align: top;
          135  +  text-align: right;
          136  +  padding: 0.2ex 2ex;
          137  +}

Added skins/default3/footer.html.

            1  +</div>
            2  +<div class="footer">
            3  +Fossil version $manifest_version $manifest_date
            4  +</div>
            5  +</body></html>

Added skins/default3/header.html.

            1  +<html>
            2  +<head>
            3  +<title>$<project_name>: $<title></title>
            4  +<link rel="alternate" type="application/rss+xml" title="RSS Feed"
            5  +      href="$baseurl/timeline.rss">
            6  +<link rel="stylesheet" href="$baseurl/style.css?black2" type="text/css"
            7  +      media="screen">
            8  +</head>
            9  +<body>
           10  +<div class="header">
           11  +  <div class="logo">
           12  +    <!-- <img src="$baseurl/logo" alt="logo"> -->
           13  +    <br><nobr>$<project_name></nobr>
           14  +  </div>
           15  +  <div class="title">$<title></div>
           16  +  <div class="status"><nobr><th1>
           17  +     if {[info exists login]} {
           18  +       puts "Logged in as $login"
           19  +     } else {
           20  +       puts "Not logged in"
           21  +     }
           22  +  </th1></nobr></div>
           23  +</div>
           24  +<div class="mainmenu"><ul><th1>
           25  +html "<li><a href=''$baseurl$index_page''>Home</a></li>"
           26  +if {[anycap jor]} {
           27  +  html "<li><a href=''$baseurl/timeline''>Timeline</a></li>"
           28  +}
           29  +if {[hascap oh]} {
           30  +  html "<li><a href=''$baseurl/dir?ci=tip''>Files</a></li>"
           31  +}
           32  +if {[hascap o]} {
           33  +  html "<li><a href=''$baseurl/leaves''>Leaves</a></li>"
           34  +  html "<li><a href=''$baseurl/brlist''>Branches</a></li>"
           35  +  html "<li><a href=''$baseurl/taglist''>Tags</a></li>"
           36  +}
           37  +if {[hascap r]} {
           38  +  html "<li><a href=''$baseurl/reportlist''>Tickets</a></li>"
           39  +}
           40  +if {[hascap j]} {
           41  +  html "<li><a href=''$baseurl/wiki''>Wiki</a></li>"
           42  +}
           43  +if {[hascap s]} {
           44  +  html "<li><a href=''$baseurl/setup''>Admin</a></li>"
           45  +} elseif {[hascap a]} {
           46  +  html "<li><a href=''$baseurl/setup_ulist''>Users</a></li>"
           47  +}
           48  +if {[info exists login]} {
           49  +  html "<li><a href=''$baseurl/login''>Logout</a></li>"
           50  +} else {
           51  +  html "<li><a href=''$baseurl/login''>Login</a></li>"
           52  +}
           53  +</th1></ul></div>
           54  +<div id="container">

Added skins/default3/info.txt.

            1  +Title:       Black & White, Menu on Left, No Logo
            2  +Description: Black letters on a white or cream background with the main menu
            3  +	     stuck on the left-hand side.
            4  +Author:      Unknown
            5  +

Added skins/default3/style.css.

            1  +/* General settings for the entire page */
            2  +body {
            3  +    margin:0px 0px 0px 0px;
            4  +    padding:0px;
            5  +    font-family:verdana, arial, helvetica, "sans serif";
            6  +    color:#333;
            7  +    background-color:white;
            8  +}
            9  +
           10  +/* consistent colours */
           11  +h2 {
           12  +  color: #333;
           13  +}
           14  +h3 {
           15  +  color: #333;
           16  +}
           17  +
           18  +/* The project logo in the upper left-hand corner of each page */
           19  +div.logo {
           20  +  display: table-cell;
           21  +  text-align: left;
           22  +  vertical-align: bottom;
           23  +  font-weight: bold;
           24  +  color: #333;
           25  +}
           26  +
           27  +/* The page title centered at the top of each page */
           28  +div.title {
           29  +  display: table-cell;
           30  +  font-size: 2em;
           31  +  font-weight: bold;
           32  +  text-align: center;
           33  +  color: #333;
           34  +  vertical-align: bottom;
           35  +  width: 100%;
           36  +}
           37  +
           38  +/* The login status message in the top right-hand corner */
           39  +div.status {
           40  +  display: table-cell;
           41  +  padding-right: 10px;
           42  +  text-align: right;
           43  +  vertical-align: bottom;
           44  +  padding-bottom: 5px;
           45  +  color: #333;
           46  +  font-size: 0.8em;
           47  +  font-weight: bold;
           48  +}
           49  +
           50  +/* The header across the top of the page */
           51  +div.header {
           52  +    margin:10px 0px 10px 0px;
           53  +    padding:1px 0px 0px 20px;
           54  +    border-style:solid;
           55  +    border-color:black;
           56  +    border-width:1px 0px;
           57  +    background-color:#eee;
           58  +}
           59  +
           60  +/* The main menu bar that appears at the top left of the page beneath
           61  +** the header. Width must be co-ordinated with the container below */
           62  +div.mainmenu {
           63  +  float: left;
           64  +  margin-left: 10px;
           65  +  margin-right: 10px;
           66  +  font-size: 0.9em;
           67  +  font-weight: bold;
           68  +  padding:5px;
           69  +  background-color:#eee;
           70  +  border:1px solid #999;
           71  +  width:8em;
           72  +}
           73  +
           74  +/* Main menu is now a list */
           75  +div.mainmenu ul {
           76  +  padding: 0;
           77  +  list-style:none;
           78  +}
           79  +div.mainmenu a, div.mainmenu a:visited{
           80  +  padding: 1px 10px 1px 10px;
           81  +  color: #333;
           82  +  text-decoration: none;
           83  +}
           84  +div.mainmenu a:hover {
           85  +  color: #eee;
           86  +  background-color: #333;
           87  +}
           88  +
           89  +/* Container for the sub-menu and content so they don''t spread
           90  +** out underneath the main menu */
           91  +#container {
           92  +  padding-left: 9em;
           93  +}
           94  +
           95  +/* The submenu bar that *sometimes* appears below the main menu */
           96  +div.submenu {
           97  +  padding: 3px 10px 3px 10px;
           98  +  font-size: 0.9em;
           99  +  text-align: center;
          100  +  border:1px solid #999;
          101  +  border-width:1px 0px;
          102  +  background-color: #eee;
          103  +  color: #333;
          104  +}
          105  +div.submenu a, div.submenu a:visited {
          106  +  padding: 3px 10px 3px 10px;
          107  +  color: #333;
          108  +  text-decoration: none;
          109  +}
          110  +div.submenu a:hover {
          111  +  color: #eee;
          112  +  background-color: #333;
          113  +}
          114  +
          115  +/* All page content from the bottom of the menu or submenu down to
          116  +** the footer */
          117  +div.content {
          118  +  float: right;
          119  +  padding: 2ex 1ex 0ex 2ex;
          120  +}
          121  +
          122  +/* Some pages have section dividers */
          123  +div.section {
          124  +  margin-bottom: 0px;
          125  +  margin-top: 1em;
          126  +  padding: 1px 1px 1px 1px;
          127  +  font-size: 1.2em;
          128  +  font-weight: bold;
          129  +  border-style:solid;
          130  +  border-color:#999;
          131  +  border-width:1px 0px;
          132  +  background-color: #eee;
          133  +  color: #333;
          134  +}
          135  +
          136  +/* The "Date" that occurs on the left hand side of timelines */
          137  +div.divider {
          138  +  background: #eee;
          139  +  border: 2px #999 solid;
          140  +  font-size: 1em; font-weight: normal;
          141  +  padding: .25em;
          142  +  margin: .2em 0 .2em 0;
          143  +  float: left;
          144  +  clear: left;
          145  +  color: #333
          146  +}
          147  +
          148  +/* The footer at the very bottom of the page */
          149  +div.footer {
          150  +  font-size: 0.8em;
          151  +  margin-top: 12px;
          152  +  padding: 5px 10px 5px 10px;
          153  +  text-align: right;
          154  +  background-color: #eee;
          155  +  color: #555;
          156  +}
          157  +
          158  +/* <verbatim> blocks */
          159  +pre.verbatim {
          160  +   background-color: #f5f5f5;
          161  +   padding: 0.5em;
          162  +}
          163  +
          164  +/* The label/value pairs on (for example) the ci page */
          165  +table.label-value th {
          166  +  vertical-align: top;
          167  +  text-align: right;
          168  +  padding: 0.2ex 2ex;
          169  +}
          170  +

Changes to src/add.c.

    34     34   */
    35     35   static void add_one_file(const char *zName, int vid, Blob *pOmit){
    36     36     Blob pathname;
    37     37     const char *zPath;
    38     38   
    39     39     file_tree_name(zName, &pathname, 1);
    40     40     zPath = blob_str(&pathname);
    41         -  if( strcmp(zPath, "manifest")==0
    42         -   || strcmp(zPath, "_FOSSIL_")==0
           41  +  if( strcmp(zPath, "_FOSSIL_")==0
    43     42      || strcmp(zPath, "_FOSSIL_-journal")==0
    44     43      || strcmp(zPath, "_FOSSIL_-wal")==0
    45     44      || strcmp(zPath, "_FOSSIL_-shm")==0
    46     45      || strcmp(zPath, ".fos")==0
    47     46      || strcmp(zPath, ".fos-journal")==0
    48     47      || strcmp(zPath, ".fos-wal")==0
    49     48      || strcmp(zPath, ".fos-shm")==0
    50         -   || strcmp(zPath, "manifest.uuid")==0
    51     49      || blob_compare(&pathname, pOmit)==0
    52     50     ){
    53     51       fossil_warning("cannot add %s", zPath);
    54     52     }else{
    55     53       if( !file_is_simple_pathname(zPath) ){
    56     54         fossil_fatal("filename contains illegal characters: %s", zPath);
    57     55       }
    58         -#ifdef __MINGW32__
           56  +#if defined(_WIN32)
    59     57       if( db_exists("SELECT 1 FROM vfile"
    60     58                     " WHERE pathname=%Q COLLATE nocase", zPath) ){
    61     59         db_multi_exec("UPDATE vfile SET deleted=0"
    62     60                       " WHERE pathname=%Q COLLATE nocase", zPath);
    63     61       }
    64     62   #else
    65     63       if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){
................................................................................
   150    148       fossil_panic("no checkout to add to");
   151    149     }
   152    150     db_begin_transaction();
   153    151     if( !file_tree_name(g.zRepositoryName, &repo, 0) ){
   154    152       blob_zero(&repo);
   155    153     }
   156    154     db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
   157         -#ifdef __MINGW32__
          155  +#if defined(_WIN32)
   158    156     db_multi_exec(
   159    157        "CREATE INDEX IF NOT EXISTS vfile_pathname "
   160    158        "  ON vfile(pathname COLLATE nocase)"
   161    159     );
   162    160   #endif
   163    161     for(i=2; i<g.argc; i++){
   164    162       char *zName;

Changes to src/allrepo.c.

    32     32   ** string is returned even if no quoting is needed.
    33     33   */
    34     34   static char *quoteFilename(const char *zFilename){
    35     35     int i, c;
    36     36     int needQuote = 0;
    37     37     for(i=0; (c = zFilename[i])!=0; i++){
    38     38       if( c=='"' ) return 0;
    39         -    if( isspace(c) ) needQuote = 1;
           39  +    if( fossil_isspace(c) ) needQuote = 1;
    40     40       if( c=='\\' && zFilename[i+1]==0 ) return 0;
    41     41       if( c=='$' ) return 0;
    42     42     }
    43     43     if( needQuote ){
    44     44       return mprintf("\"%s\"", zFilename);
    45     45     }else{
    46     46       return mprintf("%s", zFilename);
................................................................................
    51     51   /*
    52     52   ** COMMAND: all
    53     53   **
    54     54   ** Usage: %fossil all (list|ls|pull|push|rebuild|sync)
    55     55   **
    56     56   ** The ~/.fossil file records the location of all repositories for a
    57     57   ** user.  This command performs certain operations on all repositories
    58         -** that can be useful before or after a period of disconnection operation.
           58  +** that can be useful before or after a period of disconnected operation.
    59     59   **
    60         -** On Win32 systems, this file is located in %LOCALAPPDATA%, %APDDATA%
    61         -** or %HOMEPATH% and is named _fossil.
           60  +** On Win32 systems, the file is named "_fossil" and is located in
           61  +** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%.
    62     62   **
    63     63   ** Available operations are:
    64     64   **
           65  +**    ignore     Arguments are repositories that should be ignored
           66  +**               by subsequent list, pull, push, rebuild, and sync.
           67  +**
    65     68   **    list | ls  Display the location of all repositories
    66     69   **
    67     70   **    pull       Run a "pull" operation on all repositories
    68     71   **
    69     72   **    push       Run a "push" on all repositories
    70     73   **
    71     74   **    rebuild    Rebuild on all repositories
    72     75   **
    73     76   **    sync       Run a "sync" on all repositories
    74     77   **
    75     78   ** Respositories are automatically added to the set of known repositories
    76     79   ** when one of the following commands against the repository: clone, info,
    77         -** pull, push, or sync
           80  +** pull, push, or sync.  Even previously ignored repositories are added back
           81  +** to the list of repositories by these commands.
    78     82   */
    79     83   void all_cmd(void){
    80     84     int n;
    81     85     Stmt q;
    82     86     const char *zCmd;
    83     87     char *zSyscmd;
    84     88     char *zFossil;
................................................................................
    97    101       zCmd = "push -autourl -R";
    98    102     }else if( strncmp(zCmd, "pull", n)==0 ){
    99    103       zCmd = "pull -autourl -R";
   100    104     }else if( strncmp(zCmd, "rebuild", n)==0 ){
   101    105       zCmd = "rebuild";
   102    106     }else if( strncmp(zCmd, "sync", n)==0 ){
   103    107       zCmd = "sync -autourl -R";
          108  +  }else if( strncmp(zCmd, "ignore", n)==0 ){
          109  +    int j;
          110  +    db_begin_transaction();
          111  +    for(j=3; j<g.argc; j++){
          112  +      db_multi_exec("DELETE FROM global_config WHERE name GLOB 'repo:%q'",
          113  +         g.argv[j]);
          114  +    }
          115  +    db_end_transaction(0);
          116  +    return;
   104    117     }else{
   105    118       fossil_fatal("\"all\" subcommand should be one of: "
   106         -                 "list ls push pull rebuild sync");
          119  +                 "ignore list ls push pull rebuild sync");
   107    120     }
   108    121     zFossil = quoteFilename(g.argv[0]);
   109    122     nMissing = 0;
   110    123     db_prepare(&q,
   111    124        "SELECT DISTINCT substr(name, 6) COLLATE nocase"
   112    125        "  FROM global_config"
   113    126        " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1"
................................................................................
   123    136         printf("%s\n", zFilename);
   124    137         continue;
   125    138       }
   126    139       zQFilename = quoteFilename(zFilename);
   127    140       zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename);
   128    141       printf("%s\n", zSyscmd);
   129    142       fflush(stdout);
   130         -    portable_system(zSyscmd);
          143  +    fossil_system(zSyscmd);
   131    144       free(zSyscmd);
   132    145       free(zQFilename);
   133    146     }
   134    147     
   135    148     /* If any repositories whose names appear in the ~/.fossil file could not
   136    149     ** be found, remove those names from the ~/.fossil file.
   137    150     */

Changes to src/attach.c.

    73     73       for(i=0; zFilename[i]; i++){
    74     74         if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ 
    75     75           zFilename = &zFilename[i+1];
    76     76           i = -1;
    77     77         }
    78     78       }
    79     79       if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
    80         -      zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
           80  +      zUrlTail = mprintf("tkt=%s&amp;file=%t", zTarget, zFilename);
    81     81       }else{
    82         -      zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
           82  +      zUrlTail = mprintf("page=%t&amp;file=%t", zTarget, zFilename);
    83     83       }
    84     84       @
    85     85       @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
    86         -    @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br>
    87         -    if( zComment ) while( isspace(zComment[0]) ) zComment++;
           86  +    @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
           87  +    if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
    88     88       if( zComment && zComment[0] ){
    89         -      @ %w(zComment)<br>
           89  +      @ %w(zComment)<br />
    90     90       }
    91     91       if( zPage==0 && zTkt==0 ){
    92     92         if( zSrc==0 || zSrc[0]==0 ){
    93     93           zSrc = "Deleted from";
    94     94         }else {
    95     95           zSrc = "Added to";
    96     96         }
................................................................................
   249    249       for(i=n=0; zName[i]; i++){
   250    250         if( zName[i]=='/' || zName[i]=='\\' ) n = i;
   251    251       }
   252    252       zName += n;
   253    253       if( zName[0]==0 ) zName = "unknown";
   254    254       blob_appendf(&manifest, "A %F %F %s\n", zName, zTarget, zUUID);
   255    255       zComment = PD("comment", "");
   256         -    while( isspace(zComment[0]) ) zComment++;
          256  +    while( fossil_isspace(zComment[0]) ) zComment++;
   257    257       n = strlen(zComment);
   258         -    while( n>0 && isspace(zComment[n-1]) ){ n--; }
          258  +    while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
   259    259       if( n>0 ){
   260    260         blob_appendf(&manifest, "C %F\n", zComment);
   261    261       }
   262    262       zDate = db_text(0, "SELECT datetime('now')");
   263    263       zDate[10] = 'T';
   264    264       blob_appendf(&manifest, "D %s\n", zDate);
   265    265       blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
................................................................................
   268    268       rid = content_put(&manifest, 0, 0);
   269    269       manifest_crosslink(rid, &manifest);
   270    270       db_end_transaction(0);
   271    271       cgi_redirect(zFrom);
   272    272     }
   273    273     style_header("Add Attachment");
   274    274     @ <h2>Add Attachment To %s(zTargetType)</h2>
   275         -  @ <form action="%s(g.zBaseURL)/attachadd" method="POST"
   276         -  @  enctype="multipart/form-data">
          275  +  @ <form action="%s(g.zBaseURL)/attachadd" method="post"
          276  +  @  enctype="multipart/form-data"><div>
   277    277     @ File to Attach:
   278         -  @ <input type="file" name="f" size="60"><br>
   279         -  @ Description:<br>
   280         -  @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br>
          278  +  @ <input type="file" name="f" size="60" /><br />
          279  +  @ Description:<br />
          280  +  @ <textarea name="comment" cols="80" rows="5" wrap="virtual"></textarea><br />
   281    281     if( zTkt ){
   282         -    @ <input type="hidden" name="tkt" value="%h(zTkt)">
          282  +    @ <input type="hidden" name="tkt" value="%h(zTkt)" />
   283    283     }else{
   284         -    @ <input type="hidden" name="page" value="%h(zPage)">
          284  +    @ <input type="hidden" name="page" value="%h(zPage)" />
   285    285     }
   286         -  @ <input type="hidden" name="from" value="%h(zFrom)">
   287         -  @ <input type="submit" name="ok" value="Add Attachment">
   288         -  @ <input type="submit" name="cancel" value="Cancel">
   289         -  @ </form>
          286  +  @ <input type="hidden" name="from" value="%h(zFrom)" />
          287  +  @ <input type="submit" name="ok" value="Add Attachment" />
          288  +  @ <input type="submit" name="cancel" value="Cancel" />
          289  +  @ </div></form>
   290    290     style_footer();
   291    291   }
   292    292   
   293    293   
   294    294   /*
   295    295   ** WEBPAGE: attachdelete
   296    296   **
................................................................................
   347    347       blob_appendf(&manifest, "Z %b\n", &cksum);
   348    348       rid = content_put(&manifest, 0, 0);
   349    349       manifest_crosslink(rid, &manifest);
   350    350       db_end_transaction(0);
   351    351       cgi_redirect(zFrom);
   352    352     }    
   353    353     style_header("Delete Attachment");
   354         -  @ <form action="%s(g.zBaseURL)/attachdelete" method="POST">
          354  +  @ <form action="%s(g.zBaseURL)/attachdelete" method="post"><div>
   355    355     @ <p>Confirm that you want to delete the attachment named
   356         -  @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br>
          356  +  @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br /></p>
   357    357     if( zTkt ){
   358         -    @ <input type="hidden" name="tkt" value="%h(zTkt)">
          358  +    @ <input type="hidden" name="tkt" value="%h(zTkt)" />
   359    359     }else{
   360         -    @ <input type="hidden" name="page" value="%h(zPage)">
          360  +    @ <input type="hidden" name="page" value="%h(zPage)" />
   361    361     }
   362         -  @ <input type="hidden" name="file" value="%h(zFile)">
   363         -  @ <input type="hidden" name="from" value="%h(zFrom)">
   364         -  @ <input type="submit" name="confirm" value="Delete">
   365         -  @ <input type="submit" name="cancel" value="Cancel">
   366         -  @ </form>
          362  +  @ <input type="hidden" name="file" value="%h(zFile)" />
          363  +  @ <input type="hidden" name="from" value="%h(zFrom)" />
          364  +  @ <input type="submit" name="confirm" value="Delete" />
          365  +  @ <input type="submit" name="cancel" value="Cancel" />
          366  +  @ </div></form>
   367    367     style_footer();
   368    368   
   369    369   }

Changes to src/bag.c.

    84     84     int i;
    85     85     Bag old;
    86     86     int nDel = 0;   /* Number of deleted entries */
    87     87     int nLive = 0;  /* Number of live entries */
    88     88   
    89     89     old = *p;
    90     90     assert( newSize>old.cnt );
    91         -  p->a = malloc( sizeof(p->a[0])*newSize );
           91  +  p->a = fossil_malloc( sizeof(p->a[0])*newSize );
    92     92     p->sz = newSize;
    93     93     memset(p->a, 0, sizeof(p->a[0])*newSize );
    94     94     for(i=0; i<old.sz; i++){
    95     95       int e = old.a[i];
    96     96       if( e>0 ){
    97     97         unsigned h = bag_hash(e)%newSize;
    98     98         while( p->a[h] ){

Changes to src/blob.c.

    70     70   #define blob_is_reset(x)
    71     71   #endif
    72     72   
    73     73   /*
    74     74   ** We find that the built-in isspace() function does not work for
    75     75   ** some international character sets.  So here is a substitute.
    76     76   */
    77         -static int blob_isspace(char c){
           77  +int fossil_isspace(char c){
    78     78     return c==' ' || (c<='\r' && c>='\t');
    79     79   }
           80  +
           81  +/*
           82  +** Other replacements for ctype.h functions.
           83  +*/
           84  +int fossil_islower(char c){ return c>='a' && c<='z'; }
           85  +int fossil_isupper(char c){ return c>='A' && c<='Z'; }
           86  +int fossil_isdigit(char c){ return c>='0' && c<='9'; }
           87  +int fossil_tolower(char c){
           88  +  return fossil_isupper(c) ? c - 'A' + 'a' : c;
           89  +}
           90  +int fossil_isalpha(char c){
           91  +  return (c>='a' && c<='z') || (c>='A' && c<='Z');
           92  +}
           93  +int fossil_isalnum(char c){
           94  +  return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9');
           95  +}
           96  +
    80     97   
    81     98   /*
    82     99   ** COMMAND: test-isspace
    83    100   */
    84    101   void isspace_cmd(void){
    85    102     int i;
    86    103     for(i=0; i<=255; i++){
    87    104       if( i==' ' || i=='\n' || i=='\t' || i=='\v'
    88    105           || i=='\f' || i=='\r' ){
    89         -      assert( blob_isspace((char)i) );
          106  +      assert( fossil_isspace((char)i) );
    90    107       }else{
    91         -      assert( !blob_isspace((char)i) );
          108  +      assert( !fossil_isspace((char)i) );
    92    109       }
    93    110     }
    94    111     printf("All 256 characters OK\n");
    95    112   }
    96    113   
    97    114   /*
    98    115   ** This routine is called if a blob operation fails because we
................................................................................
   117    134     if( newSize==0 ){
   118    135       free(pBlob->aData);
   119    136       pBlob->aData = 0;
   120    137       pBlob->nAlloc = 0;
   121    138       pBlob->nUsed = 0;
   122    139       pBlob->iCursor = 0;
   123    140     }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
   124         -    char *pNew = realloc(pBlob->aData, newSize);
   125         -    if( pNew==0 ) blob_panic();
          141  +    char *pNew = fossil_realloc(pBlob->aData, newSize);
   126    142       pBlob->aData = pNew;
   127    143       pBlob->nAlloc = newSize;
   128    144       if( pBlob->nUsed>pBlob->nAlloc ){
   129    145         pBlob->nUsed = pBlob->nAlloc;
   130    146       }
   131    147     }
   132    148   }
................................................................................
   143    159   ** A reallocation function for when the initial string is in unmanaged
   144    160   ** space.  Copy the string to memory obtained from malloc().
   145    161   */
   146    162   static void blobReallocStatic(Blob *pBlob, unsigned int newSize){
   147    163     if( newSize==0 ){
   148    164       *pBlob = empty_blob;
   149    165     }else{
   150         -    char *pNew = malloc( newSize );
   151         -    if( pNew==0 ) blob_panic();
          166  +    char *pNew = fossil_malloc( newSize );
   152    167       if( pBlob->nUsed>newSize ) pBlob->nUsed = newSize;
   153    168       memcpy(pNew, pBlob->aData, pBlob->nUsed);
   154    169       pBlob->aData = pNew;
   155    170       pBlob->xRealloc = blobReallocMalloc;
   156    171       pBlob->nAlloc = newSize;
   157    172     }
   158    173   }
................................................................................
   427    442   **
   428    443   ** All this does is reduce the length counter.  This routine does
   429    444   ** not insert a new zero terminator.
   430    445   */
   431    446   int blob_trim(Blob *p){
   432    447     char *z = p->aData;
   433    448     int n = p->nUsed;
   434         -  while( n>0 && blob_isspace(z[n-1]) ){ n--; }
          449  +  while( n>0 && fossil_isspace(z[n-1]) ){ n--; }
   435    450     p->nUsed = n;
   436    451     return n;
   437    452   }
   438    453   
   439    454   /*
   440    455   ** Extract a single token from pFrom and use it to initialize pTo.
   441    456   ** Return the number of bytes in the token.  If no token is found,
................................................................................
   450    465   ** pTo will be an ephermeral blob.  If pFrom changes, it might alter
   451    466   ** pTo as well.
   452    467   */
   453    468   int blob_token(Blob *pFrom, Blob *pTo){
   454    469     char *aData = pFrom->aData;
   455    470     int n = pFrom->nUsed;
   456    471     int i = pFrom->iCursor;
   457         -  while( i<n && blob_isspace(aData[i]) ){ i++; }
          472  +  while( i<n && fossil_isspace(aData[i]) ){ i++; }
   458    473     pFrom->iCursor = i;
   459         -  while( i<n && !blob_isspace(aData[i]) ){ i++; }
          474  +  while( i<n && !fossil_isspace(aData[i]) ){ i++; }
   460    475     blob_extract(pFrom, i-pFrom->iCursor, pTo);
   461         -  while( i<n && blob_isspace(aData[i]) ){ i++; }
          476  +  while( i<n && fossil_isspace(aData[i]) ){ i++; }
   462    477     pFrom->iCursor = i;
   463    478     return pTo->nUsed;
   464    479   }
   465    480   
   466    481   /*
   467    482   ** Extract everything from the current cursor to the end of the blob
   468    483   ** into a new blob.  The new blob is an ephemerial reference to the
................................................................................
   521    536   ** the integer value in *pValue.
   522    537   */
   523    538   int blob_is_int(Blob *pBlob, int *pValue){
   524    539     const char *z = blob_buffer(pBlob);
   525    540     int i, n, c, v;
   526    541     n = blob_size(pBlob);
   527    542     v = 0;
   528         -  for(i=0; i<n && (c = z[i])!=0 && isdigit(c); i++){
          543  +  for(i=0; i<n && (c = z[i])!=0 && c>='0' && c<='9'; i++){
   529    544       v = v*10 + c - '0';
   530    545     }
   531    546     if( i==n ){
   532    547       *pValue = v;
   533    548       return 1;
   534    549     }else{
   535    550       return 0;
................................................................................
   610    625     if( zFilename==0 || zFilename[0]==0
   611    626           || (zFilename[0]=='-' && zFilename[1]==0) ){
   612    627       return blob_read_from_channel(pBlob, stdin, -1);
   613    628     }
   614    629     size = file_size(zFilename);
   615    630     blob_zero(pBlob);
   616    631     if( size<0 ){
   617         -    fossil_panic("no such file: %s", zFilename);
          632  +    fossil_fatal("no such file: %s", zFilename);
   618    633     }
   619    634     if( size==0 ){
   620    635       return 0;
   621    636     }
   622    637     blob_resize(pBlob, size);
   623    638     in = fopen(zFilename, "rb");
   624    639     if( in==0 ){
................................................................................
   658    673         zName = zBuf;
   659    674         strcpy(zName, zFilename);
   660    675       }
   661    676       nName = file_simplify_name(zName, nName);
   662    677       for(i=1; i<nName; i++){
   663    678         if( zName[i]=='/' ){
   664    679           zName[i] = 0;
   665         -#ifdef __MINGW32__
          680  +#if defined(_WIN32)
   666    681           /*
   667    682           ** On Windows, local path looks like: C:/develop/project/file.txt
   668    683           ** The if stops us from trying to create a directory of a drive letter
   669    684           ** C: in this example.
   670    685           */
   671    686           if( !(i==2 && zName[1]==':') ){
   672    687   #endif
   673    688             if( file_mkdir(zName, 1) ){
   674    689               fossil_fatal_recursive("unable to create directory %s", zName);
   675    690               return 0;
   676    691             }
   677         -#ifdef __MINGW32__
          692  +#if defined(_WIN32)
   678    693           }
   679    694   #endif
   680    695           zName[i] = '/';
   681    696         }
   682    697       }
   683    698       out = fopen(zName, "wb");
   684    699       if( out==0 ){
................................................................................
   854    869       blob_reset(&b1);
   855    870       blob_reset(&b2);
   856    871       blob_reset(&b3);
   857    872     }
   858    873     printf("ok\n");
   859    874   }
   860    875   
   861         -#ifdef __MINGW32__
          876  +#if defined(_WIN32)
   862    877   /*
   863    878   ** Convert every \n character in the given blob into \r\n.
   864    879   */
   865    880   void blob_add_cr(Blob *p){
   866    881     char *z = p->aData;
   867    882     int j   = p->nUsed;
   868    883     int i, n;
................................................................................
   894    909     z = p->aData;
   895    910     for(i=j=0; z[i]; i++){
   896    911       if( z[i]!='\r' ) z[j++] = z[i];
   897    912     }
   898    913     z[j] = 0;
   899    914     p->nUsed = j;
   900    915   }
          916  +
          917  +/*
          918  +** Shell-escape the given string.  Append the result to a blob.
          919  +*/
          920  +void shell_escape(Blob *pBlob, const char *zIn){
          921  +  int n = blob_size(pBlob);
          922  +  int k = strlen(zIn);
          923  +  int i, c;
          924  +  char *z;
          925  +  for(i=0; (c = zIn[i])!=0; i++){
          926  +    if( fossil_isspace(c) || c=='"' || (c=='\\' && zIn[i+1]!=0) ){
          927  +      blob_appendf(pBlob, "\"%s\"", zIn);
          928  +      z = blob_buffer(pBlob);
          929  +      for(i=n+1; i<=n+k; i++){
          930  +        if( z[i]=='"' ) z[i] = '_';
          931  +      }
          932  +      return;
          933  +    }
          934  +  }
          935  +  blob_append(pBlob, zIn, -1);
          936  +}

Changes to src/branch.c.

    33     33     char *zUuid;           /* Artifact ID of origin */
    34     34     Stmt q;                /* Generic query */
    35     35     const char *zBranch;   /* Name of the new branch */
    36     36     char *zDate;           /* Date that branch was created */
    37     37     char *zComment;        /* Check-in comment for the new branch */
    38     38     const char *zColor;    /* Color of the new branch */
    39     39     Blob branch;           /* manifest for the new branch */
    40         -  Blob parent;           /* root check-in manifest */
    41         -  Manifest mParent;      /* Parsed parent manifest */
           40  +  Manifest *pParent;     /* Parsed parent manifest */
    42     41     Blob mcksum;           /* Self-checksum on the manifest */
           42  +  const char *zDateOvrd; /* Override date string */
           43  +  const char *zUserOvrd; /* Override user name */
    43     44    
    44     45     noSign = find_option("nosign","",0)!=0;
    45     46     zColor = find_option("bgcolor","c",1);
           47  +  zDateOvrd = find_option("date-override",0,1);
           48  +  zUserOvrd = find_option("user-override",0,1);
    46     49     verify_all_options();
    47     50     if( g.argc<5 ){
    48     51       usage("new BRANCH-NAME CHECK-IN ?-bgcolor COLOR?");
    49     52     }
    50     53     db_find_and_open_repository(1);  
    51     54     noSign = db_get_int("omitsign", 0)|noSign;
    52     55     
................................................................................
    65     68   
    66     69     user_select();
    67     70     db_begin_transaction();
    68     71     rootid = name_to_rid(g.argv[4]);
    69     72     if( rootid==0 ){
    70     73       fossil_fatal("unable to locate check-in off of which to branch");
    71     74     }
           75  +
           76  +  pParent = manifest_get(rootid, CFTYPE_MANIFEST);
           77  +  if( pParent==0 ){
           78  +    fossil_fatal("%s is not a valid check-in", g.argv[4]);
           79  +  }
    72     80   
    73     81     /* Create a manifest for the new branch */
    74     82     blob_zero(&branch);
           83  +  if( pParent->zBaseline ){
           84  +    blob_appendf(&branch, "B %s\n", pParent->zBaseline);
           85  +  }
    75     86     zComment = mprintf("Create new branch named \"%h\"", zBranch);
    76     87     blob_appendf(&branch, "C %F\n", zComment);
    77         -  zDate = db_text(0, "SELECT datetime('now')");
           88  +  zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
    78     89     zDate[10] = 'T';
    79     90     blob_appendf(&branch, "D %s\n", zDate);
    80     91   
    81     92     /* Copy all of the content from the parent into the branch */
    82         -  content_get(rootid, &parent);
    83         -  manifest_parse(&mParent, &parent);
    84         -  if( mParent.type!=CFTYPE_MANIFEST ){
    85         -    fossil_fatal("%s is not a valid check-in", g.argv[4]);
    86         -  }
    87         -  for(i=0; i<mParent.nFile; ++i){
    88         -    if( mParent.aFile[i].zPerm[0] ){
    89         -      blob_appendf(&branch, "F %F %s %s\n",
    90         -                   mParent.aFile[i].zName,
    91         -                   mParent.aFile[i].zUuid,
    92         -                   mParent.aFile[i].zPerm);
    93         -    }else{
    94         -      blob_appendf(&branch, "F %F %s\n",
    95         -                   mParent.aFile[i].zName,
    96         -                   mParent.aFile[i].zUuid);
           93  +  for(i=0; i<pParent->nFile; ++i){
           94  +    blob_appendf(&branch, "F %F", pParent->aFile[i].zName);
           95  +    if( pParent->aFile[i].zUuid ){
           96  +      blob_appendf(&branch, " %s", pParent->aFile[i].zUuid);
           97  +      if( pParent->aFile[i].zPerm && pParent->aFile[i].zPerm[0] ){
           98  +        blob_appendf(&branch, " %s", pParent->aFile[i].zPerm);
           99  +      }
    97    100       }
          101  +    blob_append(&branch, "\n", 1);
    98    102     }
    99    103     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rootid);
   100    104     blob_appendf(&branch, "P %s\n", zUuid);
   101         -  blob_appendf(&branch, "R %s\n", mParent.zRepoCksum);
   102         -  manifest_clear(&mParent);
          105  +  blob_appendf(&branch, "R %s\n", pParent->zRepoCksum);
          106  +  manifest_destroy(pParent);
   103    107   
   104    108     /* Add the symbolic branch name and the "branch" tag to identify
   105    109     ** this as a new branch */
   106    110     if( zColor!=0 ){
   107    111       blob_appendf(&branch, "T *bgcolor * %F\n", zColor);
   108    112     }
   109    113     blob_appendf(&branch, "T *branch * %F\n", zBranch);
................................................................................
   118    122         rootid);
   119    123     while( db_step(&q)==SQLITE_ROW ){
   120    124       const char *zTag = db_column_text(&q, 0);
   121    125       blob_appendf(&branch, "T -%F *\n", zTag);
   122    126     }
   123    127     db_finalize(&q);
   124    128     
   125         -  blob_appendf(&branch, "U %F\n", g.zLogin);
          129  +  blob_appendf(&branch, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
   126    130     md5sum_blob(&branch, &mcksum);
   127    131     blob_appendf(&branch, "Z %b\n", &mcksum);
   128    132     if( !noSign && clearsign(&branch, &branch) ){
   129    133       Blob ans;
   130    134       blob_zero(&ans);
   131    135       prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
   132    136       if( blob_str(&ans)[0]!='y' ){
................................................................................
   213    217   ** WEBPAGE: brlist
   214    218   **
   215    219   ** Show a timeline of all branches
   216    220   */
   217    221   void brlist_page(void){
   218    222     Stmt q;
   219    223     int cnt;
          224  +  int showClosed = P("closed")!=0;
   220    225   
   221    226     login_check_credentials();
   222    227     if( !g.okRead ){ login_needed(); return; }
   223    228   
   224         -  style_header("Branches");
          229  +  style_header(showClosed ? "Closed Branches" : "Open Branches");
   225    230     style_submenu_element("Timeline", "Timeline", "brtimeline");
          231  +  if( showClosed ){
          232  +    style_submenu_element("Open","Open","brlist");
          233  +  }else{
          234  +    style_submenu_element("Closed","Closed","brlist?closed");
          235  +  }
   226    236     login_anonymous_available();
   227    237     compute_leaves(0, 1);
   228    238     style_sidebox_begin("Nomenclature:", "33%");
   229    239     @ <ol>
   230         -  @ <li> An <b>open branch</b> is a branch that has one or
          240  +  @ <li> An <div class="sideboxDescribed"><a href="brlist">
          241  +  @ open branch</a></div> is a branch that has one or
   231    242     @ more <a href="leaves">open leaves.</a>
   232    243     @ The presence of open leaves presumably means
   233    244     @ that the branch is still being extended with new check-ins.</li>
   234         -  @ <li> A <b>closed branch</b> is a branch with only
   235         -  @ <a href="leaves?closed">closed leaves</a>.
          245  +  @ <li> A <div class="sideboxDescribed"><a href="brlist?closed">
          246  +  @ closed branch</a></div> is a branch with only
          247  +  @ <div class="sideboxDescribed"><a href="leaves?closed">
          248  +  @ closed leaves</a></div>.
   236    249     @ Closed branches are fixed and do not change (unless they are first
   237    250     @ reopened)</li>
   238    251     @ </ol>
   239    252     style_sidebox_end();
   240    253   
   241         -  db_prepare(&q,
   242         -    "SELECT DISTINCT value FROM tagxref"
   243         -    " WHERE tagid=%d AND value NOT NULL"
   244         -    "   AND rid IN leaves"
   245         -    " ORDER BY value /*sort*/",
   246         -    TAG_BRANCH
   247         -  );
   248    254     cnt = 0;
          255  +  if( !showClosed ){
          256  +    db_prepare(&q,
          257  +      "SELECT DISTINCT value FROM tagxref"
          258  +      " WHERE tagid=%d AND value NOT NULL"
          259  +      "   AND rid IN leaves"
          260  +      " ORDER BY value /*sort*/",
          261  +      TAG_BRANCH
          262  +    );
          263  +  }else{
          264  +    db_prepare(&q,
          265  +      "SELECT value FROM tagxref"
          266  +      " WHERE tagid=%d AND value NOT NULL"
          267  +      " EXCEPT "
          268  +      "SELECT value FROM tagxref"
          269  +      " WHERE tagid=%d AND value NOT NULL"
          270  +      "   AND rid IN leaves"
          271  +      " ORDER BY value /*sort*/",
          272  +      TAG_BRANCH, TAG_BRANCH
          273  +    );
          274  +  }
   249    275     while( db_step(&q)==SQLITE_ROW ){
   250    276       const char *zBr = db_column_text(&q, 0);
   251    277       if( cnt==0 ){
   252         -      @ <h2>Open Branches:</h2>
          278  +      if( showClosed ){
          279  +        @ <h2>Closed Branches:</h2>
          280  +      }else{
          281  +        @ <h2>Open Branches:</h2>
          282  +      }
   253    283         @ <ul>
   254    284         cnt++;
   255    285       }
   256         -    if( g.okHistory ){
   257         -      @ <li><a href="%s(g.zBaseURL)/timeline?r=%T(zBr)">%h(zBr)</a></li>
   258         -    }else{
   259         -      @ <li><b>%h(zBr)</b></li>
   260         -    }
   261         -  }
   262         -  db_finalize(&q);
   263         -  if( cnt ){
   264         -    @ </ul>
   265         -  }
   266         -  cnt = 0;
   267         -  db_prepare(&q,
   268         -    "SELECT value FROM tagxref"
   269         -    " WHERE tagid=%d AND value NOT NULL"
   270         -    " EXCEPT "
   271         -    "SELECT value FROM tagxref"
   272         -    " WHERE tagid=%d AND value NOT NULL"
   273         -    "   AND rid IN leaves"
   274         -    " ORDER BY value /*sort*/",
   275         -    TAG_BRANCH, TAG_BRANCH
   276         -  );
   277         -  while( db_step(&q)==SQLITE_ROW ){
   278         -    const char *zBr = db_column_text(&q, 0);
   279         -    if( cnt==0 ){
   280         -      @ <h2>Closed Branches:</h2>
   281         -      @ <ul>
   282         -      cnt++;     
   283         -    }
   284    286       if( g.okHistory ){
   285    287         @ <li><a href="%s(g.zBaseURL)/timeline?r=%T(zBr)">%h(zBr)</a></li>
   286    288       }else{
   287    289         @ <li><b>%h(zBr)</b></li>
   288    290       }
   289    291     }
   290    292     if( cnt ){
   291    293       @ </ul>
   292    294     }
   293    295     db_finalize(&q);
   294         -  @ </ul>
   295         -  @ <br clear="both">
   296         -  @ <script>
          296  +  @ <script  type="text/JavaScript">
   297    297     @ function xin(id){
   298    298     @ }
   299    299     @ function xout(id){
   300    300     @ }
   301    301     @ </script>
   302    302     style_footer();
   303    303   }
................................................................................
   344    344       "%s AND blob.rid IN (SELECT rid FROM tagxref"
   345    345       "                     WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
   346    346       " ORDER BY event.mtime DESC",
   347    347       timeline_query_for_www(), TAG_BRANCH
   348    348     );
   349    349     www_print_timeline(&q, 0, brtimeline_extra);
   350    350     db_finalize(&q);
   351         -  @ <br clear="both">
   352         -  @ <script>
          351  +  @ <script  type="text/JavaScript">
   353    352     @ function xin(id){
   354    353     @ }
   355    354     @ function xout(id){
   356    355     @ }
   357    356     @ </script>
   358    357     style_footer();
   359    358   }

Changes to src/browse.c.

    69     69   ** to the "dir" page for the directory.
    70     70   **
    71     71   ** There is no hyperlink on the file element of the path.
    72     72   **
    73     73   ** The computed string is appended to the pOut blob.  pOut should
    74     74   ** have already been initialized.
    75     75   */
    76         -void hyperlinked_path(const char *zPath, Blob *pOut){
           76  +void hyperlinked_path(const char *zPath, Blob *pOut, const char *zCI){
    77     77     int i, j;
    78     78     char *zSep = "";
    79     79   
    80     80     for(i=0; zPath[i]; i=j){
    81     81       for(j=i; zPath[j] && zPath[j]!='/'; j++){}
    82     82       if( zPath[j] && g.okHistory ){
    83         -      blob_appendf(pOut, "%s<a href=\"%s/dir?name=%#T\">%#h</a>", 
    84         -                   zSep, g.zBaseURL, j, zPath, j-i, &zPath[i]);
           83  +      if( zCI ){
           84  +        blob_appendf(pOut, "%s<a href=\"%s/dir?ci=%S&amp;name=%#T\">%#h</a>", 
           85  +                     zSep, g.zBaseURL, zCI, j, zPath, j-i, &zPath[i]);
           86  +      }else{
           87  +        blob_appendf(pOut, "%s<a href=\"%s/dir?name=%#T\">%#h</a>", 
           88  +                     zSep, g.zBaseURL, j, zPath, j-i, &zPath[i]);
           89  +      }
    85     90       }else{
    86     91         blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
    87     92       }
    88     93       zSep = "/";
    89     94       while( zPath[j]=='/' ){ j++; }
    90     95     }
    91     96   }
................................................................................
    97    102   ** Query parameters:
    98    103   **
    99    104   **    name=PATH        Directory to display.  Required.
   100    105   **    ci=LABEL         Show only files in this check-in.  Optional.
   101    106   */
   102    107   void page_dir(void){
   103    108     const char *zD = P("name");
          109  +  int nD = zD ? strlen(zD)+1 : 0;
   104    110     int mxLen;
   105    111     int nCol, nRow;
   106    112     int cnt, i;
   107    113     char *zPrefix;
   108    114     Stmt q;
   109    115     const char *zCI = P("ci");
   110    116     int rid = 0;
   111         -  Blob content;
          117  +  char *zUuid = 0;
   112    118     Blob dirname;
   113         -  Manifest m;
          119  +  Manifest *pM = 0;
   114    120     const char *zSubdirLink;
   115    121   
   116    122     login_check_credentials();
   117    123     if( !g.okHistory ){ login_needed(); return; }
   118    124     style_header("File List");
   119    125     sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
   120    126                             pathelementFunc, 0, 0);
   121    127   
   122    128     /* If the name= parameter is an empty string, make it a NULL pointer */
   123    129     if( zD && strlen(zD)==0 ){ zD = 0; }
   124    130   
   125         -  /* If a specific check-in is requested, fetch and parse it. */
   126         -  if( zCI && (rid = name_to_rid(zCI))!=0 && content_get(rid, &content) ){
   127         -    if( !manifest_parse(&m, &content) || m.type!=CFTYPE_MANIFEST ){
          131  +  /* If a specific check-in is requested, fetch and parse it.  If the
          132  +  ** specific check-in does not exist, clear zCI.  zCI==0 will cause all
          133  +  ** files from all check-ins to be displayed.
          134  +  */
          135  +  if( zCI ){
          136  +    pM = manifest_get_by_name(zCI, &rid);
          137  +    if( pM ){
          138  +      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
          139  +    }else{
   128    140         zCI = 0;
   129    141       }
   130    142     }
          143  +
   131    144   
   132    145     /* Compute the title of the page */  
   133    146     blob_zero(&dirname);
   134    147     if( zD ){
   135    148       blob_append(&dirname, "in directory ", -1);
   136         -    hyperlinked_path(zD, &dirname);
          149  +    hyperlinked_path(zD, &dirname, zCI);
   137    150       zPrefix = mprintf("%h/", zD);
   138    151     }else{
   139    152       blob_append(&dirname, "in the top-level directory", -1);
   140    153       zPrefix = "";
   141    154     }
   142    155     if( zCI ){
   143         -    char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
   144    156       char zShort[20];
   145    157       memcpy(zShort, zUuid, 10);
   146    158       zShort[10] = 0;
   147    159       @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>]
   148    160       @ %s(blob_str(&dirname))</h2>
   149         -    zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix);
          161  +    zSubdirLink = mprintf("%s/dir?ci=%S&amp;name=%T", g.zTop, zUuid, zPrefix);
   150    162       if( zD ){
   151    163         style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid);
   152    164         style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD);
   153    165       }else{
   154    166         style_submenu_element("All", "All", "%s/dir", g.zBaseURL);
   155    167       }
   156    168     }else{
          169  +    int hasTrunk;
   157    170       @ <h2>The union of all files from all check-ins
   158    171       @ %s(blob_str(&dirname))</h2>
          172  +    hasTrunk = db_exists(
          173  +                  "SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'",
          174  +                  TAG_BRANCH);
   159    175       zSubdirLink = mprintf("%s/dir?name=%T", g.zBaseURL, zPrefix);
   160    176       if( zD ){
   161    177         style_submenu_element("Top", "Top", "%s/dir", g.zBaseURL);
   162         -      style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip",
          178  +      style_submenu_element("Tip", "Tip", "%s/dir?name=%t&amp;ci=tip",
   163    179                               g.zBaseURL, zD);
   164         -      style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk",
   165         -                             g.zBaseURL,zD);
          180  +      if( hasTrunk ){
          181  +        style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&amp;ci=trunk",
          182  +                               g.zBaseURL,zD);
          183  +      }
   166    184       }else{
   167    185         style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zBaseURL);
   168         -      style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL);
          186  +      if( hasTrunk ){
          187  +        style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL);
          188  +      }
   169    189       }
   170    190     }
   171    191   
   172    192     /* Compute the temporary table "localfiles" containing the names
   173    193     ** of all files and subdirectories in the zD[] directory.  
   174    194     **
   175    195     ** Subdirectory names begin with "/".  This causes them to sort
   176    196     ** first and it also gives us an easy way to distinguish files
   177    197     ** from directories in the loop that follows.
   178    198     */
   179    199     db_multi_exec(
   180    200        "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u);"
   181         -     "CREATE TEMP TABLE allfiles(x UNIQUE NOT NULL, u);"
   182    201     );
   183    202     if( zCI ){
   184    203       Stmt ins;
   185         -    int i;
   186         -    db_prepare(&ins, "INSERT INTO allfiles VALUES(:x, :u)");
   187         -    for(i=0; i<m.nFile; i++){
   188         -      db_bind_text(&ins, ":x", m.aFile[i].zName);
   189         -      db_bind_text(&ins, ":u", m.aFile[i].zUuid);
          204  +    ManifestFile *pFile;
          205  +    ManifestFile *pPrev = 0;
          206  +    int nPrev = 0;
          207  +    int c;
          208  +
          209  +    db_prepare(&ins,
          210  +       "INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u)"
          211  +    );
          212  +    manifest_file_rewind(pM);
          213  +    while( (pFile = manifest_file_next(pM,0))!=0 ){
          214  +      if( nD>0 && memcmp(pFile->zName, zD, nD-1)!=0 ) continue;
          215  +      if( pPrev && memcmp(&pFile->zName[nD],&pPrev->zName[nD],nPrev)==0 ){
          216  +        continue;
          217  +      }
          218  +      db_bind_text(&ins, ":x", &pFile->zName[nD]);
          219  +      db_bind_text(&ins, ":u", pFile->zUuid);
   190    220         db_step(&ins);
   191    221         db_reset(&ins);
          222  +      pPrev = pFile;
          223  +      for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
          224  +      if( c=='/' ) nPrev++;
   192    225       }
   193    226       db_finalize(&ins);
   194         -  }else{
          227  +  }else if( zD ){
   195    228       db_multi_exec(
   196         -      "INSERT INTO allfiles SELECT name, NULL FROM filename"
   197         -    );
   198         -  }
   199         -  if( zD ){
   200         -    db_multi_exec(
   201         -       "INSERT OR IGNORE INTO localfiles "
   202         -       "  SELECT pathelement(x,%d), u FROM allfiles"
   203         -       "   WHERE x GLOB '%q/*'",
   204         -       strlen(zD)+1, zD
          229  +      "INSERT OR IGNORE INTO localfiles"
          230  +      " SELECT pathelement(name,%d), NULL FROM filename"
          231  +      "  WHERE name GLOB '%q/*'",
          232  +      nD, zD
   205    233       );
   206    234     }else{
   207    235       db_multi_exec(
   208         -       "INSERT OR IGNORE INTO localfiles "
   209         -       "  SELECT pathelement(x,0), u FROM allfiles"
          236  +      "INSERT OR IGNORE INTO localfiles"
          237  +      " SELECT pathelement(name,0), NULL FROM filename"
   210    238       );
   211    239     }
   212    240   
   213    241     /* Generate a multi-column table listing the contents of zD[]
   214    242     ** directory.
   215    243     */
   216    244     mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
   217    245     cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
   218    246     nCol = 4;
   219    247     nRow = (cnt+nCol-1)/nCol;
   220    248     db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
   221         -  @ <table border="0" width="100%%"><tr><td valign="top" width="25%%">
          249  +  @ <table class="browser"><tr><td class="browser"><ul class="browser">
   222    250     i = 0;
   223    251     while( db_step(&q)==SQLITE_ROW ){
   224    252       const char *zFN;
   225    253       if( i==nRow ){
   226         -      @ </td><td valign="top" width="25%%">
          254  +      @ </ul></td><td class="browser"><ul class="browser">
   227    255         i = 0;
   228    256       }
   229    257       i++;
   230    258       zFN = db_column_text(&q, 0);
   231    259       if( zFN[0]=='/' ){
   232    260         zFN++;
   233    261         @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li>
   234    262       }else if( zCI ){
   235    263         const char *zUuid = db_column_text(&q, 1);
   236         -      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a>
          264  +      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li>
   237    265       }else{
   238         -      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)</a>
          266  +      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
          267  +      @     </a></li>
   239    268       }
   240    269     }
   241    270     db_finalize(&q);
   242         -  @ </td></tr></table>
          271  +  manifest_destroy(pM);
          272  +  @ </ul></td></tr></table>
   243    273     style_footer();
   244    274   }

Changes to src/captcha.c.

    67     67   
    68     68   /*
    69     69   ** Render an 8-character hexadecimal string as ascii art.
    70     70   ** Space to hold the result is obtained from malloc() and should be freed
    71     71   ** by the caller.
    72     72   */
    73     73   char *captcha_render(const char *zPw){
    74         -  char *z = malloc( 500 );
           74  +  char *z = fossil_malloc( 500 );
    75     75     int i, j, k, m;
    76     76   
    77     77     k = 0;
    78     78     for(i=0; i<6; i++){
    79     79       for(j=0; j<8; j++){
    80     80         unsigned char v = hexValue(zPw[j]);
    81     81         v = (aFont1[v] >> ((5-i)*4)) & 0xf;
................................................................................
   200    200   
   201    201   /*
   202    202   ** Render an 8-digit hexadecimal string as ascii arg.
   203    203   ** Space to hold the result is obtained from malloc() and should be freed
   204    204   ** by the caller.
   205    205   */
   206    206   char *captcha_render(const char *zPw){
   207         -  char *z = malloc( 300 );
          207  +  char *z = fossil_malloc( 300 );
   208    208     int i, j, k, m;
   209    209     const char *zChar;
   210    210   
   211    211     k = 0;
   212    212     for(i=0; i<4; i++){
   213    213       for(j=0; j<8; j++){
   214    214         unsigned char v = hexValue(zPw[j]);
................................................................................
   357    357   
   358    358   /*
   359    359   ** Render an 8-digit hexadecimal string as ascii arg.
   360    360   ** Space to hold the result is obtained from malloc() and should be freed
   361    361   ** by the caller.
   362    362   */
   363    363   char *captcha_render(const char *zPw){
   364         -  char *z = malloc( 600 );
          364  +  char *z = fossil_malloc( 600 );
   365    365     int i, j, k, m;
   366    366     const char *zChar;
   367    367   
   368    368     k = 0;
   369    369     for(i=0; i<6; i++){
   370    370       for(j=0; j<8; j++){
   371    371         unsigned char v = hexValue(zPw[j]);
................................................................................
   397    397       printf("%s:\n%s", zHex, z);
   398    398       free(z);
   399    399     }
   400    400   }
   401    401   
   402    402   /*
   403    403   ** Compute a seed value for a captcha.  The seed is public and is sent
   404         -** has a hidden parameter with the page that contains the captcha.  Knowledge
          404  +** as a hidden parameter with the page that contains the captcha.  Knowledge
   405    405   ** of the seed is insufficient for determining the captcha without additional
   406    406   ** information held only on the server and never revealed.
   407    407   */
   408    408   unsigned int captcha_seed(void){
   409    409     unsigned int x;
   410    410     sqlite3_randomness(sizeof(x), &x);
   411    411     x &= 0x7fffffff;

Changes to src/cgi.c.

    18     18   ** This file contains C functions and procedures that provide useful
    19     19   ** services to CGI programs.  There are procedures for parsing and
    20     20   ** dispensing QUERY_STRING parameters and cookies, the "mprintf()"
    21     21   ** formatting function and its cousins, and routines to encode and
    22     22   ** decode strings in HTML or HTTP.
    23     23   */
    24     24   #include "config.h"
    25         -#ifdef __MINGW32__
           25  +#ifdef _WIN32
    26     26   # include <windows.h>           /* for Sleep once server works again */
    27         -# include <winsock2.h>          /* socket operations */
    28         -# define sleep Sleep            /* windows does not have sleep, but Sleep */
    29         -# include <ws2tcpip.h>          
           27  +#  if defined(__MINGW32__)
           28  +#    define sleep Sleep            /* windows does not have sleep, but Sleep */
           29  +#    include <ws2tcpip.h>          
           30  +#  endif
    30     31   #else
    31     32   # include <sys/socket.h>
    32     33   # include <netinet/in.h>
    33     34   # include <arpa/inet.h>
    34     35   # include <sys/times.h>
    35     36   # include <sys/time.h>
    36     37   # include <sys/wait.h>
................................................................................
    39     40   #ifdef __EMX__
    40     41     typedef int socklen_t;
    41     42   #endif
    42     43   #include <time.h>
    43     44   #include <stdio.h>
    44     45   #include <stdlib.h>
    45     46   #include <unistd.h>
           47  +#if defined (__POCC__)
           48  +# undef INTERFACE
           49  +#endif
    46     50   #include "cgi.h"
    47     51   
    48     52   #if INTERFACE
    49     53   /*
    50     54   ** Shortcuts for cgi_parameter.  P("x") returns the value of query parameter
    51     55   ** or cookie "x", or NULL if there is no such parameter or cookie.  PD("x","y")
    52     56   ** does the same except "y" is returned in place of NULL if there is not match.
................................................................................
   381    385   **
   382    386   ** zName and zValue are not copied and must not change or be
   383    387   ** deallocated after this routine returns.
   384    388   */
   385    389   void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
   386    390     if( nAllocQP<=nUsedQP ){
   387    391       nAllocQP = nAllocQP*2 + 10;
   388         -    aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
   389         -    if( aParamQP==0 ) fossil_exit(1);
          392  +    aParamQP = fossil_realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
   390    393     }
   391    394     aParamQP[nUsedQP].zName = zName;
   392    395     aParamQP[nUsedQP].zValue = zValue;
   393    396     if( g.fHttpTrace ){
   394    397       fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
   395    398     }
   396    399     aParamQP[nUsedQP].seq = seqQP++;
................................................................................
   457    460   ** should not be deallocated or changed again after this routine
   458    461   ** returns or it will corrupt the parameter table.
   459    462   */
   460    463   static void add_param_list(char *z, int terminator){
   461    464     while( *z ){
   462    465       char *zName;
   463    466       char *zValue;
   464         -    while( isspace(*z) ){ z++; }
          467  +    while( fossil_isspace(*z) ){ z++; }
   465    468       zName = z;
   466    469       while( *z && *z!='=' && *z!=terminator ){ z++; }
   467    470       if( *z=='=' ){
   468    471         *z = 0;
   469    472         z++;
   470    473         zValue = z;
   471    474         while( *z && *z!=terminator ){ z++; }
................................................................................
   474    477           z++;
   475    478         }
   476    479         dehttpize(zValue);
   477    480       }else{
   478    481         if( *z ){ *z++ = 0; }
   479    482         zValue = "";
   480    483       }
   481         -    if( islower(zName[0]) ){
          484  +    if( fossil_islower(zName[0]) ){
   482    485         cgi_set_parameter_nocopy(zName, zValue);
   483    486       }
   484    487     }
   485    488   }
   486    489   
   487    490   /*
   488    491   ** *pz is a string that consists of multiple lines of text.  This
................................................................................
   569    572   ** '\000' characters are inserted in z[] at the end of each token.
   570    573   ** This routine returns the total number of tokens on the line, 6
   571    574   ** in the example above.
   572    575   */
   573    576   static int tokenize_line(char *z, int mxArg, char **azArg){
   574    577     int i = 0;
   575    578     while( *z ){
   576         -    while( isspace(*z) || *z==';' ){ z++; }
          579  +    while( fossil_isspace(*z) || *z==';' ){ z++; }
   577    580       if( *z=='"' && z[1] ){
   578    581         *z = 0;
   579    582         z++;
   580    583         if( i<mxArg-1 ){ azArg[i++] = z; }
   581    584         while( *z && *z!='"' ){ z++; }
   582    585         if( *z==0 ) break;
   583    586         *z = 0;
   584    587         z++;
   585    588       }else{
   586    589         if( i<mxArg-1 ){ azArg[i++] = z; }
   587         -      while( *z && !isspace(*z) && *z!=';' && *z!='"' ){ z++; }
          590  +      while( *z && !fossil_isspace(*z) && *z!=';' && *z!='"' ){ z++; }
   588    591         if( *z && *z!='"' ){
   589    592           *z = 0;
   590    593           z++;
   591    594         }
   592    595       }
   593    596     }
   594    597     azArg[i] = 0;
................................................................................
   615    618   
   616    619     zBoundry = get_line_from_string(&z, &len);
   617    620     if( zBoundry==0 ) return;
   618    621     while( (zLine = get_line_from_string(&z, &len))!=0 ){
   619    622       if( zLine[0]==0 ){
   620    623         int nContent = 0;
   621    624         zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
   622         -      if( zName && zValue && islower(zName[0]) ){
          625  +      if( zName && zValue && fossil_islower(zName[0]) ){
   623    626           cgi_set_parameter_nocopy(zName, zValue);
   624    627           if( showBytes ){
   625    628             cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
   626    629                  mprintf("%d",nContent));
   627    630           }
   628    631         }
   629    632         zName = 0;
   630    633         showBytes = 0;
   631    634       }else{
   632    635         nArg = tokenize_line(zLine, sizeof(azArg)/sizeof(azArg[0]), azArg);
   633    636         for(i=0; i<nArg; i++){
   634         -        int c = tolower(azArg[i][0]);
          637  +        int c = fossil_tolower(azArg[i][0]);
   635    638           int n = strlen(azArg[i]);
   636    639           if( c=='c' && sqlite3_strnicmp(azArg[i],"content-disposition:",n)==0 ){
   637    640             i++;
   638    641           }else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
   639    642             zName = azArg[++i];
   640    643           }else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
   641    644             char *z = azArg[++i];
   642         -          if( zName && z && islower(zName[0]) ){
          645  +          if( zName && z && fossil_islower(zName[0]) ){
   643    646               cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z);
   644    647             }
   645    648             showBytes = 1;
   646    649           }else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
   647    650             char *z = azArg[++i];
   648         -          if( zName && z && islower(zName[0]) ){
          651  +          if( zName && z && fossil_islower(zName[0]) ){
   649    652               cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z);
   650    653             }
   651    654           }
   652    655         }
   653    656       }
   654    657     }        
   655    658   }
................................................................................
   675    678   
   676    679     len = atoi(PD("CONTENT_LENGTH", "0"));
   677    680     g.zContentType = zType = P("CONTENT_TYPE");
   678    681     if( len>0 && zType ){
   679    682       blob_zero(&g.cgiIn);
   680    683       if( strcmp(zType,"application/x-www-form-urlencoded")==0 
   681    684            || strncmp(zType,"multipart/form-data",19)==0 ){
   682         -      z = malloc( len+1 );
   683         -      if( z==0 ) fossil_exit(1);
          685  +      z = fossil_malloc( len+1 );
   684    686         len = fread(z, 1, len, g.httpIn);
   685    687         z[len] = 0;
   686    688         if( zType[0]=='a' ){
   687    689           add_param_list(z, '&');
   688    690         }else{
   689    691           process_multipart_form_data(z, len);
   690    692         }
................................................................................
   767    769       }
   768    770     }
   769    771   
   770    772     /* If no match is found and the name begins with an upper-case
   771    773     ** letter, then check to see if there is an environment variable
   772    774     ** with the given name.
   773    775     */
   774         -  if( isupper(zName[0]) ){
          776  +  if( fossil_isupper(zName[0]) ){
   775    777       const char *zValue = getenv(zName);
   776    778       if( zValue ){
   777    779         cgi_set_parameter_nocopy(zName, zValue);
   778    780         CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
   779    781         return zValue;
   780    782       }
   781    783     }
................................................................................
   849    851     cgi_parameter("","");  /* Force the parameters into sorted order */
   850    852     for(i=0; i<nUsedQP; i++){
   851    853       cgi_printf("%s = %s  <br />\n",
   852    854          htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1));
   853    855     }
   854    856   }
   855    857   
   856         -/*
   857         -** Write HTML text for an option menu to standard output.  zParam
   858         -** is the query parameter that the option menu sets.  zDflt is the
   859         -** initial value of the option menu.  Addition arguments are name/value
   860         -** pairs that define values on the menu.  The list is terminated with
   861         -** a single NULL argument.
   862         -*/
   863         -void cgi_optionmenu(int in, const char *zP, const char *zD, ...){
   864         -  va_list ap;
   865         -  char *zName, *zVal;
   866         -  int dfltSeen = 0;
   867         -  cgi_printf("%*s<select size=1 name=\"%s\">\n", in, "", zP);
   868         -  va_start(ap, zD);
   869         -  while( (zName = va_arg(ap, char*))!=0 && (zVal = va_arg(ap, char*))!=0 ){
   870         -    if( strcmp(zVal,zD)==0 ){ dfltSeen = 1; break; }
   871         -  }
   872         -  va_end(ap);
   873         -  if( !dfltSeen ){
   874         -    if( zD[0] ){
   875         -      cgi_printf("%*s<option value=\"%h\" selected>%h</option>\n",
   876         -        in+2, "", zD, zD);
   877         -    }else{
   878         -      cgi_printf("%*s<option value=\"\" selected>&nbsp;</option>\n", in+2, "");
   879         -    }
   880         -  }
   881         -  va_start(ap, zD);
   882         -  while( (zName = va_arg(ap, char*))!=0 && (zVal = va_arg(ap, char*))!=0 ){
   883         -    if( zName[0] ){
   884         -      cgi_printf("%*s<option value=\"%h\"%s>%h</option>\n",
   885         -        in+2, "",
   886         -        zVal,
   887         -        strcmp(zVal, zD) ? "" : " selected",
   888         -        zName
   889         -      );
   890         -    }else{
   891         -      cgi_printf("%*s<option value=\"\"%s>&nbsp;</option>\n",
   892         -        in+2, "",
   893         -        strcmp(zVal, zD) ? "" : " selected"
   894         -      );
   895         -    }
   896         -  }
   897         -  va_end(ap);
   898         -  cgi_printf("%*s</select>\n", in, "");
   899         -}
   900         -
   901         -/*
   902         -** This routine works a lot like cgi_optionmenu() except that the list of
   903         -** values is contained in an array.  Also, the values are just values, not
   904         -** name/value pairs as in cgi_optionmenu.
   905         -*/
   906         -void cgi_v_optionmenu(
   907         -  int in,              /* Indent by this amount */
   908         -  const char *zP,      /* The query parameter name */
   909         -  const char *zD,      /* Default value */
   910         -  const char **az      /* NULL-terminated list of allowed values */
   911         -){
   912         -  const char *zVal;
   913         -  int i;
   914         -  cgi_printf("%*s<select size=1 name=\"%s\">\n", in, "", zP);
   915         -  for(i=0; az[i]; i++){
   916         -    if( strcmp(az[i],zD)==0 ) break;
   917         -  }
   918         -  if( az[i]==0 ){
   919         -    if( zD[0]==0 ){
   920         -      cgi_printf("%*s<option value=\"\" selected>&nbsp;</option>\n",
   921         -       in+2, "");
   922         -    }else{
   923         -      cgi_printf("%*s<option value=\"%h\" selected>%h</option>\n",
   924         -       in+2, "", zD, zD);
   925         -    }
   926         -  }
   927         -  while( (zVal = *(az++))!=0  ){
   928         -    if( zVal[0] ){
   929         -      cgi_printf("%*s<option value=\"%h\"%s>%h</option>\n",
   930         -        in+2, "",
   931         -        zVal,
   932         -        strcmp(zVal, zD) ? "" : " selected",
   933         -        zVal
   934         -      );
   935         -    }else{
   936         -      cgi_printf("%*s<option value=\"\"%s>&nbsp;</option>\n",
   937         -        in+2, "",
   938         -        strcmp(zVal, zD) ? "" : " selected"
   939         -      );
   940         -    }
   941         -  }
   942         -  cgi_printf("%*s</select>\n", in, "");
   943         -}
   944         -
   945         -/*
   946         -** This routine works a lot like cgi_v_optionmenu() except that the list
   947         -** is a list of pairs.  The first element of each pair is the value used
   948         -** internally and the second element is the value displayed to the user.
   949         -*/
   950         -void cgi_v_optionmenu2(
   951         -  int in,              /* Indent by this amount */
   952         -  const char *zP,      /* The query parameter name */
   953         -  const char *zD,      /* Default value */
   954         -  const char **az      /* NULL-terminated list of allowed values */
   955         -){
   956         -  const char *zVal;
   957         -  int i;
   958         -  cgi_printf("%*s<select size=1 name=\"%s\">\n", in, "", zP);
   959         -  for(i=0; az[i]; i+=2){
   960         -    if( strcmp(az[i],zD)==0 ) break;
   961         -  }
   962         -  if( az[i]==0 ){
   963         -    if( zD[0]==0 ){
   964         -      cgi_printf("%*s<option value=\"\" selected>&nbsp;</option>\n",
   965         -       in+2, "");
   966         -    }else{
   967         -      cgi_printf("%*s<option value=\"%h\" selected>%h</option>\n",
   968         -       in+2, "", zD, zD);
   969         -    }
   970         -  }
   971         -  while( (zVal = *(az++))!=0  ){
   972         -    const char *zName = *(az++);
   973         -    if( zName[0] ){
   974         -      cgi_printf("%*s<option value=\"%h\"%s>%h</option>\n",
   975         -        in+2, "",
   976         -        zVal,
   977         -        strcmp(zVal, zD) ? "" : " selected",
   978         -        zName
   979         -      );
   980         -    }else{
   981         -      cgi_printf("%*s<option value=\"%h\"%s>&nbsp;</option>\n",
   982         -        in+2, "",
   983         -        zVal,
   984         -        strcmp(zVal, zD) ? "" : " selected"
   985         -      );
   986         -    }
   987         -  }
   988         -  cgi_printf("%*s</select>\n", in, "");
   989         -}
   990         -
   991    858   /*
   992    859   ** This routine works like "printf" except that it has the
   993    860   ** extra formatting capabilities such as %h and %t.
   994    861   */
   995    862   void cgi_printf(const char *zFormat, ...){
   996    863     va_list ap;
   997    864     va_start(ap,zFormat);
................................................................................
  1045    912   */
  1046    913   static char *extract_token(char *zInput, char **zLeftOver){
  1047    914     char *zResult = 0;
  1048    915     if( zInput==0 ){
  1049    916       if( zLeftOver ) *zLeftOver = 0;
  1050    917       return 0;
  1051    918     }
  1052         -  while( isspace(*zInput) ){ zInput++; }
          919  +  while( fossil_isspace(*zInput) ){ zInput++; }
  1053    920     zResult = zInput;
  1054         -  while( *zInput && !isspace(*zInput) ){ zInput++; }
          921  +  while( *zInput && !fossil_isspace(*zInput) ){ zInput++; }
  1055    922     if( *zInput ){
  1056    923       *zInput = 0;
  1057    924       zInput++;
  1058         -    while( isspace(*zInput) ){ zInput++; }
          925  +    while( fossil_isspace(*zInput) ){ zInput++; }
  1059    926     }
  1060    927     if( zLeftOver ){ *zLeftOver = zInput; }
  1061    928     return zResult;
  1062    929   }
  1063    930   
  1064    931   /*
  1065    932   ** This routine handles a single HTTP request which is coming in on
................................................................................
  1070    937   ** the setup.  Once all the setup is finished, this procedure returns
  1071    938   ** and subsequent code handles the actual generation of the webpage.
  1072    939   */
  1073    940   void cgi_handle_http_request(const char *zIpAddr){
  1074    941     char *z, *zToken;
  1075    942     int i;
  1076    943     struct sockaddr_in remoteName;
  1077         -  size_t size = sizeof(struct sockaddr_in);
          944  +  socklen_t size = sizeof(struct sockaddr_in);
  1078    945     char zLine[2000];     /* A single line of input. */
  1079    946   
  1080    947     g.fullHttpReply = 1;
  1081    948     if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
  1082    949       malformed_request();
  1083    950     }
  1084    951     zToken = extract_token(zLine, &z);
................................................................................
  1098    965     cgi_setenv("REQUEST_URI", zToken);
  1099    966     for(i=0; zToken[i] && zToken[i]!='?'; i++){}
  1100    967     if( zToken[i] ) zToken[i++] = 0;
  1101    968     cgi_setenv("PATH_INFO", zToken);
  1102    969     cgi_setenv("QUERY_STRING", &zToken[i]);
  1103    970     if( zIpAddr==0 &&
  1104    971           getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 
  1105         -                                (socklen_t*)&size)>=0
          972  +                                &size)>=0
  1106    973     ){
  1107    974       zIpAddr = inet_ntoa(remoteName.sin_addr);
  1108    975     }
  1109    976     if( zIpAddr ){   
  1110    977       cgi_setenv("REMOTE_ADDR", zIpAddr);
  1111    978       g.zIpAddr = mprintf("%s", zIpAddr);
  1112    979     }
................................................................................
  1115    982     */
  1116    983     while( fgets(zLine,sizeof(zLine),g.httpIn) ){
  1117    984       char *zFieldName;
  1118    985       char *zVal;
  1119    986   
  1120    987       zFieldName = extract_token(zLine,&zVal);
  1121    988       if( zFieldName==0 || *zFieldName==0 ) break;
  1122         -    while( isspace(*zVal) ){ zVal++; }
          989  +    while( fossil_isspace(*zVal) ){ zVal++; }
  1123    990       i = strlen(zVal);
  1124         -    while( i>0 && isspace(zVal[i-1]) ){ i--; }
          991  +    while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
  1125    992       zVal[i] = 0;
  1126         -    for(i=0; zFieldName[i]; i++){ zFieldName[i] = tolower(zFieldName[i]); }
  1127         -    if( strcmp(zFieldName,"user-agent:")==0 ){
  1128         -      cgi_setenv("HTTP_USER_AGENT", zVal);
  1129         -    }else if( strcmp(zFieldName,"content-length:")==0 ){
          993  +    for(i=0; zFieldName[i]; i++){
          994  +      zFieldName[i] = fossil_tolower(zFieldName[i]);
          995  +    }
          996  +    if( strcmp(zFieldName,"content-length:")==0 ){
  1130    997         cgi_setenv("CONTENT_LENGTH", zVal);
  1131         -    }else if( strcmp(zFieldName,"referer:")==0 ){
  1132         -      cgi_setenv("HTTP_REFERER", zVal);
  1133         -    }else if( strcmp(zFieldName,"host:")==0 ){
  1134         -      cgi_setenv("HTTP_HOST", zVal);
  1135    998       }else if( strcmp(zFieldName,"content-type:")==0 ){
  1136    999         cgi_setenv("CONTENT_TYPE", zVal);
  1137   1000       }else if( strcmp(zFieldName,"cookie:")==0 ){
  1138   1001         cgi_setenv("HTTP_COOKIE", zVal);
         1002  +    }else if( strcmp(zFieldName,"https:")==0 ){
         1003  +      cgi_setenv("HTTPS", zVal);
         1004  +    }else if( strcmp(zFieldName,"host:")==0 ){
         1005  +      cgi_setenv("HTTP_HOST", zVal);
  1139   1006       }else if( strcmp(zFieldName,"if-none-match:")==0 ){
  1140   1007         cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
  1141   1008       }else if( strcmp(zFieldName,"if-modified-since:")==0 ){
  1142   1009         cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
  1143   1010       }
         1011  +#if 0
         1012  +    else if( strcmp(zFieldName,"referer:")==0 ){
         1013  +      cgi_setenv("HTTP_REFERER", zVal);
         1014  +    }else if( strcmp(zFieldName,"user-agent:")==0 ){
         1015  +      cgi_setenv("HTTP_USER_AGENT", zVal);
         1016  +    }
         1017  +#endif
  1144   1018     }
  1145   1019   
  1146   1020     cgi_init();
  1147   1021   }
  1148   1022   
         1023  +#if INTERFACE
         1024  +/* 
         1025  +** Bitmap values for the flags parameter to cgi_http_server().
         1026  +*/
         1027  +#define HTTP_SERVER_LOCALHOST      0x0001     /* Bind to 127.0.0.1 only */
         1028  +
         1029  +#endif /* INTERFACE */
         1030  +
  1149   1031   /*
  1150   1032   ** Maximum number of child processes that we can have running
  1151   1033   ** at one time before we start slowing things down.
  1152   1034   */
  1153   1035   #define MAX_PARALLEL 2
  1154   1036   
  1155   1037   /*
................................................................................
  1158   1040   ** As new connections arrive, fork a child and let child return
  1159   1041   ** out of this procedure call.  The child will handle the request.
  1160   1042   ** The parent never returns from this procedure.
  1161   1043   **
  1162   1044   ** Return 0 to each child as it runs.  If unable to establish a
  1163   1045   ** listening socket, return non-zero.
  1164   1046   */
  1165         -int cgi_http_server(int mnPort, int mxPort, char *zBrowser){
  1166         -#ifdef __MINGW32__
         1047  +int cgi_http_server(int mnPort, int mxPort, char *zBrowser, int flags){
         1048  +#if defined(_WIN32)
  1167   1049     /* Use win32_http_server() instead */
  1168   1050     fossil_exit(1);
  1169   1051   #else
  1170   1052     int listener = -1;           /* The server socket */
  1171   1053     int connection;              /* A socket for each individual connection */
  1172   1054     fd_set readfds;              /* Set of file descriptors for select() */
  1173         -  size_t lenaddr;              /* Length of the inaddr structure */
         1055  +  socklen_t lenaddr;           /* Length of the inaddr structure */
  1174   1056     int child;                   /* PID of the child process */
  1175   1057     int nchildren = 0;           /* Number of child processes */
  1176   1058     struct timeval delay;        /* How long to wait inside select() */
  1177   1059     struct sockaddr_in inaddr;   /* The socket address */
  1178   1060     int opt = 1;                 /* setsockopt flag */
  1179   1061     int iPort = mnPort;
  1180   1062   
  1181   1063     while( iPort<=mxPort ){
  1182   1064       memset(&inaddr, 0, sizeof(inaddr));
  1183   1065       inaddr.sin_family = AF_INET;
  1184         -    inaddr.sin_addr.s_addr = INADDR_ANY;
         1066  +    if( flags & HTTP_SERVER_LOCALHOST ){
         1067  +      inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
         1068  +    }else{
         1069  +      inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
         1070  +    }
  1185   1071       inaddr.sin_port = htons(iPort);
  1186   1072       listener = socket(AF_INET, SOCK_STREAM, 0);
  1187   1073       if( listener<0 ){
  1188   1074         iPort++;
  1189   1075         continue;
  1190   1076       }
  1191   1077   
................................................................................
  1222   1108         /* Slow down if connections are arriving too fast */
  1223   1109         sleep( nchildren-MAX_PARALLEL );
  1224   1110       }
  1225   1111       delay.tv_sec = 60;
  1226   1112       delay.tv_usec = 0;
  1227   1113       FD_ZERO(&readfds);
  1228   1114       FD_SET( listener, &readfds);
  1229         -    if( select( listener+1, &readfds, 0, 0, &delay) ){
         1115  +    select( listener+1, &readfds, 0, 0, &delay);
         1116  +    if( FD_ISSET(listener, &readfds) ){
  1230   1117         lenaddr = sizeof(inaddr);
  1231         -      connection = accept(listener, (struct sockaddr*)&inaddr,
  1232         -                                    (socklen_t*) &lenaddr);
         1118  +      connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
  1233   1119         if( connection>=0 ){
  1234   1120           child = fork();
  1235   1121           if( child!=0 ){
  1236   1122             if( child>0 ) nchildren++;
  1237   1123             close(connection);
  1238   1124           }else{
  1239   1125             close(0);

Changes to src/checkin.c.

   213    213     int nTerm = 0;
   214    214     int i;
   215    215     int cTerm;
   216    216   
   217    217     if( zGlobList==0 || zGlobList[0]==0 ) return "0";
   218    218     blob_zero(&expr);
   219    219     while( zGlobList[0] ){
   220         -    while( isspace(zGlobList[0]) || zGlobList[0]==',' ) zGlobList++;
          220  +    while( fossil_isspace(zGlobList[0]) || zGlobList[0]==',' ) zGlobList++;
   221    221       if( zGlobList[0]==0 ) break;
   222    222       if( zGlobList[0]=='\'' || zGlobList[0]=='"' ){
   223    223         cTerm = zGlobList[0];
   224    224         zGlobList++;
   225    225       }else{
   226    226         cTerm = ',';
   227    227       }
   228    228       for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){}
   229    229       if( cTerm==',' ){
   230         -      while( i>0 && isspace(zGlobList[i-1]) ){ i--; }
          230  +      while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; }
   231    231       }
   232    232       blob_appendf(&expr, "%s%s GLOB '%.*q'", zSep, zVal, i, zGlobList);
   233    233       zSep = " OR ";
   234    234       if( cTerm!=',' && zGlobList[i] ) i++;
   235    235       zGlobList += i;
   236    236       if( zGlobList[0] ) zGlobList++;
   237    237       nTerm++;
................................................................................
   257    257   void extra_cmd(void){
   258    258     Blob path;
   259    259     Blob repo;
   260    260     Stmt q;
   261    261     int n;
   262    262     const char *zIgnoreFlag = find_option("ignore",0,1);
   263    263     int allFlag = find_option("dotfiles",0,0)!=0;
          264  +  int outputManifest = db_get_boolean("manifest",0);
   264    265   
   265    266     db_must_be_within_tree();
   266    267     db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
   267    268     n = strlen(g.zLocalRoot);
   268    269     blob_init(&path, g.zLocalRoot, n-1);
   269    270     if( zIgnoreFlag==0 ){
   270    271       zIgnoreFlag = db_get("ignore-glob", 0);
   271    272     }
   272    273     vfile_scan(0, &path, blob_size(&path), allFlag);
   273    274     db_prepare(&q, 
   274    275         "SELECT x FROM sfile"
   275         -      " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_',"
          276  +      " WHERE x NOT IN ('%s','%s','_FOSSIL_',"
   276    277                          "'_FOSSIL_-journal','.fos','.fos-journal',"
   277    278                          "'_FOSSIL_-wal','_FOSSIL_-shm','.fos-wal',"
   278    279                          "'.fos-shm')"
   279    280         "   AND NOT %s"
   280    281         " ORDER BY 1",
          282  +      outputManifest ? "manifest" : "_FOSSIL_",
          283  +      outputManifest ? "manifest.uuid" : "_FOSSIL_",
   281    284         glob_expr("x", zIgnoreFlag)
   282    285     );
   283    286     if( file_tree_name(g.zRepositoryName, &repo, 0) ){
   284    287       db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
   285    288     }
   286    289     while( db_step(&q)==SQLITE_ROW ){
   287    290       printf("%s\n", db_column_text(&q, 0));
................................................................................
   399    402     if( zEditor==0 ){
   400    403       zEditor = getenv("VISUAL");
   401    404     }
   402    405     if( zEditor==0 ){
   403    406       zEditor = getenv("EDITOR");
   404    407     }
   405    408     if( zEditor==0 ){
   406         -#ifdef __MINGW32__
          409  +#if defined(_WIN32)
   407    410       zEditor = "notepad";
   408    411   #else
   409    412       zEditor = "ed";
   410    413   #endif
   411    414     }
   412    415     zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'",
   413    416                      g.zLocalRoot);
   414         -#ifdef __MINGW32__
          417  +#if defined(_WIN32)
   415    418     blob_add_cr(&text);
   416    419   #endif
   417    420     blob_write_to_file(&text, zFile);
   418    421     zCmd = mprintf("%s \"%s\"", zEditor, zFile);
   419    422     printf("%s\n", zCmd);
   420         -  if( portable_system(zCmd) ){
          423  +  if( fossil_system(zCmd) ){
   421    424       fossil_panic("editor aborted");
   422    425     }
   423    426     blob_reset(&text);
   424    427     blob_read_from_file(&text, zFile);
   425    428     blob_remove_cr(&text);
   426    429     unlink(zFile);
   427    430     free(zFile);
   428    431     blob_zero(pComment);
   429    432     while( blob_line(&text, &line) ){
   430    433       int i, n;
   431    434       char *z;
   432    435       n = blob_size(&line);
   433    436       z = blob_buffer(&line);
   434         -    for(i=0; i<n && isspace(z[i]);  i++){}
          437  +    for(i=0; i<n && fossil_isspace(z[i]);  i++){}
   435    438       if( i<n && z[i]=='#' ) continue;
   436    439       if( i<n || blob_size(pComment)>0 ){
   437    440         blob_appendf(pComment, "%b", &line);
   438    441       }
   439    442     }
   440    443     blob_reset(&text);
   441    444     zComment = blob_str(pComment);
   442    445     i = strlen(zComment);
   443         -  while( i>0 && isspace(zComment[i-1]) ){ i--; }
          446  +  while( i>0 && fossil_isspace(zComment[i-1]) ){ i--; }
   444    447     blob_resize(pComment, i);
   445    448   }
   446    449   
   447    450   /*
   448    451   ** Populate the Global.aCommitFile[] based on the command line arguments
   449    452   ** to a [commit] command. Global.aCommitFile is an array of integers
   450    453   ** sized at (N+1), where N is the number of arguments passed to [commit].
................................................................................
   459    462   ** to mean "all files".
   460    463   */
   461    464   void select_commit_files(void){
   462    465     if( g.argc>2 ){
   463    466       int ii;
   464    467       Blob b;
   465    468       blob_zero(&b);
   466         -    g.aCommitFile = malloc(sizeof(int)*(g.argc-1));
          469  +    g.aCommitFile = fossil_malloc(sizeof(int)*(g.argc-1));
   467    470   
   468    471       for(ii=2; ii<g.argc; ii++){
   469    472         int iId;
   470    473         file_tree_name(g.argv[ii], &b, 1);
   471    474         iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
   472    475         if( iId<0 ){
   473    476           fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
................................................................................
   511    514     b = db_exists(
   512    515       "SELECT 1 FROM event"
   513    516       " WHERE datetime(mtime)>=%Q"
   514    517       "   AND type='ci' AND objid=%d",
   515    518       zDate, rid
   516    519     );
   517    520     if( b ){
   518         -    fossil_fatal("ancestor check-in [%.10s] (%s) is younger (clock skew?)",
   519         -                 zUuid, zDate);
          521  +    fossil_fatal("ancestor check-in [%.10s] (%s) is not older (clock skew?)"
          522  +                 " Use -f to override.", zUuid, zDate);
   520    523     }
   521    524   #endif
          525  +}
          526  +
          527  +/*
          528  +** zDate should be a valid date string.  Convert this string into the
          529  +** format YYYY-MM-DDTHH:MM:SS.  If the string is not a valid date, 
          530  +** print a fatal error and quit.
          531  +*/
          532  +char *date_in_standard_format(const char *zInputDate){
          533  +  char *zDate = db_text(0, "SELECT datetime(%Q)", zInputDate);
          534  +  if( zDate[0]==0 ){
          535  +    fossil_fatal("unrecognized date format (%s): use \"YYYY-MM-DD HH:MM:SS\"",
          536  +                 zInputDate);
          537  +  }
          538  +  assert( strlen(zDate)==19 );
          539  +  assert( zDate[10]==' ' );
          540  +  zDate[10] = 'T';
          541  +  return zDate;
          542  +}
          543  +
          544  +/*
          545  +** Create a manifest.
          546  +*/
          547  +static void create_manifest(
          548  +  Blob *pOut,                 /* Write the manifest here */
          549  +  const char *zBaselineUuid,  /* UUID of baseline, or zero */
          550  +  Manifest *pBaseline,        /* Make it a delta manifest if not zero */
          551  +  Blob *pComment,             /* Check-in comment text */
          552  +  int vid,                    /* blob-id of the parent manifest */
          553  +  int verifyDate,             /* Verify that child is younger */
          554  +  Blob *pCksum,               /* Repository checksum.  May be 0 */
          555  +  const char *zDateOvrd,      /* Date override.  If 0 then use 'now' */
          556  +  const char *zUserOvrd,      /* User override.  If 0 then use g.zLogin */
          557  +  const char *zBranch,        /* Branch name.  May be 0 */
          558  +  const char *zBgColor,       /* Background color.  May be 0 */
          559  +  int *pnFBcard               /* Number of generated B- and F-cards */
          560  +){
          561  +  char *zDate;                /* Date of the check-in */
          562  +  char *zParentUuid;          /* UUID of parent check-in */
          563  +  Blob filename;              /* A single filename */
          564  +  int nBasename;              /* Size of base filename */
          565  +  Stmt q;                     /* Query of files changed */
          566  +  Stmt q2;                    /* Query of merge parents */
          567  +  Blob mcksum;                /* Manifest checksum */
          568  +  ManifestFile *pFile;        /* File from the baseline */
          569  +  int nFBcard = 0;            /* Number of B-cards and F-cards */
          570  +
          571  +  assert( pBaseline==0 || pBaseline->zBaseline==0 );
          572  +  assert( pBaseline==0 || zBaselineUuid!=0 );
          573  +  blob_zero(pOut);
          574  +  zParentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
          575  +  if( pBaseline ){
          576  +    blob_appendf(pOut, "B %s\n", zBaselineUuid);
          577  +    manifest_file_rewind(pBaseline);
          578  +    pFile = manifest_file_next(pBaseline, 0);
          579  +    nFBcard++;
          580  +  }else{
          581  +    pFile = 0;
          582  +  }
          583  +  blob_appendf(pOut, "C %F\n", blob_str(pComment));
          584  +  zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
          585  +  blob_appendf(pOut, "D %s\n", zDate);
          586  +  zDate[10] = ' ';
          587  +  db_prepare(&q,
          588  +    "SELECT pathname, uuid, origname, blob.rid, isexe"
          589  +    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
          590  +    " WHERE NOT deleted AND vfile.vid=%d"
          591  +    " ORDER BY 1", vid);
          592  +  blob_zero(&filename);
          593  +  blob_appendf(&filename, "%s", g.zLocalRoot);
          594  +  nBasename = blob_size(&filename);
          595  +  while( db_step(&q)==SQLITE_ROW ){
          596  +    const char *zName = db_column_text(&q, 0);
          597  +    const char *zUuid = db_column_text(&q, 1);
          598  +    const char *zOrig = db_column_text(&q, 2);
          599  +    int frid = db_column_int(&q, 3);
          600  +    int isexe = db_column_int(&q, 4);
          601  +    const char *zPerm;
          602  +    int cmp;
          603  +    blob_append(&filename, zName, -1);
          604  +#if !defined(_WIN32)
          605  +    /* For unix, extract the "executable" permission bit directly from
          606  +    ** the filesystem.  On windows, the "executable" bit is retained
          607  +    ** unchanged from the original. */
          608  +    isexe = file_isexe(blob_str(&filename));
          609  +#endif
................................................................................
          610  +    if( isexe ){
          611  +      zPerm = " x";
          612  +    }else{
          613  +      zPerm = "";
          614  +    }
          615  +    if( !g.markPrivate ) content_make_public(frid);
          616  +    while( pFile && strcmp(pFile->zName,zName)<0 ){
          617  +      blob_appendf(pOut, "F %F\n", pFile->zName);
          618  +      pFile = manifest_file_next(pBaseline, 0);
          619  +      nFBcard++;
          620  +    }
          621  +    cmp = 1;
          622  +    if( pFile==0
          623  +      || (cmp = strcmp(pFile->zName,zName))!=0
          624  +      || strcmp(pFile->zUuid, zUuid)!=0
          625  +    ){
          626  +      blob_resize(&filename, nBasename);
          627  +      if( zOrig==0 || strcmp(zOrig,zName)==0 ){
          628  +        blob_appendf(pOut, "F %F %s%s\n", zName, zUuid, zPerm);
          629  +      }else{
          630  +        if( zPerm[0]==0 ){ zPerm = " w"; }
          631  +        blob_appendf(pOut, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
          632  +      }
          633  +      nFBcard++;
          634  +    }
          635  +    if( cmp==0 ) pFile = manifest_file_next(pBaseline,0);
          636  +  }
          637  +  blob_reset(&filename);
          638  +  db_finalize(&q);
          639  +  while( pFile ){
          640  +    blob_appendf(pOut, "F %F\n", pFile->zName);
          641  +    pFile = manifest_file_next(pBaseline, 0);
          642  +    nFBcard++;
          643  +  }
          644  +  blob_appendf(pOut, "P %s", zParentUuid);
          645  +  if( verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
          646  +  free(zParentUuid);
          647  +  db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
          648  +  db_bind_int(&q2, ":id", 0);
          649  +  while( db_step(&q2)==SQLITE_ROW ){
          650  +    char *zMergeUuid;
          651  +    int mid = db_column_int(&q2, 0);
          652  +    if( !g.markPrivate && content_is_private(mid) ) continue;
          653  +    zMergeUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
          654  +    if( zMergeUuid ){
          655  +      blob_appendf(pOut, " %s", zMergeUuid);
          656  +      if( verifyDate ) checkin_verify_younger(mid, zMergeUuid, zDate);
          657  +      free(zMergeUuid);
          658  +    }
          659  +  }
          660  +  db_finalize(&q2);
          661  +  free(zDate);
          662  +
          663  +  blob_appendf(pOut, "\n");
          664  +  if( pCksum ) blob_appendf(pOut, "R %b\n", pCksum);
          665  +  if( zBranch && zBranch[0] ){
          666  +    Stmt q;
          667  +    if( zBgColor && zBgColor[0] ){
          668  +      blob_appendf(pOut, "T *bgcolor * %F\n", zBgColor);
          669  +    }
          670  +    blob_appendf(pOut, "T *branch * %F\n", zBranch);
          671  +    blob_appendf(pOut, "T *sym-%F *\n", zBranch);
          672  +
          673  +    /* Cancel all other symbolic tags */
          674  +    db_prepare(&q,
          675  +        "SELECT tagname FROM tagxref, tag"
          676  +        " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
          677  +        "   AND tagtype>0 AND tagname GLOB 'sym-*'"
          678  +        "   AND tagname!='sym-'||%Q"
          679  +        " ORDER BY tagname",
          680  +        vid, zBranch);
          681  +    while( db_step(&q)==SQLITE_ROW ){
          682  +      const char *zTag = db_column_text(&q, 0);
          683  +      blob_appendf(pOut, "T -%F *\n", zTag);
          684  +    }
          685  +    db_finalize(&q);
          686  +  }  
          687  +  blob_appendf(pOut, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
          688  +  md5sum_blob(pOut, &mcksum);
          689  +  blob_appendf(pOut, "Z %b\n", &mcksum);
          690  +  if( pnFBcard ) *pnFBcard = nFBcard;
   522    691   }
          692  +
   523    693   
   524    694   /*
   525    695   ** COMMAND: ci
   526    696   ** COMMAND: commit
   527    697   **
   528    698   ** Usage: %fossil commit ?OPTIONS? ?FILE...?
   529    699   **
   530    700   ** Create a new version containing all of the changes in the current
   531    701   ** checkout.  You will be prompted to enter a check-in comment unless
   532         -** the comment has been specified on the command-line using "-m".
   533         -** The editor defined in the "editor" fossil option (see %fossil help set)
   534         -** will be used, or from the "VISUAL" or "EDITOR" environment variables
   535         -** (in that order) if no editor is set.
          702  +** the comment has been specified on the command-line using "-m" or a 
          703  +** file containing the comment using -M.  The editor defined in the
          704  +** "editor" fossil option (see %fossil help set) will be used, or from
          705  +** the "VISUAL" or "EDITOR" environment variables (in that order) if
          706  +** no editor is set.
          707  +**
          708  +** All files that have changed will be committed unless some subset of
          709  +** files is specified on the command line.
   536    710   **
   537         -** You will be prompted for your GPG passphrase in order to sign the
   538         -** new manifest unless the "--nosign" option is used.  All files that
   539         -** have changed will be committed unless some subset of files is
   540         -** specified on the command line.
   541         -**
   542         -** The --branch option followed by a branch name cases the new check-in
          711  +** The --branch option followed by a branch name causes the new check-in
   543    712   ** to be placed in the named branch.  The --bgcolor option can be followed
   544    713   ** by a color name (ex:  '#ffc0c0') to specify the background color of
   545    714   ** entries in the new branch when shown in the web timeline interface.
   546    715   **
   547    716   ** A check-in is not permitted to fork unless the --force or -f
   548    717   ** option appears.  A check-in is not allowed against a closed check-in.
   549    718   **
   550    719   ** The --private option creates a private check-in that is never synced.
   551    720   ** Children of private check-ins are automatically private.
   552    721   **
   553    722   ** Options:
   554    723   **
   555    724   **    --comment|-m COMMENT-TEXT
          725  +**    --message-file|-M COMMENT-FILE
   556    726   **    --branch NEW-BRANCH-NAME
   557    727   **    --bgcolor COLOR
   558    728   **    --nosign
   559    729   **    --force|-f
   560    730   **    --private
          731  +**    --baseline
          732  +**    --delta
   561    733   **    
   562    734   */
   563    735   void commit_cmd(void){
   564         -  int rc;
   565         -  int vid, nrid, nvid;
   566         -  Blob comment;
   567         -  const char *zComment;
   568         -  Stmt q;
   569         -  Stmt q2;
   570         -  char *zUuid, *zDate;
          736  +  int hasChanges;        /* True if unsaved changes exist */
          737  +  int vid;               /* blob-id of parent version */
          738  +  int nrid;              /* blob-id of a modified file */
          739  +  int nvid;              /* Blob-id of the new check-in */
          740  +  Blob comment;          /* Check-in comment */
          741  +  const char *zComment;  /* Check-in comment */
          742  +  Stmt q;                /* Query to find files that have been modified */
          743  +  char *zUuid;           /* UUID of the new check-in */
   571    744     int noSign = 0;        /* True to omit signing the manifest using GPG */
   572    745     int isAMerge = 0;      /* True if checking in a merge */
   573    746     int forceFlag = 0;     /* Force a fork */
          747  +  int forceDelta = 0;    /* Force a delta-manifest */
          748  +  int forceBaseline = 0; /* Force a baseline-manifest */
   574    749     char *zManifestFile;   /* Name of the manifest file */
   575         -  int nBasename;         /* Length of "g.zLocalRoot/" */
          750  +  int useCksum;          /* True if checksums should be computed and verified */
          751  +  int outputManifest;    /* True to output "manifest" and "manifest.uuid" */
          752  +  int testRun;           /* True for a test run.  Debugging only */
   576    753     const char *zBranch;   /* Create a new branch with this name */
   577    754     const char *zBgColor;  /* Set background color when branching */
   578    755     const char *zDateOvrd; /* Override date string */
   579    756     const char *zUserOvrd; /* Override user name */
   580    757     const char *zComFile;  /* Read commit message from this file */
   581         -  Blob filename;         /* complete filename */
   582         -  Blob manifest;
          758  +  Blob manifest;         /* Manifest in baseline form */
   583    759     Blob muuid;            /* Manifest uuid */
   584         -  Blob mcksum;           /* Self-checksum on the manifest */
   585    760     Blob cksum1, cksum2;   /* Before and after commit checksums */
   586    761     Blob cksum1b;          /* Checksum recorded in the manifest */
          762  +  int szD;               /* Size of the delta manifest */
          763  +  int szB;               /* Size of the baseline manifest */
   587    764    
   588    765     url_proxy_options();
   589    766     noSign = find_option("nosign",0,0)!=0;
          767  +  forceDelta = find_option("delta",0,0)!=0;
          768  +  forceBaseline = find_option("baseline",0,0)!=0;
          769  +  if( forceDelta && forceBaseline ){
          770  +    fossil_fatal("cannot use --delta and --baseline together");
          771  +  }
          772  +  testRun = find_option("test",0,0)!=0;
   590    773     zComment = find_option("comment","m",1);
   591    774     forceFlag = find_option("force", "f", 0)!=0;
   592    775     zBranch = find_option("branch","b",1);
   593    776     zBgColor = find_option("bgcolor",0,1);
   594    777     zComFile = find_option("message-file", "M", 1);
   595    778     if( find_option("private",0,0) ){
   596    779       g.markPrivate = 1;
................................................................................
   598    781       if( zBgColor==0 ) zBgColor = "#fec084";  /* Orange */
   599    782     }
   600    783     zDateOvrd = find_option("date-override",0,1);
   601    784     zUserOvrd = find_option("user-override",0,1);
   602    785     db_must_be_within_tree();
   603    786     noSign = db_get_boolean("omitsign", 0)|noSign;
   604    787     if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
          788  +  useCksum = db_get_boolean("repo-cksum", 1);
          789  +  outputManifest = db_get_boolean("manifest", 0);
   605    790     verify_all_options();
          791  +
          792  +  /* So that older versions of Fossil (that do not understand delta-
          793  +  ** manifest) can continue to use this repository, do not create a new
          794  +  ** delta-manifest unless this repository already contains one or more
          795  +  ** delta-manifets, or unless the delta-manifest is explicitly requested
          796  +  ** by the --delta option.
          797  +  */
          798  +  if( !forceDelta && !db_get_boolean("seen-delta-manifest",0) ){
          799  +    forceBaseline = 1;
          800  +  }
   606    801   
   607    802     /* Get the ID of the parent manifest artifact */
   608    803     vid = db_lget_int("checkout", 0);
   609    804     if( content_is_private(vid) ){
   610    805       g.markPrivate = 1;
   611    806     }
   612    807   
   613    808     /*
   614    809     ** Autosync if autosync is enabled and this is not a private check-in.
   615    810     */
   616    811     if( !g.markPrivate ){
   617    812       autosync(AUTOSYNC_PULL);
   618    813     }
          814  +
          815  +  /* Require confirmation to continue with the check-in if there is
          816  +  ** clock skew
          817  +  */
          818  +  if( g.clockSkewSeen ){
          819  +    Blob ans;
          820  +    blob_zero(&ans);
          821  +    prompt_user("continue in spite of time skew (y/N)? ", &ans);
          822  +    if( blob_str(&ans)[0]!='y' ){
          823  +      fossil_exit(1);
          824  +    }
          825  +  }
   619    826   
   620    827     /* There are two ways this command may be executed. If there are
   621    828     ** no arguments following the word "commit", then all modified files
   622    829     ** in the checked out directory are committed. If one or more arguments
   623    830     ** follows "commit", then only those files are committed.
   624    831     **
   625    832     ** After the following function call has returned, the Global.aCommitFile[]
................................................................................
   637    844     /*
   638    845     ** Check that the user exists.
   639    846     */
   640    847     if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
   641    848       fossil_fatal("no such user: %s", g.zLogin);
   642    849     }
   643    850     
          851  +  hasChanges = unsaved_changes();
   644    852     db_begin_transaction();
   645    853     db_record_repository_filename(0);
   646         -  rc = unsaved_changes();
   647         -  if( rc==0 && !isAMerge && !forceFlag ){
   648         -    fossil_panic("nothing has changed");
          854  +  if( hasChanges==0 && !isAMerge && !forceFlag ){
          855  +    fossil_fatal("nothing has changed");
   649    856     }
   650    857   
   651    858     /* If one or more files that were named on the command line have not
   652    859     ** been modified, bail out now.
   653    860     */
   654    861     if( g.aCommitFile ){
   655    862       Blob unmodified;
................................................................................
   676    883     */
   677    884     if( db_exists("SELECT 1 FROM tagxref"
   678    885                   " WHERE tagid=%d AND rid=%d AND tagtype>0",
   679    886                   TAG_CLOSED, vid) ){
   680    887       fossil_fatal("cannot commit against a closed leaf");
   681    888     }
   682    889   
   683         -  vfile_aggregate_checksum_disk(vid, &cksum1);
          890  +  if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1);
   684    891     if( zComment ){
   685    892       blob_zero(&comment);
   686    893       blob_append(&comment, zComment, -1);
   687    894     }else if( zComFile ){
   688    895       blob_zero(&comment);
   689    896       blob_read_from_file(&comment, zComFile);
   690    897     }else{
................................................................................
   731    938         content_deltify(rid, nrid, 0);
   732    939       }
   733    940       db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d WHERE id=%d", nrid,nrid,id);
   734    941       db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
   735    942     }
   736    943     db_finalize(&q);
   737    944   
   738         -  /* Create the manifest */
   739         -  blob_zero(&manifest);
          945  +  /* Create the new manifest */
   740    946     if( blob_size(&comment)==0 ){
   741    947       blob_append(&comment, "(no comment)", -1);
   742    948     }
   743         -  blob_appendf(&manifest, "C %F\n", blob_str(&comment));
   744         -  zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
   745         -  zDate[10] = 'T';
   746         -  blob_appendf(&manifest, "D %s\n", zDate);
   747         -  zDate[10] = ' ';
   748         -  db_prepare(&q,
   749         -    "SELECT pathname, uuid, origname, blob.rid, isexe"
   750         -    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
   751         -    " WHERE NOT deleted AND vfile.vid=%d"
   752         -    " ORDER BY 1", vid);
   753         -  blob_zero(&filename);
   754         -  blob_appendf(&filename, "%s", g.zLocalRoot);
   755         -  nBasename = blob_size(&filename);
   756         -  while( db_step(&q)==SQLITE_ROW ){
   757         -    const char *zName = db_column_text(&q, 0);
   758         -    const char *zUuid = db_column_text(&q, 1);
   759         -    const char *zOrig = db_column_text(&q, 2);
   760         -    int frid = db_column_int(&q, 3);
   761         -    int isexe = db_column_int(&q, 4);
   762         -    const char *zPerm;
   763         -    blob_append(&filename, zName, -1);
   764         -#ifndef __MINGW32__
   765         -    /* For unix, extract the "executable" permission bit directly from
   766         -    ** the filesystem.  On windows, the "executable" bit is retained
   767         -    ** unchanged from the original. */
   768         -    isexe = file_isexe(blob_str(&filename));
   769         -#endif
   770         -    if( isexe ){
   771         -      zPerm = " x";
          949  +  if( forceDelta ){
          950  +    blob_zero(&manifest);
          951  +  }else{
          952  +    create_manifest(&manifest, 0, 0, &comment, vid,
          953  +                    !forceFlag, useCksum ? &cksum1 : 0,
          954  +                    zDateOvrd, zUserOvrd, zBranch, zBgColor, &szB);
          955  +  }
          956  +
          957  +  /* See if a delta-manifest would be more appropriate */
          958  +  if( !forceBaseline ){
          959  +    const char *zBaselineUuid;
          960  +    Manifest *pParent;
          961  +    Manifest *pBaseline;
          962  +    pParent = manifest_get(vid, CFTYPE_MANIFEST);
          963  +    if( pParent && pParent->zBaseline ){
          964  +      zBaselineUuid = pParent->zBaseline;
          965  +      pBaseline = manifest_get_by_name(zBaselineUuid, 0);
   772    966       }else{
   773         -      zPerm = "";
   774         -    }
   775         -    blob_resize(&filename, nBasename);
   776         -    if( zOrig==0 || strcmp(zOrig,zName)==0 ){
   777         -      blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
   778         -    }else{
   779         -      if( zPerm[0]==0 ){ zPerm = " w"; }
   780         -      blob_appendf(&manifest, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
          967  +      zBaselineUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
          968  +      pBaseline = pParent;
   781    969       }
   782         -    if( !g.markPrivate ) content_make_public(frid);
   783         -  }
   784         -  blob_reset(&filename);
   785         -  db_finalize(&q);
   786         -  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
   787         -  blob_appendf(&manifest, "P %s", zUuid);
   788         -  checkin_verify_younger(vid, zUuid, zDate);
   789         -
   790         -  db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
   791         -  db_bind_int(&q2, ":id", 0);
   792         -  while( db_step(&q2)==SQLITE_ROW ){
   793         -    int mid = db_column_int(&q2, 0);
   794         -    if( !g.markPrivate && content_is_private(mid) ) continue;
   795         -    zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
   796         -    if( zUuid ){
   797         -      blob_appendf(&manifest, " %s", zUuid);
   798         -      checkin_verify_younger(mid, zUuid, zDate);
   799         -      free(zUuid);
          970  +    if( pBaseline ){
          971  +      Blob delta;
          972  +      create_manifest(&delta, zBaselineUuid, pBaseline, &comment, vid,
          973  +                      !forceFlag, useCksum ? &cksum1 : 0,
          974  +                      zDateOvrd, zUserOvrd, zBranch, zBgColor, &szD);
          975  +      /*
          976  +      ** At this point, two manifests have been constructed, either of
          977  +      ** which would work for this checkin.  The first manifest (held
          978  +      ** in the "manifest" variable) is a baseline manifest and the second
          979  +      ** (held in variable named "delta") is a delta manifest.  The
          980  +      ** question now is: which manifest should we use?
          981  +      **
          982  +      ** Let B be the number of F-cards in the baseline manifest and
          983  +      ** let D be the number of F-cards in the delta manifest, plus one for
          984  +      ** the B-card.  (B is held in the szB variable and D is held in the
          985  +      ** szD variable.)  Assume that all delta manifests adds X new F-cards.
          986  +      ** Then to minimize the total number of F- and B-cards in the repository,
          987  +      ** we should use the delta manifest if and only if:
          988  +      **
          989  +      **      D*D < B*X - X*X
          990  +      **
          991  +      ** X is an unknown here, but for most repositories, we will not be
          992  +      ** far wrong if we assume X=3.
          993  +      */
          994  +      if( forceDelta || (szD*szD)<(szB*3-9) ){
          995  +        blob_reset(&manifest);
          996  +        manifest = delta;
          997  +      }else{
          998  +        blob_reset(&delta);
          999  +      }
         1000  +    }else if( forceDelta ){
         1001  +      fossil_panic("unable to find a baseline-manifest for the delta");
   800   1002       }
   801   1003     }
   802         -  db_reset(&q2);
   803         -
   804         -  blob_appendf(&manifest, "\n");
   805         -  blob_appendf(&manifest, "R %b\n", &cksum1);
   806         -  if( zBranch && zBranch[0] ){
   807         -    Stmt q;
   808         -    if( zBgColor && zBgColor[0] ){
   809         -      blob_appendf(&manifest, "T *bgcolor * %F\n", zBgColor);
   810         -    }
   811         -    blob_appendf(&manifest, "T *branch * %F\n", zBranch);
   812         -    blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
   813         -
   814         -    /* Cancel all other symbolic tags */
   815         -    db_prepare(&q,
   816         -        "SELECT tagname FROM tagxref, tag"
   817         -        " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
   818         -        "   AND tagtype>0 AND tagname GLOB 'sym-*'"
   819         -        "   AND tagname!='sym-'||%Q"
   820         -        " ORDER BY tagname",
   821         -        vid, zBranch);
   822         -    while( db_step(&q)==SQLITE_ROW ){
   823         -      const char *zTag = db_column_text(&q, 0);
   824         -      blob_appendf(&manifest, "T -%F *\n", zTag);
   825         -    }
   826         -    db_finalize(&q);
   827         -  }  
   828         -  blob_appendf(&manifest, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
   829         -  md5sum_blob(&manifest, &mcksum);
   830         -  blob_appendf(&manifest, "Z %b\n", &mcksum);
   831         -  zManifestFile = mprintf("%smanifest", g.zLocalRoot);
   832   1004     if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
   833   1005       Blob ans;
   834   1006       blob_zero(&ans);
   835   1007       prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
   836   1008       if( blob_str(&ans)[0]!='y' ){
   837   1009         fossil_exit(1);
   838   1010       }
   839   1011     }
   840         -  blob_write_to_file(&manifest, zManifestFile);
   841         -  blob_reset(&manifest);
   842         -  blob_read_from_file(&manifest, zManifestFile);
   843         -  free(zManifestFile);
         1012  +
         1013  +  /* If the --test option is specified, output the manifest file
         1014  +  ** and rollback the transaction.  
         1015  +  */
         1016  +  if( testRun ){
         1017  +    blob_write_to_file(&manifest, "");
         1018  +  }
         1019  +
         1020  +  if( outputManifest ){
         1021  +    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
         1022  +    blob_write_to_file(&manifest, zManifestFile);
         1023  +    blob_reset(&manifest);
         1024  +    blob_read_from_file(&manifest, zManifestFile);
         1025  +    free(zManifestFile);
         1026  +  }
   844   1027     nvid = content_put(&manifest, 0, 0);
   845   1028     if( nvid==0 ){
   846   1029       fossil_panic("trouble committing manifest: %s", g.zErrMsg);
   847   1030     }
   848   1031     db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
   849   1032     manifest_crosslink(nvid, &manifest);
   850   1033     content_deltify(vid, nvid, 0);
   851   1034     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
   852   1035     printf("New_Version: %s\n", zUuid);
   853         -  zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
   854         -  blob_zero(&muuid);
   855         -  blob_appendf(&muuid, "%s\n", zUuid);
   856         -  blob_write_to_file(&muuid, zManifestFile);
   857         -  free(zManifestFile);
   858         -  blob_reset(&muuid);
         1036  +  if( outputManifest ){
         1037  +    zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
         1038  +    blob_zero(&muuid);
         1039  +    blob_appendf(&muuid, "%s\n", zUuid);
         1040  +    blob_write_to_file(&muuid, zManifestFile);
         1041  +    free(zManifestFile);
         1042  +    blob_reset(&muuid);
         1043  +  }
   859   1044   
   860   1045     
   861   1046     /* Update the vfile and vmerge tables */
   862   1047     db_multi_exec(
   863   1048       "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
   864   1049       "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
   865   1050       "UPDATE vfile SET vid=%d;"
   866   1051       "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
   867   1052       " WHERE file_is_selected(id);"
   868   1053       , vid, nvid
   869   1054     );
   870   1055     db_lset_int("checkout", nvid);
   871   1056   
   872         -  /* Verify that the repository checksum matches the expected checksum
   873         -  ** calculated before the checkin started (and stored as the R record
   874         -  ** of the manifest file).
   875         -  */
   876         -  vfile_aggregate_checksum_repository(nvid, &cksum2);
   877         -  if( blob_compare(&cksum1, &cksum2) ){
   878         -    fossil_panic("tree checksum does not match repository after commit");
   879         -  }
   880         -
   881         -  /* Verify that the manifest checksum matches the expected checksum */
   882         -  vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
   883         -  if( blob_compare(&cksum1, &cksum1b) ){
   884         -    fossil_panic("manifest checksum does not agree with manifest: "
   885         -                 "%b versus %b", &cksum1, &cksum1b);
   886         -  }
   887         -  if( blob_compare(&cksum1, &cksum2) ){
   888         -    fossil_panic("tree checksum does not match manifest after commit: "
   889         -                 "%b versus %b", &cksum1, &cksum2);
   890         -  }
   891         -
   892         -  /* Verify that the commit did not modify any disk images. */
   893         -  vfile_aggregate_checksum_disk(nvid, &cksum2);
   894         -  if( blob_compare(&cksum1, &cksum2) ){
   895         -    fossil_panic("tree checksums before and after commit do not match");
         1057  +  if( useCksum ){
         1058  +    /* Verify that the repository checksum matches the expected checksum
         1059  +    ** calculated before the checkin started (and stored as the R record
         1060  +    ** of the manifest file).
         1061  +    */
         1062  +    vfile_aggregate_checksum_repository(nvid, &cksum2);
         1063  +    if( blob_compare(&cksum1, &cksum2) ){
         1064  +      fossil_panic("tree checksum does not match repository after commit");
         1065  +    }
         1066  +  
         1067  +    /* Verify that the manifest checksum matches the expected checksum */
         1068  +    vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
         1069  +    if( blob_compare(&cksum1, &cksum1b) ){
         1070  +      fossil_panic("manifest checksum does not agree with manifest: "
         1071  +                   "%b versus %b", &cksum1, &cksum1b);
         1072  +    }
         1073  +    if( blob_compare(&cksum1, &cksum2) ){
         1074  +      fossil_panic("tree checksum does not match manifest after commit: "
         1075  +                   "%b versus %b", &cksum1, &cksum2);
         1076  +    }
         1077  +  
         1078  +    /* Verify that the commit did not modify any disk images. */
         1079  +    vfile_aggregate_checksum_disk(nvid, &cksum2);
         1080  +    if( blob_compare(&cksum1, &cksum2) ){
         1081  +      fossil_panic("tree checksums before and after commit do not match");
         1082  +    }
   896   1083     }
   897   1084   
   898   1085     /* Clear the undo/redo stack */
   899   1086     undo_reset();
   900   1087   
   901   1088     /* Commit */
   902   1089     db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
         1090  +  if( testRun ){
         1091  +    db_end_transaction(1);
         1092  +    exit(1);
         1093  +  }
   903   1094     db_end_transaction(0);
   904   1095   
   905   1096     if( !g.markPrivate ){
   906   1097       autosync(AUTOSYNC_PUSH);  
   907   1098     }
   908   1099     if( count_nonbranch_children(vid)>1 ){
   909   1100       printf("**** warning: a fork has occurred *****\n");
   910   1101     }
   911   1102   }

Changes to src/checkout.c.

    76     76     return vid;
    77     77   }
    78     78   
    79     79   /*
    80     80   ** Load a vfile from a record ID.
    81     81   */
    82     82   void load_vfile_from_rid(int vid){
    83         -  Blob manifest;
    84         -
    85     83     if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){
    86     84       return;
    87     85     }
    88         -  content_get(vid, &manifest);
    89         -  vfile_build(vid, &manifest);
    90         -  blob_reset(&manifest);
           86  +  vfile_build(vid);
    91     87   }
    92     88   
    93     89   /*
    94     90   ** Set or clear the vfile.isexe flag for a file.
    95     91   */
    96     92   static void set_or_clear_isexe(const char *zFilename, int vid, int onoff){
    97         -  db_multi_exec("UPDATE vfile SET isexe=%d WHERE vid=%d and pathname=%Q",
    98         -                onoff, vid, zFilename);
           93  +  static Stmt s;
           94  +  db_static_prepare(&s,
           95  +    "UPDATE vfile SET isexe=:isexe"
           96  +    " WHERE vid=:vid AND pathname=:path AND isexe!=:isexe"
           97  +  );
           98  +  db_bind_int(&s, ":isexe", onoff);
           99  +  db_bind_int(&s, ":vid", vid);
          100  +  db_bind_text(&s, ":path", zFilename);
          101  +  db_step(&s);
          102  +  db_reset(&s);
          103  +}
          104  +
          105  +/*
          106  +** Set or clear the execute permission bit (as appropriate) for all
          107  +** files in the current check-out.
          108  +*/
          109  +void checkout_set_all_exe(int vid){
          110  +  Blob filename;
          111  +  int baseLen;
          112  +  Manifest *pManifest;
          113  +  ManifestFile *pFile;
          114  +
          115  +  /* Check the EXE permission status of all files
          116  +  */
          117  +  pManifest = manifest_get(vid, CFTYPE_MANIFEST);
          118  +  if( pManifest==0 ) return;
          119  +  blob_zero(&filename);
          120  +  blob_appendf(&filename, "%s/", g.zLocalRoot);
          121  +  baseLen = blob_size(&filename);
          122  +  manifest_file_rewind(pManifest);
          123  +  while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
          124  +    int isExe;
          125  +    blob_append(&filename, pFile->zName, -1);
          126  +    isExe = pFile->zPerm && strstr(pFile->zPerm, "x");
          127  +    file_setexe(blob_str(&filename), isExe);
          128  +    set_or_clear_isexe(pFile->zName, vid, isExe);
          129  +    blob_resize(&filename, baseLen);
          130  +  }
          131  +  blob_reset(&filename);
          132  +  manifest_destroy(pManifest);
    99    133   }
          134  +
   100    135   
   101    136   /*
   102         -** Read the manifest file given by vid out of the repository
   103         -** and store it in the root of the local check-out.
          137  +** If the "manifest" setting is true, then automatically generate
          138  +** files named "manifest" and "manifest.uuid" containing, respectively,
          139  +** the text of the manifest and the artifact ID of the manifest.
   104    140   */
   105    141   void manifest_to_disk(int vid){
   106    142     char *zManFile;
   107    143     Blob manifest;
   108    144     Blob hash;
   109         -  Blob filename;
   110         -  int baseLen;
   111         -  int i;
   112         -  Manifest m;
   113    145   
   114         -  blob_zero(&manifest);
   115         -  zManFile = mprintf("%smanifest", g.zLocalRoot);
   116         -  content_get(vid, &manifest);
   117         -  blob_write_to_file(&manifest, zManFile);
   118         -  free(zManFile);
   119         -  blob_zero(&hash);
   120         -  sha1sum_blob(&manifest, &hash);
   121         -  zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
   122         -  blob_append(&hash, "\n", 1);
   123         -  blob_write_to_file(&hash, zManFile);
   124         -  free(zManFile);
   125         -  blob_reset(&hash);
   126         -  manifest_parse(&m, &manifest);
   127         -  blob_zero(&filename);
   128         -  blob_appendf(&filename, "%s/", g.zLocalRoot);
   129         -  baseLen = blob_size(&filename);
   130         -  for(i=0; i<m.nFile; i++){ 
   131         -    int isExe;
   132         -    blob_append(&filename, m.aFile[i].zName, -1);
   133         -    isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x");
   134         -    file_setexe(blob_str(&filename), isExe);
   135         -    set_or_clear_isexe(m.aFile[i].zName, vid, isExe);
   136         -    blob_resize(&filename, baseLen);
          146  +  if( db_get_boolean("manifest",0) ){
          147  +    blob_zero(&manifest);
          148  +    content_get(vid, &manifest);
          149  +    zManFile = mprintf("%smanifest", g.zLocalRoot);
          150  +    blob_write_to_file(&manifest, zManFile);
          151  +    free(zManFile);
          152  +    blob_zero(&hash);
          153  +    sha1sum_blob(&manifest, &hash);
          154  +    zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
          155  +    blob_append(&hash, "\n", 1);
          156  +    blob_write_to_file(&hash, zManFile);
          157  +    free(zManFile);
          158  +    blob_reset(&hash);
          159  +  }else{
          160  +    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
          161  +      zManFile = mprintf("%smanifest", g.zLocalRoot);
          162  +      unlink(zManFile);
          163  +      free(zManFile);
          164  +    }
          165  +    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
          166  +      zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
          167  +      unlink(zManFile);
          168  +      free(zManFile);
          169  +    }
   137    170     }
   138         -  blob_reset(&filename);
   139         -  manifest_clear(&m);
          171  +    
   140    172   }
   141    173   
   142    174   /*
   143    175   ** COMMAND: checkout
   144    176   ** COMMAND: co
   145    177   **
   146    178   ** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
................................................................................
   206    238     if( !keepFlag ){
   207    239       uncheckout(prior);
   208    240     }
   209    241     db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
   210    242     if( !keepFlag ){
   211    243       vfile_to_disk(vid, 0, 1, promptFlag);
   212    244     }
          245  +  checkout_set_all_exe(vid);
   213    246     manifest_to_disk(vid);
   214    247     db_lset_int("checkout", vid);
   215    248     undo_reset();
   216    249     db_multi_exec("DELETE FROM vmerge");
   217    250     if( !keepFlag ){
   218    251       vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
   219    252       vfile_aggregate_checksum_disk(vid, &cksum2);
   220    253       if( blob_compare(&cksum1, &cksum2) ){
   221    254         printf("WARNING: manifest checksum does not agree with disk\n");
   222    255       }
   223         -    if( blob_compare(&cksum1, &cksum1b) ){
          256  +    if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){
   224    257         printf("WARNING: manifest checksum does not agree with manifest\n");
   225    258       }
   226    259     }
   227    260     db_end_transaction(0);
   228    261   }
   229    262   
   230    263   /*

Changes to src/clearsign.c.

    37     37       return 0;
    38     38     }
    39     39     zRand = db_text(0, "SELECT hex(randomblob(10))");
    40     40     zOut = mprintf("out-%s", zRand);
    41     41     zIn = mprintf("in-%z", zRand);
    42     42     blob_write_to_file(pIn, zOut);
    43     43     zCmd = mprintf("%s %s %s", zBase, zIn, zOut);
    44         -  rc = portable_system(zCmd);
           44  +  rc = fossil_system(zCmd);
    45     45     free(zCmd);
    46     46     if( rc==0 ){
    47     47       if( pOut==pIn ){
    48     48         blob_reset(pIn);
    49     49       }
    50     50       blob_zero(pOut);
    51     51       blob_read_from_file(pOut, zIn);

Changes to src/comformat.c.

    36     36     int tlen = lineLength - indent;
    37     37     int si, sk, i, k;
    38     38     int doIndent = 0;
    39     39     char zBuf[400];
    40     40     int lineCnt = 0; 
    41     41   
    42     42     for(;;){
    43         -    while( isspace(zText[0]) ){ zText++; }
           43  +    while( fossil_isspace(zText[0]) ){ zText++; }
    44     44       if( zText[0]==0 ){
    45     45         if( doIndent==0 ){
    46     46           printf("\n");
    47     47           lineCnt = 1;
    48     48         }
    49     49         return lineCnt;
    50     50       }
    51     51       for(sk=si=i=k=0; zText[i] && k<tlen; i++){
    52     52         char c = zText[i];
    53         -      if( isspace(c) ){
           53  +      if( fossil_isspace(c) ){
    54     54           si = i;
    55     55           sk = k;
    56     56           if( k==0 || zBuf[k-1]!=' ' ){
    57     57             zBuf[k++] = ' ';
    58     58           }
    59     59         }else{
    60     60           zBuf[k] = c;
    61         -        if( c=='-' && k>0 && isalpha(zBuf[k-1]) ){
           61  +        if( c=='-' && k>0 && fossil_isalpha(zBuf[k-1]) ){
    62     62             si = i+1;
    63     63             sk = k+1;
    64     64           }
    65     65           k++;
    66     66         }
    67     67       }
    68     68       if( doIndent ){

Changes to src/config.h.

    14     14   **   http://www.hwaci.com/drh/
    15     15   **
    16     16   *******************************************************************************
    17     17   **
    18     18   ** A common header file used by all modules.
    19     19   */
    20     20   
           21  +/* The following macros are necessary for large-file support under
           22  +** some linux distributions, and possibly other unixes as well.
           23  +*/
           24  +#define _LARGE_FILE       1
           25  +#ifndef _FILE_OFFSET_BITS
           26  +#  define _FILE_OFFSET_BITS 64
           27  +#endif
           28  +#define _LARGEFILE_SOURCE 1
           29  +
           30  +#ifndef _RC_COMPILE_
           31  +
    21     32   /*
    22     33   ** System header files used by all modules
    23     34   */
    24     35   #include <unistd.h>
    25     36   #include <stdio.h>
    26     37   #include <stdlib.h>
    27         -#include <ctype.h>
           38  +/* #include <ctype.h> // do not use - causes problems */
    28     39   #include <string.h>
    29     40   #include <stdarg.h>
    30     41   #include <assert.h>
    31         -#ifdef __MINGW32__
    32         -# include <windows.h>
           42  +
           43  +#endif
           44  +
           45  +#if defined( __MINGW32__) ||  defined(__DMC__) || defined(_MSC_VER) || defined(__POCC__)
           46  +#  if defined(__DMC__)  || defined(_MSC_VER) || defined(__POCC__)
           47  +     typedef int socklen_t;
           48  +#  endif
           49  +#  ifndef _WIN32
           50  +#    define _WIN32
           51  +#  endif
    33     52   #else
           53  +# include <sys/types.h>
           54  +# include <signal.h>
    34     55   # include <pwd.h>
    35     56   #endif
    36     57   
           58  +/*
           59  +** Define the compiler variant, used to compile the project
           60  +*/
           61  +#if !defined(COMPILER_NAME)
           62  +#  if defined(__DMC__)
           63  +#    define COMPILER_NAME "dmc"
           64  +#  elif defined(__POCC__)
           65  +#    if defined(_M_X64)
           66  +#      define COMPILER_NAME "pellesc64"
           67  +#    else
           68  +#      define COMPILER_NAME "pellesc32"
           69  +#    endif
           70  +#  elif defined(_MSC_VER)
           71  +#    define COMPILER_NAME "msc"
           72  +#  elif defined(__MINGW32__)
           73  +#    define COMPILER_NAME "mingw32"
           74  +#  elif defined(_WIN32)
           75  +#    define COMPILER_NAME "win32"
           76  +#  elif defined(__GNUC__)
           77  +#    define COMPILER_NAME "gcc-" __VERSION__
           78  +#  else
           79  +#    define COMPILER_NAME "unknown"
           80  +#  endif
           81  +#endif
           82  +
           83  +#ifndef _RC_COMPILE_
           84  +
    37     85   #include "sqlite3.h"
    38     86   
    39     87   /*
    40     88   ** Typedef for a 64-bit integer
    41     89   */
    42         -typedef sqlite_int64 i64;
    43         -typedef sqlite_uint64 u64;
           90  +typedef sqlite3_int64 i64;
           91  +typedef sqlite3_uint64 u64;
    44     92   
    45     93   /*
    46     94   ** Unsigned character type
    47     95   */
    48     96   typedef unsigned char u8;
    49     97   
    50         -/*
    51         -** Standard colors.  These colors can also be changed using a stylesheet.
    52         -*/
    53         -
    54         -/* A blue border and background.  Used for the title bar and for dates
    55         -** in a timeline.
    56         -*/
    57         -#define BORDER1       "#a0b5f4"      /* Stylesheet class: border1 */
    58         -#define BG1           "#d0d9f4"      /* Stylesheet class: bkgnd1 */
    59         -
    60         -/* A red border and background.  Use for releases in the timeline.
    61         -*/
    62         -#define BORDER2       "#ec9898"      /* Stylesheet class: border2 */
    63         -#define BG2           "#f7c0c0"      /* Stylesheet class: bkgnd2 */
    64         -
    65         -/* A gray background.  Used for column headers in the Wiki Table of Contents
    66         -** and to highlight ticket properties.
    67         -*/
    68         -#define BG3           "#d0d0d0"      /* Stylesheet class: bkgnd3 */
    69         -
    70         -/* A light-gray background.  Used for title bar, menus, and rlog alternation
    71         -*/
    72         -#define BG4           "#f0f0f0"      /* Stylesheet class: bkgnd4 */
    73         -
    74         -/* A deeper gray background.  Used for branches
    75         -*/
    76         -#define BG5           "#dddddd"      /* Stylesheet class: bkgnd5 */
    77         -
    78         -/* Default HTML page header */
    79         -#define HEADER "<html>\n" \
    80         -               "<head>\n" \
    81         -               "<link rel=\"alternate\" type=\"application/rss+xml\"\n" \
    82         -               "   title=\"%N Timeline Feed\" href=\"%B/timeline.rss\">\n" \
    83         -               "<title>%N: %T</title>\n</head>\n" \
    84         -               "<body bgcolor=\"white\">"
    85         -
    86         -/* Default HTML page footer */
    87         -#define FOOTER "<div id=\"footer\"><small><small>\n" \
    88         -               "<a href=\"about\">Fossil version %V</a>\n" \
    89         -               "</small></small></div>\n" \
    90         -               "</body></html>\n"
    91         -
    92     98   /* In the timeline, check-in messages are truncated at the first space
    93     99   ** that is more than MX_CKIN_MSG from the beginning, or at the first
    94    100   ** paragraph break that is more than MN_CKIN_MSG from the beginning.
    95    101   */
    96    102   #define MN_CKIN_MSG   100
    97    103   #define MX_CKIN_MSG   300
          104  +
          105  +/*
          106  +** The following macros are used to cast pointers to integers and
          107  +** integers to pointers.  The way you do this varies from one compiler
          108  +** to the next, so we have developed the following set of #if statements
          109  +** to generate appropriate macros for a wide range of compilers.
          110  +**
          111  +** The correct "ANSI" way to do this is to use the intptr_t type. 
          112  +** Unfortunately, that typedef is not available on all compilers, or
          113  +** if it is available, it requires an #include of specific headers
          114  +** that vary from one machine to the next.
          115  +*/
          116  +#if defined(__PTRDIFF_TYPE__)  /* This case should work for GCC */
          117  +# define FOSSIL_INT_TO_PTR(X)  ((void*)(__PTRDIFF_TYPE__)(X))
          118  +# define FOSSIL_PTR_TO_INT(X)  ((int)(__PTRDIFF_TYPE__)(X))
          119  +#elif !defined(__GNUC__)       /* Works for compilers other than LLVM */
          120  +# define FOSSIL_INT_TO_PTR(X)  ((void*)&((char*)0)[X])
          121  +# define FOSSIL_PTR_TO_INT(X)  ((int)(((char*)X)-(char*)0))
          122  +#else                          /* Generates a warning - but it always works */
          123  +# define FOSSIL_INT_TO_PTR(X)  ((void*)(X))
          124  +# define FOSSIL_PTR_TO_INT(X)  ((int)(X))
          125  +#endif
          126  +
    98    127   
    99    128   /* Unset the following to disable internationalization code. */
   100    129   #ifndef FOSSIL_I18N
   101    130   # define FOSSIL_I18N 1
   102    131   #endif
   103    132   
   104    133   #if FOSSIL_I18N
................................................................................
   105    134   # include <locale.h>
   106    135   # include <langinfo.h>
   107    136   #endif
   108    137   #ifndef CODESET
   109    138   # undef FOSSIL_I18N
   110    139   # define FOSSIL_I18N 0
   111    140   #endif
          141  +
          142  +#endif /* _RC_COMPILE_ */

Changes to src/configure.c.

    72     72     { "css",                    CONFIGSET_SKIN },
    73     73     { "header",                 CONFIGSET_SKIN },
    74     74     { "footer",                 CONFIGSET_SKIN },
    75     75     { "logo-mimetype",          CONFIGSET_SKIN },
    76     76     { "logo-image",             CONFIGSET_SKIN },
    77     77     { "project-name",           CONFIGSET_PROJ },
    78     78     { "project-description",    CONFIGSET_PROJ },
           79  +  { "manifest",               CONFIGSET_PROJ },
    79     80     { "index-page",             CONFIGSET_SKIN },
    80     81     { "timeline-block-markup",  CONFIGSET_SKIN },
    81     82     { "timeline-max-comment",   CONFIGSET_SKIN },
    82     83     { "ticket-table",           CONFIGSET_TKT  },
    83     84     { "ticket-common",          CONFIGSET_TKT  },
    84     85     { "ticket-newpage",         CONFIGSET_TKT  },
    85     86     { "ticket-viewpage",        CONFIGSET_TKT  },
................................................................................
   452    453         zPw = 0;
   453    454         g.dontKeepUrl = 1;
   454    455       }else{
   455    456         zServer = db_get("last-sync-url", 0);
   456    457         if( zServer==0 ){
   457    458           fossil_fatal("no server specified");
   458    459         }
   459         -      zPw = db_get("last-sync-pw", 0);
          460  +      zPw = unobscure(db_get("last-sync-pw", 0));
   460    461       }
   461    462       url_parse(zServer);
   462    463       if( g.urlPasswd==0 && zPw ) g.urlPasswd = mprintf("%s", zPw);
   463    464       user_select();
          465  +    url_enable_proxy("via proxy: ");
   464    466       if( strncmp(zMethod, "push", n)==0 ){
   465    467         client_sync(0,0,0,0,mask);
   466    468       }else{
   467    469         client_sync(0,0,0,mask,0);
   468    470       }
   469    471     }else
   470    472     if( strncmp(zMethod, "reset", n)==0 ){

Changes to src/content.c.

    17     17   **
    18     18   ** Procedures store and retrieve records from the repository
    19     19   */
    20     20   #include "config.h"
    21     21   #include "content.h"
    22     22   #include <assert.h>
    23     23   
    24         -/*
    25         -** Macros for debugging
    26         -*/
    27         -#if 0
    28         -# define CONTENT_TRACE(X)  printf X;
    29         -#else
    30         -# define CONTENT_TRACE(X)
    31         -#endif
    32         -
    33     24   /*
    34     25   ** The artifact retrival cache
    35     26   */
    36         -#define MX_CACHE_CNT  50    /* Maximum number of positive cache entries */
    37         -#define EXPELL_INTERVAL 5   /* How often to expell from a full cache */
    38     27   static struct {
    39         -  int n;               /* Current number of positive cache entries */
           28  +  i64 szTotal;         /* Total size of all entries in the cache */
           29  +  int n;               /* Current number of eache entries */
           30  +  int nAlloc;          /* Number of slots allocated in a[] */
    40     31     int nextAge;         /* Age counter for implementing LRU */
    41     32     int skipCnt;         /* Used to limit entries expelled from cache */
    42         -  struct {             /* One instance of this for each cache entry */
           33  +  struct cacheLine {   /* One instance of this for each cache entry */
    43     34       int rid;                  /* Artifact id */
    44     35       int age;                  /* Age.  Newer is larger */
    45     36       Blob content;             /* Content of the artifact */
    46         -  } a[MX_CACHE_CNT];   /* The positive cache */
           37  +  } *a;                /* The positive cache */
           38  +  Bag inCache;         /* Set of artifacts currently in cache */
    47     39   
    48     40     /*
    49     41     ** The missing artifact cache.
    50     42     **
    51     43     ** Artifacts whose record ID are in missingCache cannot be retrieved
    52     44     ** either because they are phantoms or because they are a delta that
    53     45     ** depends on a phantom.  Artifacts whose content we are certain is
................................................................................
    54     46     ** available are in availableCache.  If an artifact is in neither cache
    55     47     ** then its current availablity is unknown.
    56     48     */
    57     49     Bag missing;         /* Cache of artifacts that are incomplete */
    58     50     Bag available;       /* Cache of artifacts that are complete */
    59     51   } contentCache;
    60     52   
           53  +/*
           54  +** Remove the oldest element from the content cache
           55  +*/
           56  +static void content_cache_expire_oldest(void){
           57  +  int i;
           58  +  int mnAge = contentCache.nextAge;
           59  +  int mn = -1;
           60  +  for(i=0; i<contentCache.n; i++){
           61  +    if( contentCache.a[i].age<mnAge ){
           62  +      mnAge = contentCache.a[i].age;
           63  +      mn = i;
           64  +    }
           65  +  }
           66  +  if( mn>=0 ){
           67  +    bag_remove(&contentCache.inCache, contentCache.a[mn].rid);
           68  +    contentCache.szTotal -= blob_size(&contentCache.a[mn].content);
           69  +    blob_reset(&contentCache.a[mn].content);
           70  +    contentCache.n--;
           71  +    contentCache.a[mn] = contentCache.a[contentCache.n];
           72  +  }
           73  +}
           74  +
           75  +/*
           76  +** Add an entry to the content cache
           77  +*/
           78  +void content_cache_insert(int rid, Blob *pBlob){
           79  +  struct cacheLine *p;
           80  +  if( contentCache.n>500 || contentCache.szTotal>50000000 ){
           81  +    content_cache_expire_oldest();
           82  +  }
           83  +  if( contentCache.n>=contentCache.nAlloc ){
           84  +    contentCache.nAlloc = contentCache.nAlloc*2 + 10;
           85  +    contentCache.a = fossil_realloc(contentCache.a,
           86  +                             contentCache.nAlloc*sizeof(contentCache.a[0]));
           87  +  }
           88  +  p = &contentCache.a[contentCache.n++];
           89  +  p->rid = rid;
           90  +  p->age = contentCache.nextAge++;
           91  +  contentCache.szTotal += blob_size(pBlob);
           92  +  p->content = *pBlob;
           93  +  blob_zero(pBlob);
           94  +  bag_insert(&contentCache.inCache, rid);
           95  +}
    61     96   
    62     97   /*
    63     98   ** Clear the content cache.
    64     99   */
    65    100   void content_clear_cache(void){
    66    101     int i;
    67    102     for(i=0; i<contentCache.n; i++){
    68    103       blob_reset(&contentCache.a[i].content);
    69    104     }
    70    105     bag_clear(&contentCache.missing);
    71    106     bag_clear(&contentCache.available);
          107  +  bag_clear(&contentCache.inCache);
    72    108     contentCache.n = 0;
          109  +  contentCache.szTotal = 0;
    73    110   }
    74    111   
    75    112   /*
    76    113   ** Return the srcid associated with rid.  Or return 0 if rid is 
    77    114   ** original content and not a delta.
    78    115   */
    79    116   static int findSrcid(int rid){
................................................................................
    93    130   /*
    94    131   ** Check to see if content is available for artifact "rid".  Return
    95    132   ** true if it is.  Return false if rid is a phantom or depends on
    96    133   ** a phantom.
    97    134   */
    98    135   int content_is_available(int rid){
    99    136     int srcid;
   100         -  if( bag_find(&contentCache.missing, rid) ){
   101         -    return 0;
   102         -  }
   103         -  if( bag_find(&contentCache.available, rid) ){
   104         -    return 1;
   105         -  }
   106         -  if( db_int(-1, "SELECT size FROM blob WHERE rid=%d", rid)<0 ){
   107         -    bag_insert(&contentCache.missing, rid);
   108         -    return 0;
   109         -  }
   110         -  srcid = findSrcid(rid);
   111         -  if( srcid==0 ){
   112         -    bag_insert(&contentCache.available, rid);
   113         -    return 1;
   114         -  }
   115         -  if( content_is_available(srcid) ){
   116         -    bag_insert(&contentCache.available, rid);
   117         -    return 1;
   118         -  }else{
   119         -    bag_insert(&contentCache.missing, rid);
   120         -    return 0;
   121         -  }
          137  +  int depth = 0;  /* Limit to recursion depth */
          138  +  while( depth++ < 10000000 ){  
          139  +    if( bag_find(&contentCache.missing, rid) ){
          140  +      return 0;
          141  +    }
          142  +    if( bag_find(&contentCache.available, rid) ){
          143  +      return 1;
          144  +    }
          145  +    if( db_int(-1, "SELECT size FROM blob WHERE rid=%d", rid)<0 ){
          146  +      bag_insert(&contentCache.missing, rid);
          147  +      return 0;
          148  +    }
          149  +    srcid = findSrcid(rid);
          150  +    if( srcid==0 ){
          151  +      bag_insert(&contentCache.available, rid);
          152  +      return 1;
          153  +    }
          154  +    rid = srcid;
          155  +  }
          156  +  fossil_panic("delta-loop in repository");
          157  +  return 0;
   122    158   }
   123    159   
   124    160   /*
   125    161   ** Mark artifact rid as being available now.  Update the cache to
   126    162   ** show that everything that was formerly unavailable because rid
   127    163   ** was missing is now available.
   128    164   */
................................................................................
   161    197       blob_uncompress(pBlob, pBlob);
   162    198       rc = 1;
   163    199     }
   164    200     db_reset(&q);
   165    201     return rc;
   166    202   }
   167    203   
   168         -
   169    204   /*
   170    205   ** Extract the content for ID rid and put it into the
   171    206   ** uninitialized blob.  Return 1 on success.  If the record
   172    207   ** is a phantom, zero pBlob and return 0.
   173    208   */
   174    209   int content_get(int rid, Blob *pBlob){
   175         -  Blob src;
   176         -  int srcid;
   177         -  int rc = 0;
          210  +  int rc;
   178    211     int i;
   179         -  static Bag inProcess;
          212  +  int nextRid;
   180    213   
   181    214     assert( g.repositoryOpen );
   182    215     blob_zero(pBlob);
   183    216     if( rid==0 ) return 0;
   184    217   
   185    218     /* Early out if we know the content is not available */
   186    219     if( bag_find(&contentCache.missing, rid) ){
   187         -    CONTENT_TRACE(("%*smiss from cache: %d\n",
   188         -                    bag_count(&inProcess), "", rid))
   189    220       return 0;
   190    221     }
   191    222   
   192    223     /* Look for the artifact in the cache first */
   193         -  for(i=0; i<contentCache.n; i++){
   194         -    if( contentCache.a[i].rid==rid ){
   195         -      *pBlob = contentCache.a[i].content;
   196         -      blob_zero(&contentCache.a[i].content);
   197         -      contentCache.n--;
   198         -      if( i<contentCache.n ){
   199         -        contentCache.a[i] = contentCache.a[contentCache.n];
          224  +  if( bag_find(&contentCache.inCache, rid) ){
          225  +    for(i=0; i<contentCache.n; i++){
          226  +      if( contentCache.a[i].rid==rid ){
          227  +        blob_copy(pBlob, &contentCache.a[i].content);
          228  +        contentCache.a[i].age = contentCache.nextAge++;
          229  +        return 1;
          230  +      }
          231  +    }
          232  +  }
          233  +
          234  +  nextRid = findSrcid(rid);
          235  +  if( nextRid==0 ){
          236  +    rc = content_of_blob(rid, pBlob);
          237  +  }else{
          238  +    int n = 1;
          239  +    int nAlloc = 10;
          240  +    int *a = 0;
          241  +    int mx;
          242  +    Blob delta, next;
          243  +
          244  +    a = fossil_malloc( sizeof(a[0])*nAlloc );
          245  +    a[0] = rid;
          246  +    a[1] = nextRid;
          247  +    n = 1;
          248  +    while( !bag_find(&contentCache.inCache, nextRid)
          249  +        && (nextRid = findSrcid(nextRid))>0 ){
          250  +      n++;
          251  +      if( n>=nAlloc ){
          252  +        nAlloc = nAlloc*2 + 10;
          253  +        a = fossil_realloc(a, nAlloc*sizeof(a[0]));
   200    254         }
   201         -      CONTENT_TRACE(("%*scache: %d\n", 
   202         -                    bag_count(&inProcess), "", rid))
   203         -      return 1;
          255  +      a[n] = nextRid;
   204    256       }
   205         -  }
   206         -
   207         -  /* See if we need to apply a delta to find this artifact */
   208         -  srcid = findSrcid(rid);
   209         -  CONTENT_TRACE(("%*ssearching for %d.  Need %d.\n",
   210         -                 bag_count(&inProcess), "", rid, srcid))
   211         -
   212         -
   213         -  if( srcid ){
   214         -    /* Yes, a delta is required */
   215         -    if( bag_find(&inProcess, srcid) ){
   216         -      db_multi_exec(
   217         -        "UPDATE blob SET content=NULL, size=-1 WHERE rid=%d;"
   218         -        "DELETE FROM delta WHERE rid=%d;"
   219         -        "INSERT OR IGNORE INTO phantom VALUES(%d);",
   220         -        srcid, srcid, srcid
   221         -      );
   222         -      blob_zero(pBlob);
   223         -      return 0;
   224         -    }
   225         -    bag_insert(&inProcess, srcid);
   226         -
   227         -    if( content_get(srcid, &src) ){
   228         -      Blob delta;
   229         -      if( content_of_blob(rid, &delta) ){
   230         -        blob_init(pBlob,0,0);
   231         -        blob_delta_apply(&src, &delta, pBlob);
          257  +    mx = n;
          258  +    rc = content_get(a[n], pBlob);
          259  +    n--;
          260  +    while( rc && n>=0 ){
          261  +      rc = content_of_blob(a[n], &delta);
          262  +      if( rc ){
          263  +        blob_delta_apply(pBlob, &delta, &next);
   232    264           blob_reset(&delta);
   233         -        rc = 1;
   234         -      }
   235         -
   236         -      /* Save the srcid artifact in the cache */
   237         -      if( contentCache.n<MX_CACHE_CNT ){
   238         -        i = contentCache.n++;
   239         -      }else if( ((contentCache.skipCnt++)%EXPELL_INTERVAL)!=0 ){
   240         -        i = -1;
   241         -      }else{
   242         -        int j, best;
   243         -        best = contentCache.nextAge+1;
   244         -        i = -1;
   245         -        for(j=0; j<contentCache.n; j++){
   246         -          if( contentCache.a[j].age<best ){
   247         -            i = j;
   248         -            best = contentCache.a[j].age;
   249         -          }
          265  +        if( (mx-n)%8==0 ){
          266  +          content_cache_insert(a[n+1], pBlob);
          267  +        }else{
          268  +          blob_reset(pBlob);
   250    269           }
   251         -        CONTENT_TRACE(("%*sexpell %d from cache\n",
   252         -                       bag_count(&inProcess), "", contentCache.a[i].rid))
   253         -        blob_reset(&contentCache.a[i].content);
          270  +        *pBlob = next;
   254    271         }
   255         -      if( i>=0 ){
   256         -        contentCache.a[i].content = src;
   257         -        contentCache.a[i].age = contentCache.nextAge++;
   258         -        contentCache.a[i].rid = srcid;
   259         -        CONTENT_TRACE(("%*sadd %d to cache\n",
   260         -                       bag_count(&inProcess), "", srcid))
   261         -      }else{
   262         -        blob_reset(&src);
   263         -      }
          272  +      n--;
   264    273       }
   265         -    bag_remove(&inProcess, srcid);
   266         -  }else{
   267         -    /* No delta required.  Read content directly from the database */
   268         -    if( content_of_blob(rid, pBlob) ){
   269         -      rc = 1;
   270         -    }
          274  +    free(a);
          275  +    if( !rc ) blob_reset(pBlob);
   271    276     }
   272    277     if( rc==0 ){
   273    278       bag_insert(&contentCache.missing, rid);
   274    279     }else{
   275    280       bag_insert(&contentCache.available, rid);
   276    281     }
   277    282     return rc;
   278    283   }
   279    284   
   280    285   /*
   281         -** COMMAND:  artifact
          286  +** COMMAND: artifact
   282    287   **
   283         -** Usage: %fossil artifact ARTIFACT-ID  ?OUTPUT-FILENAME?
          288  +** Usage: %fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS?
   284    289   **
   285    290   ** Extract an artifact by its SHA1 hash and write the results on
   286    291   ** standard output, or if the optional 4th argument is given, in
   287    292   ** the named output file.
          293  +**
          294  +** Options:
          295  +**
          296  +**    -R|--repository FILE       Extract artifacts from repository FILE
   288    297   */
   289    298   void artifact_cmd(void){
   290    299     int rid;
   291    300     Blob content;
   292    301     const char *zFile;
   293         -  if( g.argc!=4 && g.argc!=3 ) usage("RECORDID ?FILENAME?");
          302  +  db_find_and_open_repository(1);
          303  +  if( g.argc!=4 && g.argc!=3 ) usage("ARTIFACT-ID ?FILENAME? ?OPTIONS?");
   294    304     zFile = g.argc==4 ? g.argv[3] : "-";
   295         -  db_must_be_within_tree();
   296    305     rid = name_to_rid(g.argv[2]);
   297    306     content_get(rid, &content);
   298    307     blob_write_to_file(&content, zFile);
   299    308   }
   300    309   
   301    310   /*
   302    311   ** COMMAND:  test-content-rawget
................................................................................
   314    323     rid = name_to_rid(g.argv[2]);
   315    324     blob_zero(&content);
   316    325     db_blob(&content, "SELECT content FROM blob WHERE rid=%d", rid);
   317    326     blob_uncompress(&content, &content);
   318    327     blob_write_to_file(&content, zFile);
   319    328   }
   320    329   
          330  +/*
          331  +** The following flag is set to disable the automatic calls to
          332  +** manifest_crosslink() when a record is dephantomized.  This
          333  +** flag can be set (for example) when doing a clone when we know
          334  +** that rebuild will be run over all records at the conclusion
          335  +** of the operation.
          336  +*/
          337  +static int ignoreDephantomizations = 0;
          338  +
   321    339   /*
   322    340   ** When a record is converted from a phantom to a real record,
   323    341   ** if that record has other records that are derived by delta,
   324    342   ** then call manifest_crosslink() on those other records.
          343  +**
          344  +** If the formerly phantom record or any of the other records
          345  +** derived by delta from the former phantom are a baseline manifest,
          346  +** then also invoke manifest_crosslink() on the delta-manifests
          347  +** associated with that baseline.
          348  +**
          349  +** Tail recursion is used to minimize stack depth.
   325    350   */
   326    351   void after_dephantomize(int rid, int linkFlag){
   327    352     Stmt q;
   328         -  int prevTid = 0;
   329         -
   330         -  /* The prevTid variable is used to delay invoking this routine
   331         -  ** recursively, if possible, until after the query has finalized,
   332         -  ** in order to avoid having an excessive number of prepared statements.
   333         -  ** This is most effective in the common case where the query returns 
   334         -  ** just one row.
   335         -  */
   336         -  db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
   337         -  while( db_step(&q)==SQLITE_ROW ){
   338         -    int tid = db_column_int(&q, 0);
   339         -    if( prevTid ) after_dephantomize(prevTid, 1);
   340         -    prevTid = tid;
   341         -  }
   342         -  db_finalize(&q);
   343         -  if( prevTid ) after_dephantomize(prevTid, 1);
   344         -  if( linkFlag ){
   345         -    Blob content;
   346         -    content_get(rid, &content);
   347         -    manifest_crosslink(rid, &content);
   348         -    blob_reset(&content);
   349         -  }
          353  +  int nChildAlloc = 0;
          354  +  int *aChild = 0;
          355  +  Blob content;
          356  +
          357  +  if( ignoreDephantomizations ) return;
          358  +  while( rid ){
          359  +    int nChildUsed = 0;
          360  +    int i;
          361  +
          362  +    /* Parse the object rid itself */
          363  +    if( linkFlag ){
          364  +      content_get(rid, &content);
          365  +      manifest_crosslink(rid, &content);
          366  +      blob_reset(&content);
          367  +    }
          368  +
          369  +    /* Parse all delta-manifests that depend on baseline-manifest rid */
          370  +    db_prepare(&q, "SELECT rid FROM orphan WHERE baseline=%d", rid);
          371  +    while( db_step(&q)==SQLITE_ROW ){
          372  +      int child = db_column_int(&q, 0);
          373  +      if( nChildUsed>=nChildAlloc ){
          374  +        nChildAlloc = nChildAlloc*2 + 10;
          375  +        aChild = fossil_realloc(aChild, nChildAlloc*sizeof(aChild));
          376  +      }
          377  +      aChild[nChildUsed++] = child;
          378  +    }
          379  +    db_finalize(&q);
          380  +    for(i=0; i<nChildUsed; i++){
          381  +      content_get(aChild[i], &content);
          382  +      manifest_crosslink(aChild[i], &content);
          383  +      blob_reset(&content);
          384  +    }
          385  +    if( nChildUsed ){
          386  +      db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
          387  +    }
          388  +
          389  +    /* Recursively dephantomize all artifacts that are derived by
          390  +    ** delta from artifact rid */
          391  +    nChildUsed = 0;
          392  +    db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
          393  +    while( db_step(&q)==SQLITE_ROW ){
          394  +      int child = db_column_int(&q, 0);
          395  +      if( nChildUsed>=nChildAlloc ){
          396  +        nChildAlloc = nChildAlloc*2 + 10;
          397  +        aChild = fossil_realloc(aChild, nChildAlloc*sizeof(aChild));
          398  +      }
          399  +      aChild[nChildUsed++] = child;
          400  +    }
          401  +    db_finalize(&q);
          402  +    for(i=1; i<nChildUsed; i++){
          403  +      after_dephantomize(aChild[i], 1);
          404  +    }
          405  +
          406  +    /* Tail recursion for the common case where only a single artifact
          407  +    ** is derived by delta from rid... */
          408  +    rid = nChildUsed>0 ? aChild[0] : 0;
          409  +    linkFlag = 1;
          410  +  }
          411  +  free(aChild);
          412  +}
          413  +
          414  +/*
          415  +** Turn dephantomization processing on or off.
          416  +*/
          417  +void content_enable_dephantomize(int onoff){
          418  +  ignoreDephantomizations = !onoff;
   350    419   }
   351    420   
   352    421   /*
   353    422   ** Write content into the database.  Return the record ID.  If the
   354    423   ** content is already in the database, just return the record ID.
   355    424   **
   356    425   ** If srcId is specified, then pBlob is delta content from

Changes to src/db.c.

    25     25   **    (2)  The "repository" database
    26     26   **
    27     27   **    (3)  A local checkout database named "_FOSSIL_" or ".fos"
    28     28   **         and located at the root of the local copy of the source tree.
    29     29   **
    30     30   */
    31     31   #include "config.h"
           32  +#if ! defined(_WIN32)
           33  +#  include <pwd.h>
           34  +#endif
    32     35   #include <sqlite3.h>
    33     36   #include <sys/types.h>
    34     37   #include <sys/stat.h>
    35     38   #include <unistd.h>
    36     39   #include "db.h"
    37     40   
    38     41   #if INTERFACE
................................................................................
   132    135   void db_force_rollback(void){
   133    136     static int busy = 0;
   134    137     if( busy || g.db==0 ) return;
   135    138     busy = 1;
   136    139     undo_rollback();
   137    140     if( nBegin ){
   138    141       sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0);
          142  +    nBegin = 0;
   139    143       if( isNewRepo ){
   140    144         db_close();
   141    145         unlink(g.zRepositoryName);
   142    146       }
   143    147     }
   144         -  nBegin = 0;
   145    148     busy = 0;
   146    149   }
   147    150   
   148    151   /*
   149    152   ** Install a commit hook.  Hooks are installed in sequence order.
   150    153   ** It is an error to install the same commit hook more than once.
   151    154   **
................................................................................
   532    535     }else{
   533    536       z = 0;
   534    537     }
   535    538     db_finalize(&s);
   536    539     return z;
   537    540   }
   538    541   
   539         -#ifdef __MINGW32__
          542  +#if defined(_WIN32)
   540    543   extern char *sqlite3_win32_mbcs_to_utf8(const char*);
   541    544   #endif
   542    545   
   543    546   /*
   544    547   ** Initialize a new database file with the given schema.  If anything
   545    548   ** goes wrong, call db_err() to exit.
   546    549   */
................................................................................
   550    553     ...                      /* Additional SQL to run.  Terminate with NULL. */
   551    554   ){
   552    555     sqlite3 *db;
   553    556     int rc;
   554    557     const char *zSql;
   555    558     va_list ap;
   556    559   
   557         -#ifdef __MINGW32__
          560  +#if defined(_WIN32)
   558    561     zFileName = sqlite3_win32_mbcs_to_utf8(zFileName);
   559    562   #endif
   560    563     rc = sqlite3_open(zFileName, &db);
   561    564     if( rc!=SQLITE_OK ){
   562    565       db_err(sqlite3_errmsg(db));
   563    566     }
   564    567     sqlite3_busy_timeout(db, 5000);
................................................................................
   585    588   */
   586    589   static sqlite3 *openDatabase(const char *zDbName){
   587    590     int rc;
   588    591     const char *zVfs;
   589    592     sqlite3 *db;
   590    593   
   591    594     zVfs = getenv("FOSSIL_VFS");
   592         -#ifdef __MINGW32__
          595  +#if defined(_WIN32)
   593    596     zDbName = sqlite3_win32_mbcs_to_utf8(zDbName);
   594    597   #endif
   595    598     rc = sqlite3_open_v2(
   596    599          zDbName, &db,
   597    600          SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
   598    601          zVfs
   599    602     );
................................................................................
   613    616   */
   614    617   void db_open_or_attach(const char *zDbName, const char *zLabel){
   615    618     if( !g.db ){
   616    619       g.db = openDatabase(zDbName);
   617    620       g.zRepoDb = "main";
   618    621       db_connection_init();
   619    622     }else{
   620         -#ifdef __MINGW32__
          623  +#if defined(_WIN32)
   621    624       zDbName = sqlite3_win32_mbcs_to_utf8(zDbName);
   622    625   #endif
   623    626       db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
   624    627       g.zRepoDb = mprintf("%s", zLabel);
   625    628     }
   626    629   }
   627    630   
................................................................................
   637    640   ** connection so that we can join between the various databases.  In that
   638    641   ** case, invoke this routine with useAttach as 1.
   639    642   */
   640    643   void db_open_config(int useAttach){
   641    644     char *zDbName;
   642    645     const char *zHome;
   643    646     if( g.configOpen ) return;
   644         -#ifdef __MINGW32__
          647  +#if defined(_WIN32)
   645    648     zHome = getenv("LOCALAPPDATA");
   646    649     if( zHome==0 ){
   647    650       zHome = getenv("APPDATA");
   648    651       if( zHome==0 ){
   649    652         zHome = getenv("HOMEPATH");
   650    653       }
   651    654     }
................................................................................
   659    662       fossil_fatal("cannot locate home directory - "
   660    663                    "please set the HOME environment variable");
   661    664     }
   662    665   #endif
   663    666     if( file_isdir(zHome)!=1 ){
   664    667       fossil_fatal("invalid home directory: %s", zHome);
   665    668     }
   666         -#ifndef __MINGW32__
          669  +#ifndef _WIN32
   667    670     if( access(zHome, W_OK) ){
   668    671       fossil_fatal("home directory %s must be writeable", zHome);
   669    672     }
   670    673   #endif
   671    674     g.zHome = mprintf("%/", zHome);
   672         -#ifdef __MINGW32__
          675  +#if defined(_WIN32)
   673    676     /* . filenames give some window systems problems and many apps problems */
   674    677     zDbName = mprintf("%//_fossil", zHome);
   675    678   #else
   676    679     zDbName = mprintf("%s/.fossil", zHome);
   677    680   #endif
   678    681     if( file_size(zDbName)<1024*3 ){
   679    682       db_init_database(zDbName, zConfigSchema, (char*)0);
................................................................................
   892    895     db_open_repository(0);
   893    896   }
   894    897   
   895    898   /*
   896    899   ** Close the database connection.
   897    900   */
   898    901   void db_close(void){
          902  +  sqlite3_stmt *pStmt;
   899    903     if( g.db==0 ) return;
   900    904     while( pAllStmt ){
   901    905       db_finalize(pAllStmt);
   902    906     }
   903    907     db_end_transaction(1);
          908  +  pStmt = 0;
          909  +  while( (pStmt = sqlite3_next_stmt(g.db, pStmt))!=0 ){
          910  +    fossil_warning("unfinalized SQL statement: [%s]", sqlite3_sql(pStmt));
          911  +  }
   904    912     g.repositoryOpen = 0;
   905    913     g.localOpen = 0;
   906    914     g.configOpen = 0;
          915  +  sqlite3_wal_checkpoint(g.db, 0);
   907    916     sqlite3_close(g.db);
   908    917     g.db = 0;
          918  +  if( g.dbConfig ){
          919  +    sqlite3_close(g.dbConfig);
          920  +    g.dbConfig = 0;
          921  +  }
   909    922   }
   910    923   
   911    924   
   912    925   /*
   913    926   ** Create a new empty repository database with the given name.
   914    927   **
   915    928   ** Only the schema is initialized.  The required VAR tables entries
................................................................................
   932    945   void db_create_default_users(int setupUserOnly, const char *zDefaultUser){
   933    946     const char *zUser;
   934    947     zUser = db_get("default-user", 0);
   935    948     if( zUser==0 ){
   936    949       zUser = zDefaultUser;
   937    950     }
   938    951     if( zUser==0 ){
   939         -#ifdef __MINGW32__
          952  +#if defined(_WIN32)
   940    953       zUser = getenv("USERNAME");
   941    954   #else
   942    955       zUser = getenv("USER");
   943    956   #endif
   944    957     }
   945    958     if( zUser==0 ){
   946    959       zUser = "root";
................................................................................
   998   1011     db_create_default_users(0, zDefaultUser);
   999   1012     user_select();
  1000   1013   
  1001   1014     if( zInitialDate ){
  1002   1015       int rid;
  1003   1016       blob_zero(&manifest);
  1004   1017       blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n");
  1005         -    zDate = db_text(0, "SELECT datetime(%Q)", zInitialDate);
  1006         -    zDate[10]='T';
         1018  +    zDate = date_in_standard_format(zInitialDate);
  1007   1019       blob_appendf(&manifest, "D %s\n", zDate);
  1008   1020       blob_appendf(&manifest, "P\n");
  1009   1021       md5sum_init();
  1010   1022       blob_appendf(&manifest, "R %s\n", md5sum_finish(0));
  1011   1023       blob_appendf(&manifest, "T *branch * trunk\n");
  1012   1024       blob_appendf(&manifest, "T *sym-trunk *\n");
  1013   1025       blob_appendf(&manifest, "U %F\n", g.zLogin);
................................................................................
  1251   1263   ** If g.useAttach that means the ~/.fossil database was opened with
  1252   1264   ** the useAttach flag set to 1.  In that case no connection swap is required
  1253   1265   ** so this routine is a no-op.
  1254   1266   */
  1255   1267   void db_swap_connections(void){
  1256   1268     if( !g.useAttach ){
  1257   1269       sqlite3 *dbTemp = g.db;
  1258         -    assert( g.dbConfig!=0 );
  1259   1270       g.db = g.dbConfig;
  1260   1271       g.dbConfig = dbTemp;
  1261   1272     }
  1262   1273   }
  1263   1274   
  1264   1275   /*
  1265   1276   ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
................................................................................
  1372   1383   }
  1373   1384   void db_lset_int(const char *zName, int value){
  1374   1385     db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
  1375   1386   }
  1376   1387   
  1377   1388   /*
  1378   1389   ** Record the name of a local repository in the global_config() database.
  1379         -** The repostiroy filename %s is recorded as an entry with a "name" field
         1390  +** The repository filename %s is recorded as an entry with a "name" field
  1380   1391   ** of the following form:
  1381   1392   **
  1382   1393   **       repo:%s
  1383   1394   **
  1384   1395   ** The value field is set to 1.
  1385   1396   */
  1386   1397   void db_record_repository_filename(const char *zName){
................................................................................
  1479   1490     }else{
  1480   1491       printf("%-20s\n", zName);
  1481   1492     }
  1482   1493     db_finalize(&q);
  1483   1494   }
  1484   1495   
  1485   1496   
         1497  +/*
         1498  +** define all settings, which can be controlled via the set/unset
         1499  +** command. var is the name of the internal configuration name for db_(un)set.
         1500  +** If var is 0, the settings name is used.
         1501  +** width is the length for the edit field on the behavior page, 0
         1502  +** is used for on/off checkboxes.
         1503  +** The behaviour page doesn't use a special layout. It lists all
         1504  +** set-commands and displays the 'set'-help as info.
         1505  +*/
         1506  +#if INTERFACE
         1507  +struct stControlSettings {
         1508  +  char const *name;     /* Name of the setting */
         1509  +  char const *var;      /* Internal variable name used by db_set() */
         1510  +  int width;            /* Width of display.  0 for boolean values */
         1511  +  char const *def;      /* Default value */
         1512  +};
         1513  +#endif /* INTERFACE */
         1514  +struct stControlSettings const ctrlSettings[] = {
         1515  +  { "auto-captcha",  "autocaptcha",    0, "on"                  },
         1516  +  { "auto-shun",     0,                0, "on"                  },
         1517  +  { "autosync",      0,                0, "on"                  },
         1518  +  { "binary-glob",   0,               32, ""                    },
         1519  +  { "clearsign",     0,                0, "off"                 },
         1520  +  { "diff-command",  0,               16, ""                    },
         1521  +  { "dont-push",     0,                0, "off"                 },
         1522  +  { "editor",        0,               16, ""                    },
         1523  +  { "gdiff-command", 0,               16, "gdiff"               },
         1524  +  { "ignore-glob",   0,               40, ""                    },
         1525  +  { "http-port",     0,               16, "8080"                },
         1526  +  { "localauth",     0,                0, "off"                 },
         1527  +  { "manifest",      0,                0, "off"                 },
         1528  +  { "mtime-changes", 0,                0, "on"                  },
         1529  +  { "pgp-command",   0,               32, "gpg --clearsign -o " },
         1530  +  { "proxy",         0,               32, "off"                 },
         1531  +  { "repo-cksum",    0,                0, "on"                  },
         1532  +  { "ssh-command",   0,               32, ""                    },
         1533  +  { "web-browser",   0,               32, ""                    },
         1534  +  { 0,0,0,0 }
         1535  +};
         1536  +
  1486   1537   /*
  1487   1538   ** COMMAND: settings
  1488   1539   ** COMMAND: unset
  1489   1540   ** %fossil settings ?PROPERTY? ?VALUE? ?-global?
  1490   1541   ** %fossil unset PROPERTY ?-global?
  1491   1542   **
  1492   1543   ** The "settings" command with no arguments lists all properties and their
................................................................................
  1497   1548   **
  1498   1549   **
  1499   1550   **    auto-captcha     If enabled, the Login page provides a button to
  1500   1551   **                     fill in the captcha password.  Default: on
  1501   1552   **
  1502   1553   **    auto-shun        If enabled, automatically pull the shunning list
  1503   1554   **                     from a server to which the client autosyncs.
         1555  +**                     Default: on
  1504   1556   **
  1505   1557   **    autosync         If enabled, automatically pull prior to commit
  1506   1558   **                     or update and automatically push after commit or
  1507   1559   **                     tag or branch creation.  If the value is "pullonly"
  1508   1560   **                     then only pull operations occur automatically.
         1561  +**                     Default: on
  1509   1562   **
  1510   1563   **    binary-glob      The VALUE is a comma-separated list of GLOB patterns
  1511   1564   **                     that should be treated as binary files for merging
  1512   1565   **                     purposes.  Example:   *.xml
  1513   1566   **
  1514   1567   **    clearsign        When enabled, fossil will attempt to sign all commits
  1515   1568   **                     with gpg.  When disabled (the default), commits will
  1516         -**                     be unsigned.
         1569  +**                     be unsigned.  Default: off
  1517   1570   **
  1518   1571   **    diff-command     External command to run when performing a diff.
  1519   1572   **                     If undefined, the internal text diff will be used.
  1520   1573   **
  1521   1574   **    dont-push        Prevent this repository from pushing from client to
  1522   1575   **                     server.  Useful when setting up a private branch.
  1523   1576   **
................................................................................
  1534   1587   **                     Example:  *.o,*.obj,*.exe
  1535   1588   **
  1536   1589   **    localauth        If enabled, require that HTTP connections from
  1537   1590   **                     127.0.0.1 be authenticated by password.  If
  1538   1591   **                     false, all HTTP requests from localhost have
  1539   1592   **                     unrestricted access to the repository.
  1540   1593   **
         1594  +**    manifest         If enabled, automatically create files "manifest" and
         1595  +**                     "manifest.uuid" in every checkout.  The SQLite and
         1596  +**                     Fossil repositories both require this.  Default: off.
         1597  +**
  1541   1598   **    mtime-changes    Use file modification times (mtimes) to detect when
  1542   1599   **                     files have been modified.  (Default "on".)
  1543   1600   **
  1544   1601   **    pgp-command      Command used to clear-sign manifests at check-in.
  1545   1602   **                     The default is "gpg --clearsign -o ".
  1546   1603   **
  1547   1604   **    proxy            URL of the HTTP proxy.  If undefined or "off" then
  1548   1605   **                     the "http_proxy" environment variable is consulted.
  1549   1606   **                     If the http_proxy environment variable is undefined
  1550   1607   **                     then a direct HTTP connection is used.
         1608  +**
         1609  +**    repo-cksum       Compute checksums over all files in each checkout
         1610  +**                     as a double-check of correctness.  Defaults to "on".
         1611  +**                     Disable on large repositories for a performance
         1612  +**                     improvement.
         1613  +**
         1614  +**    ssh-command      Command used to talk to a remote machine with
         1615  +**                     the "ssh://" protocol.
  1551   1616   **
  1552   1617   **    web-browser      A shell command used to launch your preferred
  1553   1618   **                     web browser when given a URL as an argument.
  1554   1619   **                     Defaults to "start" on windows, "open" on Mac,
  1555   1620   **                     and "firefox" on Unix.
  1556   1621   */
  1557   1622   void setting_cmd(void){
  1558         -  static const char *azName[] = {
  1559         -    "auto-captcha",
  1560         -    "auto-shun",
  1561         -    "autosync",
  1562         -    "binary-glob",
  1563         -    "clearsign",
  1564         -    "diff-command",
  1565         -    "dont-push",
  1566         -    "editor",
  1567         -    "gdiff-command",
  1568         -    "ignore-glob",
  1569         -    "http-port",
  1570         -    "localauth",
  1571         -    "mtime-changes",
  1572         -    "pgp-command",
  1573         -    "proxy",
  1574         -    "web-browser",
  1575         -  };
  1576   1623     int i;
  1577   1624     int globalFlag = find_option("global","g",0)!=0;
  1578   1625     int unsetFlag = g.argv[1][0]=='u';
  1579   1626     db_open_config(1);
  1580   1627     db_find_and_open_repository(0);
  1581   1628     if( !g.repositoryOpen ){
  1582   1629       globalFlag = 1;
  1583   1630     }
  1584   1631     if( unsetFlag && g.argc!=3 ){
  1585   1632       usage("PROPERTY ?-global?");
  1586   1633     }
  1587   1634     if( g.argc==2 ){
  1588         -    for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
  1589         -      print_setting(azName[i]);
         1635  +    for(i=0; ctrlSettings[i].name; i++){
         1636  +      print_setting(ctrlSettings[i].name);
  1590   1637       }
  1591   1638     }else if( g.argc==3 || g.argc==4 ){
  1592   1639       const char *zName = g.argv[2];
         1640  +    int isManifest;
  1593   1641       int n = strlen(zName);
  1594         -    for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
  1595         -      if( strncmp(azName[i], zName, n)==0 ) break;
         1642  +    for(i=0; ctrlSettings[i].name; i++){
         1643  +      if( strncmp(ctrlSettings[i].name, zName, n)==0 ) break;
  1596   1644       }
  1597         -    if( i>=sizeof(azName)/sizeof(azName[0]) ){
         1645  +    if( !ctrlSettings[i].name ){
  1598   1646         fossil_fatal("no such setting: %s", zName);
  1599   1647       }
         1648  +    isManifest = strcmp(ctrlSettings[i].name, "manifest")==0;
         1649  +    if( isManifest && globalFlag ){
         1650  +      fossil_fatal("cannot set 'manifest' globally");
         1651  +    }
  1600   1652       if( unsetFlag ){
  1601         -      db_unset(azName[i], globalFlag);
         1653  +      db_unset(ctrlSettings[i].name, globalFlag);
  1602   1654       }else if( g.argc==4 ){
  1603         -      db_set(azName[i], g.argv[3], globalFlag);
         1655  +      db_set(ctrlSettings[i].name, g.argv[3], globalFlag);
  1604   1656       }else{
  1605         -      print_setting(azName[i]);
         1657  +      isManifest = 0;
         1658  +      print_setting(ctrlSettings[i].name);
         1659  +    }
         1660  +    if( isManifest ){
         1661  +      manifest_to_disk(db_lget_int("checkout", 0));
  1606   1662       }
  1607   1663     }else{
  1608   1664       usage("?PROPERTY? ?VALUE?");
  1609   1665     }
  1610   1666   }
         1667  +
         1668  +/*
         1669  +** The input in a a timespan measured in days.  Return a string which
         1670  +** describes that timespan in units of seconds, minutes, hours, days,
         1671  +** or years, depending on its duration.
         1672  +*/
         1673  +char *db_timespan_name(double rSpan){
         1674  +  if( rSpan<0 ) rSpan = -rSpan;
         1675  +  rSpan *= 24.0*3600.0;  /* Convert units to seconds */
         1676  +  if( rSpan<120.0 ){
         1677  +    return sqlite3_mprintf("%.1f seconds", rSpan);
         1678  +  }
         1679  +  rSpan /= 60.0;         /* Convert units to minutes */
         1680  +  if( rSpan<90.0 ){
         1681  +    return sqlite3_mprintf("%.1f minutes", rSpan);
         1682  +  }
         1683  +  rSpan /= 60.0;         /* Convert units to hours */
         1684  +  if( rSpan<=48.0 ){
         1685  +    return sqlite3_mprintf("%.1f hours", rSpan);
         1686  +  }
         1687  +  rSpan /= 24.0;         /* Convert units to days */
         1688  +  if( rSpan<=365.0 ){
         1689  +    return sqlite3_mprintf("%.1f days", rSpan);
         1690  +  }
         1691  +  rSpan /= 356.24;         /* Convert units to years */
         1692  +  return sqlite3_mprintf("%.1f years", rSpan);
         1693  +}
         1694  +
         1695  +/*
         1696  +** COMMAND: test-timespan
         1697  +** %fossil test-timespan TIMESTAMP
         1698  +**
         1699  +** Print the approximate span of time from now to TIMESTAMP.
         1700  +*/
         1701  +void test_timespan_cmd(void){
         1702  +  double rDiff;
         1703  +  if( g.argc!=3 ) usage("TIMESTAMP");
         1704  +  sqlite3_open(":memory:", &g.db);  
         1705  +  rDiff = db_double(0.0, "SELECT julianday('now') - julianday(%Q)", g.argv[2]);
         1706  +  printf("Time differences: %s\n", db_timespan_name(rDiff));
         1707  +  sqlite3_close(g.db);
         1708  +  g.db = 0;
         1709  +}

Changes to src/delta.c.

   193    193   }
   194    194   
   195    195   /*
   196    196   ** Compute a 32-bit checksum on the N-byte buffer.  Return the result.
   197    197   */
   198    198   static unsigned int checksum(const char *zIn, size_t N){
   199    199     const unsigned char *z = (const unsigned char *)zIn;
   200         -  unsigned sum = 0;
          200  +  unsigned sum0 = 0;
          201  +  unsigned sum1 = 0;
          202  +  unsigned sum2 = 0;
          203  +  unsigned sum3 = 0;
   201    204     while(N >= 16){
   202         -    sum += ((unsigned)z[0] + z[4] + z[8] + z[12]) << 24;
   203         -    sum += ((unsigned)z[1] + z[5] + z[9] + z[13]) << 16;
   204         -    sum += ((unsigned)z[2] + z[6] + z[10]+ z[14]) << 8;
   205         -    sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
          205  +    sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
          206  +    sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
          207  +    sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
          208  +    sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
   206    209       z += 16;
   207    210       N -= 16;
   208    211     }
   209    212     while(N >= 4){
   210         -    sum += (z[0]<<24) | (z[1]<<16) | (z[2]<<8) | z[3];
          213  +    sum0 += z[0];
          214  +    sum1 += z[1];
          215  +    sum2 += z[2];
          216  +    sum3 += z[3];
   211    217       z += 4;
   212    218       N -= 4;
   213    219     }
          220  +  sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
   214    221     switch(N){
   215         -    case 3:   sum += (z[2] << 8);
   216         -    case 2:   sum += (z[1] << 16);
   217         -    case 1:   sum += (z[0] << 24);
          222  +    case 3:   sum3 += (z[2] << 8);
          223  +    case 2:   sum3 += (z[1] << 16);
          224  +    case 1:   sum3 += (z[0] << 24);
   218    225       default:  ;
   219    226     }
   220         -  return sum;
          227  +  return sum3;
   221    228   }
   222    229   
   223    230   /*
   224    231   ** Create a new delta.
   225    232   **
   226    233   ** The delta is written into a preallocated buffer, zDelta, which 
   227    234   ** should be at least 60 bytes longer than the target file, zOut.
................................................................................
   315    322       return zDelta - zOrigDelta;
   316    323     }
   317    324   
   318    325     /* Compute the hash table used to locate matching sections in the
   319    326     ** source file.
   320    327     */
   321    328     nHash = lenSrc/NHASH;
   322         -  collide = malloc( nHash*2*sizeof(int) );
   323         -  if( collide==0 ) return -1;
          329  +  collide = fossil_malloc( nHash*2*sizeof(int) );
   324    330     landmark = &collide[nHash];
   325    331     memset(landmark, -1, nHash*sizeof(int));
   326    332     memset(collide, -1, nHash*sizeof(int));
   327    333     for(i=0; i<lenSrc-NHASH; i+=NHASH){
   328    334       int hv;
   329    335       hash_init(&h, &zSrc[i]);
   330    336       hv = hash_32bit(&h) % nHash;
................................................................................
   511    517     int lenSrc,            /* Length of the source file */
   512    518     const char *zDelta,    /* Delta to apply to the pattern */
   513    519     int lenDelta,          /* Length of the delta */
   514    520     char *zOut             /* Write the output into this preallocated buffer */
   515    521   ){
   516    522     unsigned int limit;
   517    523     unsigned int total = 0;
          524  +#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
   518    525     char *zOrigOut = zOut;
          526  +#endif
   519    527   
   520    528     limit = getInt(&zDelta, &lenDelta);
   521    529     if( *zDelta!='\n' ){
   522    530       /* ERROR: size integer not terminated by "\n" */
   523    531       return -1;
   524    532     }
   525    533     zDelta++; lenDelta--;
................................................................................
   566    574           zDelta += cnt;
   567    575           lenDelta -= cnt;
   568    576           break;
   569    577         }
   570    578         case ';': {
   571    579           zDelta++; lenDelta--;
   572    580           zOut[0] = 0;
          581  +#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
   573    582           if( cnt!=checksum(zOrigOut, total) ){
   574    583             /* ERROR:  bad checksum */
   575    584             return -1;
   576    585           }
          586  +#endif
   577    587           if( total!=limit ){
   578    588             /* ERROR: generated size does not match predicted size */
   579    589             return -1;
   580    590           }
   581    591           return total;
   582    592         }
   583    593         default: {

Changes to src/descendants.c.

   316    316       style_submenu_element("Open", "Open", "leaves");
   317    317     }
   318    318     style_header("Leaves");
   319    319     login_anonymous_available();
   320    320     compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);
   321    321     style_sidebox_begin("Nomenclature:", "33%");
   322    322     @ <ol>
   323         -  @ <li> A <b>leaf</b> is a check-in with no descendants.</li>
   324         -  @ <li> An <b>open leaf</b> is a leaf that does not have a "closed" tag
          323  +  @ <li> A <div class="sideboxDescribed">leaf</div>
          324  +  @ is a check-in with no descendants.</li>
          325  +  @ <li> An <div class="sideboxDescribed">open leaf</div>
          326  +  @ is a leaf that does not have a "closed" tag
   325    327     @ and is thus assumed to still be in use.</li>
   326         -  @ <li> A <b>closed leaf</b> has a "closed" tag and is thus assumed to
          328  +  @ <li> A <div class="sideboxDescribed">closed leaf</div>
          329  +  @ has a "closed" tag and is thus assumed to
   327    330     @ be historical and no longer in active use.</li>
   328    331     @ </ol>
   329    332     style_sidebox_end();
   330    333   
   331    334     if( showAll ){
   332    335       @ <h1>All leaves, both open and closed:</h1>
   333    336     }else if( showClosed ){
................................................................................
   339    342       "%s"
   340    343       "   AND blob.rid IN leaves"
   341    344       " ORDER BY event.mtime DESC",
   342    345       timeline_query_for_www()
   343    346     );
   344    347     www_print_timeline(&q, TIMELINE_LEAFONLY, leaves_extra);
   345    348     db_finalize(&q);
   346         -  @ <br clear="both">
   347         -  @ <script>
          349  +  @ <br />
          350  +  @ <script  type="text/JavaScript">
   348    351     @ function xin(id){
   349    352     @ }
   350    353     @ function xout(id){
   351    354     @ }
   352    355     @ </script>
   353    356     style_footer();
   354    357   }

Changes to src/diff.c.

    63     63   };
    64     64   
    65     65   /*
    66     66   ** Return an array of DLine objects containing a pointer to the
    67     67   ** start of each line and a hash of that line.  The lower 
    68     68   ** bits of the hash store the length of each line.
    69     69   **
    70         -** Trailing whitespace is removed from each line.
           70  +** Trailing whitespace is removed from each line.  2010-08-20:  Not any
           71  +** more.  If trailing whitespace is ignored, the "patch" command gets
           72  +** confused by the diff output.  Ticket [a9f7b23c2e376af5b0e5b]
    71     73   **
    72     74   ** Return 0 if the file is binary or contains a line that is
    73     75   ** too long.
    74     76   */
    75         -static DLine *break_into_lines(const char *z, int n, int *pnLine){
           77  +static DLine *break_into_lines(const char *z, int n, int *pnLine, int ignoreWS){
    76     78     int nLine, i, j, k, x;
    77     79     unsigned int h, h2;
    78     80     DLine *a;
    79     81   
    80     82     /* Count the number of lines.  Allocate space to hold
    81     83     ** the returned array.
    82     84     */
................................................................................
    92     94         }
    93     95         j = 0;
    94     96       }
    95     97     }
    96     98     if( j>LENGTH_MASK ){
    97     99       return 0;
    98    100     }
    99         -  a = malloc( nLine*sizeof(a[0]) );
   100         -  if( a==0 ) fossil_panic("out of memory");
          101  +  a = fossil_malloc( nLine*sizeof(a[0]) );
   101    102     memset(a, 0, nLine*sizeof(a[0]) );
          103  +  if( n==0 ){
          104  +    *pnLine = 0;
          105  +    return a;
          106  +  }
   102    107   
   103    108     /* Fill in the array */
   104    109     for(i=0; i<nLine; i++){
   105    110       a[i].z = z;
   106    111       for(j=0; z[j] && z[j]!='\n'; j++){}
   107         -    for(k=j; k>0 && isspace(z[k-1]); k--){}
          112  +    k = j;
          113  +    while( ignoreWS && k>0 && fossil_isspace(z[k-1]) ){ k--; }
   108    114       for(h=0, x=0; x<k; x++){
   109    115         h = h ^ (h<<2) ^ z[x];
   110    116       }
   111    117       a[i].h = h = (h<<LENGTH_MASK_SZ) | k;;
   112    118       h2 = h % nLine;
   113    119       a[i].iNext = a[h2].iHash;
   114    120       a[h2].iHash = i+1;
................................................................................
   136    142     blob_append(pOut, "\n", 1);
   137    143   }
   138    144   
   139    145   /*
   140    146   ** Expand the size of aEdit[] array to hold nEdit elements.
   141    147   */
   142    148   static void expandEdit(DContext *p, int nEdit){
   143         -  int *a;
   144         -  a = realloc(p->aEdit, nEdit*sizeof(int));
   145         -  if( a==0 ){
   146         -    free( p->aEdit );
   147         -    p->nEdit = 0;
   148         -    nEdit = 0;
   149         -  }
   150         -  p->aEdit = a;
          149  +  p->aEdit = fossil_realloc(p->aEdit, nEdit*sizeof(int));
   151    150     p->nEditAlloc = nEdit;
   152    151   }
   153    152   
   154    153   /*
   155    154   ** Append a new COPY/DELETE/INSERT triple.
   156    155   */
   157    156   static void appendTriple(DContext *p, int nCopy, int nDel, int nIns){
................................................................................
   277    276       m = R[r+nr*3];
   278    277       if( m>nContext ) m = nContext;
   279    278       for(j=0; j<m; j++){
   280    279         appendDiffLine(pOut, " ", &B[b+j]);
   281    280       }
   282    281     }
   283    282   }
          283  +
          284  +/*
          285  +** Compute the optimal longest common subsequence (LCS) using an
          286  +** exhaustive search.  This version of the LCS is only used for
          287  +** shorter input strings since runtime is O(N*N) where N is the
          288  +** input string length.
          289  +*/
          290  +static void optimalLCS(
          291  +  DContext *p,               /* Two files being compared */
          292  +  int iS1, int iE1,          /* Range of lines in p->aFrom[] */
          293  +  int iS2, int iE2,          /* Range of lines in p->aTo[] */
          294  +  int *piSX, int *piEX,      /* Write p->aFrom[] common segment here */
          295  +  int *piSY, int *piEY       /* Write p->aTo[] common segment here */
          296  +){
          297  +  int mxLength = 0;          /* Length of longest common subsequence */
          298  +  int i, j;                  /* Loop counters */
          299  +  int k;                     /* Length of a candidate subsequence */
          300  +  int iSXb = iS1;            /* Best match so far */
          301  +  int iSYb = iS2;            /* Best match so far */
          302  +
          303  +  for(i=iS1; i<iE1-mxLength; i++){
          304  +    for(j=iS2; j<iE2-mxLength; j++){
          305  +      if( !same_dline(&p->aFrom[i], &p->aTo[j]) ) continue;
          306  +      if( mxLength && !same_dline(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){
          307  +        continue;
          308  +      }
          309  +      k = 1;
          310  +      while( i+k<iE1 && j+k<iE2 && same_dline(&p->aFrom[i+k],&p->aTo[j+k]) ){
          311  +        k++;
          312  +      }
          313  +      if( k>mxLength ){
          314  +        iSXb = i;
          315  +        iSYb = j;
          316  +        mxLength = k;
          317  +      }
          318  +    }
          319  +  }
          320  +  *piSX = iSXb;
          321  +  *piEX = iSXb + mxLength;
          322  +  *piSY = iSYb;
          323  +  *piEY = iSYb + mxLength;
          324  +}
   284    325   
   285    326   /*
   286    327   ** Compare two blocks of text on lines iS1 through iE1-1 of the aFrom[]
   287    328   ** file and lines iS2 through iE2-1 of the aTo[] file.  Locate a sequence
   288    329   ** of lines in these two blocks that are exactly the same.  Return
   289    330   ** the bounds of the matching sequence.
          331  +**
          332  +** If there are two or more possible answers of the same length, the
          333  +** returned sequence should be the one closest to the center of the
          334  +** input range.
          335  +**
          336  +** Ideally, the common sequence should be the longest possible common
          337  +** sequence.  However, an exact computation of LCS is O(N*N) which is
          338  +** way too slow for larger files.  So this routine uses an O(N)
          339  +** heuristic approximation based on hashing that usually works about 
          340  +** as well.  But if the O(N) algorithm doesn't get a good solution
          341  +** and N is not too large, we fall back to an exact solution by
          342  +** calling optimalLCS().
   290    343   */
   291    344   static void longestCommonSequence(
   292    345     DContext *p,               /* Two files being compared */
   293    346     int iS1, int iE1,          /* Range of lines in p->aFrom[] */
   294    347     int iS2, int iE2,          /* Range of lines in p->aTo[] */
   295    348     int *piSX, int *piEX,      /* Write p->aFrom[] common segment here */
   296    349     int *piSY, int *piEY       /* Write p->aTo[] common segment here */
................................................................................
   300    353     int iSX, iSY, iEX, iEY;    /* Current match */
   301    354     double score;              /* Current score */
   302    355     int skew;                  /* How lopsided is the match */
   303    356     int dist;                  /* Distance of match from center */
   304    357     int mid;                   /* Center of the span */
   305    358     int iSXb, iSYb, iEXb, iEYb;   /* Best match so far */
   306    359     int iSXp, iSYp, iEXp, iEYp;   /* Previous match */
          360  +
   307    361   
   308    362     iSXb = iSXp = iS1;
   309    363     iEXb = iEXp = iS1;
   310    364     iSYb = iSYp = iS2;
   311    365     iEYb = iEYp = iS2;
   312    366     mid = (iE1 + iS1)/2;
   313    367     for(i=iS1; i<iE1; i++){
................................................................................
   352    406       }else{
   353    407         iSXp = iSX;
   354    408         iSYp = iSY;
   355    409         iEXp = iEX;
   356    410         iEYp = iEY;
   357    411       }
   358    412     }
   359         -  *piSX = iSXb;
   360         -  *piSY = iSYb;
   361         -  *piEX = iEXb;
   362         -  *piEY = iEYb;
          413  +  if( iSXb==iEXb && (iE1-iS1)*(iE2-iS2)<400 ){
          414  +    /* If no common sequence is found using the hashing heuristic and
          415  +    ** the input is not too big, use the expensive exact solution */
          416  +    optimalLCS(p, iS1, iE1, iS2, iE2, piSX, piEX, piSY, piEY);
          417  +  }else{
          418  +    *piSX = iSXb;
          419  +    *piSY = iSYb;
          420  +    *piEX = iEXb;
          421  +    *piEY = iEYb;
          422  +  }
   363    423     /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n", 
   364    424        iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY);  */
   365    425   }
   366    426   
   367    427   /*
   368    428   ** Do a single step in the difference.  Compute a sequence of
   369    429   ** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
................................................................................
   470    530   ** file is encountered, 0 is returned and pOut is written with
   471    531   ** text "cannot compute difference between binary files".
   472    532   */
   473    533   int *text_diff(
   474    534     Blob *pA_Blob,   /* FROM file */
   475    535     Blob *pB_Blob,   /* TO file */
   476    536     Blob *pOut,      /* Write unified diff here if not NULL */
   477         -  int nContext     /* Amount of context to unified diff */
          537  +  int nContext,    /* Amount of context to unified diff */
          538  +  int ignoreEolWs  /* Ignore whitespace at the end of lines */
   478    539   ){
   479    540     DContext c;
   480    541    
   481    542     /* Prepare the input files */
   482    543     memset(&c, 0, sizeof(c));
   483         -  c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), &c.nFrom);
   484         -  c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), &c.nTo);
          544  +  c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
          545  +                             &c.nFrom, ignoreEolWs);
          546  +  c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
          547  +                           &c.nTo, ignoreEolWs);
   485    548     if( c.aFrom==0 || c.aTo==0 ){
   486    549       free(c.aFrom);
   487    550       free(c.aTo);
   488    551       if( pOut ){
   489    552         blob_appendf(pOut, "cannot compute difference between binary files\n");
   490    553       }
   491    554       return 0;
................................................................................
   520    583     int i;
   521    584     int *R;
   522    585     if( g.argc<4 ) usage("FILE1 FILE2 ...");
   523    586     blob_read_from_file(&a, g.argv[2]);
   524    587     for(i=3; i<g.argc; i++){
   525    588       if( i>3 ) printf("-------------------------------\n");
   526    589       blob_read_from_file(&b, g.argv[i]);
   527         -    R = text_diff(&a, &b, 0, 0);
          590  +    R = text_diff(&a, &b, 0, 0, 0);
   528    591       for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
   529    592         printf(" copy %4d  delete %4d  insert %4d\n", R[r], R[r+1], R[r+2]);
   530    593       }
   531    594       /* free(R); */
   532    595       blob_reset(&b);
   533    596     }
   534    597   }
................................................................................
   538    601   */
   539    602   void test_udiff_cmd(void){
   540    603     Blob a, b, out;
   541    604     if( g.argc!=4 ) usage("FILE1 FILE2");
   542    605     blob_read_from_file(&a, g.argv[2]);
   543    606     blob_read_from_file(&b, g.argv[3]);
   544    607     blob_zero(&out);
   545         -  text_diff(&a, &b, &out, 3);
          608  +  text_diff(&a, &b, &out, 3, 0);
   546    609     blob_write_to_file(&out, "-");
   547    610   }
   548    611   
   549    612   /**************************************************************************
   550    613   ** The basic difference engine is above.  What follows is the annotation
   551    614   ** engine.  Both are in the same file since they share many components.
   552    615   */
................................................................................
   572    635   ** to be annotated.  The annotator takes control of the input Blob and
   573    636   ** will release it when it is finished with it.
   574    637   */
   575    638   static int annotation_start(Annotator *p, Blob *pInput){
   576    639     int i;
   577    640   
   578    641     memset(p, 0, sizeof(*p));
   579         -  p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput), &p->c.nTo);
          642  +  p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,1);
   580    643     if( p->c.aTo==0 ){
   581    644       return 1;
   582    645     }
   583         -  p->aOrig = malloc( sizeof(p->aOrig[0])*p->c.nTo );
   584         -  if( p->aOrig==0 ) fossil_panic("out of memory");
          646  +  p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
   585    647     for(i=0; i<p->c.nTo; i++){
   586    648       p->aOrig[i].z = p->c.aTo[i].z;
   587    649       p->aOrig[i].n = p->c.aTo[i].h & LENGTH_MASK;
   588    650       p->aOrig[i].zSrc = 0;
   589    651     }
   590    652     p->nOrig = p->c.nTo;
   591    653     return 0;
................................................................................
   600    662   */
   601    663   static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
   602    664     int i, j;
   603    665     int lnTo;
   604    666   
   605    667     /* Prepare the parent file to be diffed */
   606    668     p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
   607         -                                &p->c.nFrom);
          669  +                                &p->c.nFrom, 1);
   608    670     if( p->c.aFrom==0 ){
   609    671       return 1;
   610    672     }
   611    673   
   612    674     /* Compute the differences going from pParent to the file being
   613    675     ** annotated. */
   614    676     diff_all(&p->c);
................................................................................
   755    817   
   756    818   /*
   757    819   ** COMMAND: annotate
   758    820   **
   759    821   ** %fossil annotate FILENAME
   760    822   **
   761    823   ** Output the text of a file with markings to show when each line of
   762         -** the file was introduced.
          824  +** the file was last modified.
   763    825   */
   764    826   void annotate_cmd(void){
   765    827     int fnid;         /* Filename ID */
   766    828     int fid;          /* File instance ID */
   767    829     int mid;          /* Manifest where file was checked in */
   768    830     Blob treename;    /* FILENAME translated to canonical form */
   769    831     char *zFilename;  /* Cannonical filename */

Changes to src/diffcmd.c.

    18     18   ** This file contains code used to implement the "diff" command
    19     19   */
    20     20   #include "config.h"
    21     21   #include "diffcmd.h"
    22     22   #include <assert.h>
    23     23   
    24     24   /*
    25         -** Shell-escape the given string.  Append the result to a blob.
           25  +** Diff option flags
    26     26   */
    27         -static void shell_escape(Blob *pBlob, const char *zIn){
    28         -  int n = blob_size(pBlob);
    29         -  int k = strlen(zIn);
    30         -  int i, c;
    31         -  char *z;
    32         -  for(i=0; (c = zIn[i])!=0; i++){
    33         -    if( isspace(c) || c=='"' || (c=='\\' && zIn[i+1]!=0) ){
    34         -      blob_appendf(pBlob, "\"%s\"", zIn);
    35         -      z = blob_buffer(pBlob);
    36         -      for(i=n+1; i<=n+k; i++){
    37         -        if( z[i]=='"' ) z[i] = '_';
    38         -      }
    39         -      return;
    40         -    }
    41         -  }
    42         -  blob_append(pBlob, zIn, -1);
    43         -}
    44         -
    45         -/*
    46         -** This function implements a cross-platform "system()" interface.
    47         -*/
    48         -int portable_system(const char *zOrigCmd){
    49         -  int rc;
    50         -#ifdef __MINGW32__
    51         -  /* On windows, we have to put double-quotes around the entire command.
    52         -  ** Who knows why - this is just the way windows works.
    53         -  */
    54         -  char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
    55         -  rc = system(zNewCmd);
    56         -  free(zNewCmd);
    57         -#else
    58         -  /* On unix, evaluate the command directly.
    59         -  */
    60         -  rc = system(zOrigCmd);
    61         -#endif 
    62         -  return rc; 
    63         -}
           27  +#define DIFF_NEWFILE  0x01    /* Treat non-existing fails as empty files */
           28  +#define DIFF_NOEOLWS  0x02    /* Ignore whitespace at the end of lines */
    64     29   
    65     30   /*
    66     31   ** Show the difference between two files, one in memory and one on disk.
    67     32   **
    68     33   ** The difference is the set of edits needed to transform pFile1 into
    69     34   ** zFile2.  The content of pFile1 is in memory.  zFile2 exists on disk.
    70     35   **
................................................................................
    71     36   ** Use the internal diff logic if zDiffCmd is NULL.  Otherwise call the
    72     37   ** command zDiffCmd to do the diffing.
    73     38   */
    74     39   static void diff_file(
    75     40     Blob *pFile1,             /* In memory content to compare from */
    76     41     const char *zFile2,       /* On disk content to compare to */
    77     42     const char *zName,        /* Display name of the file */
    78         -  const char *zDiffCmd      /* Command for comparison */
           43  +  const char *zDiffCmd,     /* Command for comparison */
           44  +  int ignoreEolWs           /* Ignore whitespace at end of line */
    79     45   ){
    80     46     if( zDiffCmd==0 ){
    81         -    Blob out;      /* Diff output text */
    82         -    Blob file2;    /* Content of zFile2 */
           47  +    Blob out;                 /* Diff output text */
           48  +    Blob file2;               /* Content of zFile2 */
           49  +    const char *zName2;       /* Name of zFile2 for display */
    83     50   
    84     51       /* Read content of zFile2 into memory */
    85     52       blob_zero(&file2);
    86         -    blob_read_from_file(&file2, zFile2);
           53  +    if( file_size(zFile2)<0 ){
           54  +      zName2 = "/dev/null";
           55  +    }else{
           56  +      blob_read_from_file(&file2, zFile2);
           57  +      zName2 = zName;
           58  +    }
    87     59   
    88     60       /* Compute and output the differences */
    89     61       blob_zero(&out);
    90         -    text_diff(pFile1, &file2, &out, 5);
    91         -    printf("--- %s\n+++ %s\n", zName, zName);
           62  +    text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
           63  +    printf("--- %s\n+++ %s\n", zName, zName2);
    92     64       printf("%s\n", blob_str(&out));
    93     65   
    94     66       /* Release memory resources */
    95     67       blob_reset(&file2);
    96     68       blob_reset(&out);
    97     69     }else{
    98     70       int cnt = 0;
................................................................................
   112     84       blob_zero(&cmd);
   113     85       blob_appendf(&cmd, "%s ", zDiffCmd);
   114     86       shell_escape(&cmd, blob_str(&nameFile1));
   115     87       blob_append(&cmd, " ", 1);
   116     88       shell_escape(&cmd, zFile2);
   117     89   
   118     90       /* Run the external diff command */
   119         -    portable_system(blob_str(&cmd));
           91  +    fossil_system(blob_str(&cmd));
   120     92   
   121     93       /* Delete the temporary file and clean up memory used */
   122     94       unlink(blob_str(&nameFile1));
   123     95       blob_reset(&nameFile1);
   124     96       blob_reset(&cmd);
   125     97     }
   126     98   }
................................................................................
   134    106   ** Use the internal diff logic if zDiffCmd is NULL.  Otherwise call the
   135    107   ** command zDiffCmd to do the diffing.
   136    108   */
   137    109   static void diff_file_mem(
   138    110     Blob *pFile1,             /* In memory content to compare from */
   139    111     Blob *pFile2,             /* In memory content to compare to */
   140    112     const char *zName,        /* Display name of the file */
   141         -  const char *zDiffCmd      /* Command for comparison */
          113  +  const char *zDiffCmd,     /* Command for comparison */
          114  +  int ignoreEolWs           /* Ignore whitespace at end of lines */
   142    115   ){
   143    116     if( zDiffCmd==0 ){
   144    117       Blob out;      /* Diff output text */
   145    118   
   146    119       blob_zero(&out);
   147         -    text_diff(pFile1, pFile2, &out, 5);
          120  +    text_diff(pFile1, pFile2, &out, 5, ignoreEolWs);
   148    121       printf("--- %s\n+++ %s\n", zName, zName);
   149    122       printf("%s\n", blob_str(&out));
   150    123   
   151    124       /* Release memory resources */
   152    125       blob_reset(&out);
   153    126     }else{
   154    127       Blob cmd;
................................................................................
   165    138       blob_zero(&cmd);
   166    139       blob_appendf(&cmd, "%s ", zDiffCmd);
   167    140       shell_escape(&cmd, zTemp1);
   168    141       blob_append(&cmd, " ", 1);
   169    142       shell_escape(&cmd, zTemp2);
   170    143   
   171    144       /* Run the external diff command */
   172         -    portable_system(blob_str(&cmd));
          145  +    fossil_system(blob_str(&cmd));
   173    146   
   174    147       /* Delete the temporary file and clean up memory used */
   175    148       unlink(zTemp1);
   176    149       unlink(zTemp2);
   177    150       blob_reset(&cmd);
   178    151     }
   179    152   }
   180    153   
   181    154   /*
   182    155   ** Do a diff against a single file named in g.argv[2] from version zFrom
   183    156   ** against the same file on disk.
   184    157   */
   185         -static void diff_one_against_disk(const char *zFrom, const char *zDiffCmd){
          158  +static void diff_one_against_disk(
          159  +  const char *zFrom,        /* Name of file */
          160  +  const char *zDiffCmd,     /* Use this "diff" command */
          161  +  int ignoreEolWs           /* Ignore whitespace changes at end of lines */
          162  +){
   186    163     Blob fname;
   187    164     Blob content;
   188    165     file_tree_name(g.argv[2], &fname, 1);
   189    166     historical_version_of_file(zFrom, blob_str(&fname), &content, 0);
   190         -  diff_file(&content, g.argv[2], g.argv[2], zDiffCmd);
          167  +  diff_file(&content, g.argv[2], g.argv[2], zDiffCmd, ignoreEolWs);
   191    168     blob_reset(&content);
   192    169     blob_reset(&fname);
   193    170   }
   194    171   
   195    172   /*
   196    173   ** Run a diff between the version zFrom and files on disk.  zFrom might
   197    174   ** be NULL which means to simply show the difference between the edited
   198    175   ** files on disk and the check-out on which they are based.
   199    176   */
   200         -static void diff_all_against_disk(const char *zFrom, const char *zDiffCmd){
          177  +static void diff_all_against_disk(
          178  +  const char *zFrom,        /* Version to difference from */
          179  +  const char *zDiffCmd,     /* Use this diff command.  NULL for built-in */
          180  +  int diffFlags             /* Flags controlling diff output */
          181  +){
   201    182     int vid;
   202    183     Blob sql;
   203    184     Stmt q;
          185  +  int ignoreEolWs;          /* Ignore end-of-line whitespace */
          186  +  int asNewFile;            /* Treat non-existant files as empty files */
   204    187   
          188  +  ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
          189  +  asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
   205    190     vid = db_lget_int("checkout", 0);
   206    191     vfile_check_signature(vid, 1);
   207    192     blob_zero(&sql);
   208    193     db_begin_transaction();
   209    194     if( zFrom ){
   210    195       int rid = name_to_rid(zFrom);
   211    196       if( !is_a_version(rid) ){
................................................................................
   244    229     }
   245    230     db_prepare(&q, blob_str(&sql));
   246    231     while( db_step(&q)==SQLITE_ROW ){
   247    232       const char *zPathname = db_column_text(&q,0);
   248    233       int isDeleted = db_column_int(&q, 1);
   249    234       int isChnged = db_column_int(&q,2);
   250    235       int isNew = db_column_int(&q,3);
          236  +    int srcid = db_column_int(&q, 4);
   251    237       char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
          238  +    char *zToFree = zFullName;
          239  +    int showDiff = 1;
   252    240       if( isDeleted ){
   253    241         printf("DELETED  %s\n", zPathname);
          242  +      if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; }
   254    243       }else if( access(zFullName, 0) ){
   255    244         printf("MISSING  %s\n", zPathname);
          245  +      if( !asNewFile ){ showDiff = 0; }
   256    246       }else if( isNew ){
   257    247         printf("ADDED    %s\n", zPathname);
   258         -    }else if( isDeleted ){
   259         -      printf("DELETED  %s\n", zPathname);
          248  +      srcid = 0;
          249  +      if( !asNewFile ){ showDiff = 0; }
   260    250       }else if( isChnged==3 ){
   261    251         printf("ADDED_BY_MERGE %s\n", zPathname);
   262         -    }else{
   263         -      int srcid = db_column_int(&q, 4);
          252  +      srcid = 0;
          253  +      if( !asNewFile ){ showDiff = 0; }
          254  +    }
          255  +    if( showDiff ){
   264    256         Blob content;
   265         -      content_get(srcid, &content);
          257  +      if( srcid>0 ){
          258  +        content_get(srcid, &content);
          259  +      }else{
          260  +        blob_zero(&content);
          261  +      }
   266    262         printf("Index: %s\n======================================="
   267    263                "============================\n",
   268    264                zPathname
   269    265         );
   270         -      diff_file(&content, zFullName, zPathname, zDiffCmd);
          266  +      diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
   271    267         blob_reset(&content);
   272    268       }
   273         -    free(zFullName);
          269  +    free(zToFree);
   274    270     }
   275    271     db_finalize(&q);
   276    272     db_end_transaction(1);  /* ROLLBACK */
   277    273   }
   278    274   
   279    275   /*
   280    276   ** Output the differences between two versions of a single file.
   281    277   ** zFrom and zTo are the check-ins containing the two file versions.
   282    278   ** The filename is contained in g.argv[2].
   283    279   */
   284    280   static void diff_one_two_versions(
   285    281     const char *zFrom,
   286    282     const char *zTo,
   287         -  const char *zDiffCmd
          283  +  const char *zDiffCmd,
          284  +  int ignoreEolWs
   288    285   ){
   289    286     char *zName;
   290    287     Blob fname;
   291    288     Blob v1, v2;
   292    289     file_tree_name(g.argv[2], &fname, 1);
   293    290     zName = blob_str(&fname);
   294    291     historical_version_of_file(zFrom, zName, &v1, 0);
   295    292     historical_version_of_file(zTo, zName, &v2, 0);
   296         -  diff_file_mem(&v1, &v2, zName, zDiffCmd);
          293  +  diff_file_mem(&v1, &v2, zName, zDiffCmd, ignoreEolWs);
   297    294     blob_reset(&v1);
   298    295     blob_reset(&v2);
   299    296     blob_reset(&fname);
   300    297   }
          298  +
          299  +/*
          300  +** Show the difference between two files identified by ManifestFile
          301  +** entries.
          302  +*/
          303  +static void diff_manifest_entry(
          304  +  struct ManifestFile *pFrom,
          305  +  struct ManifestFile *pTo,
          306  +  const char *zDiffCmd,
          307  +  int ignoreEolWs
          308  +){
          309  +  Blob f1, f2;
          310  +  int rid;
          311  +  const char *zName =  pFrom ? pFrom->zName : pTo->zName;
          312  +  printf("Index: %s\n======================================="
          313  +         "============================\n", zName);
          314  +  if( pFrom ){
          315  +    rid = uuid_to_rid(pFrom->zUuid, 0);
          316  +    content_get(rid, &f1);
          317  +  }else{
          318  +    blob_zero(&f1);
          319  +  }
          320  +  if( pTo ){
          321  +    rid = uuid_to_rid(pTo->zUuid, 0);
          322  +    content_get(rid, &f2);
          323  +  }else{
          324  +    blob_zero(&f2);
          325  +  }
          326  +  diff_file_mem(&f1, &f2, zName, zDiffCmd, ignoreEolWs);
          327  +  blob_reset(&f1);
          328  +  blob_reset(&f2);
          329  +}
   301    330   
   302    331   /*
   303    332   ** Output the differences between two check-ins.
   304    333   */
   305    334   static void diff_all_two_versions(
   306    335     const char *zFrom,
   307    336     const char *zTo,
   308         -  const char *zDiffCmd
          337  +  const char *zDiffCmd,
          338  +  int diffFlags
   309    339   ){
   310         -  Manifest mFrom, mTo;
   311         -  int iFrom, iTo;
          340  +  Manifest *pFrom, *pTo;
          341  +  ManifestFile *pFromFile, *pToFile;
          342  +  int ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0 ? 1 : 0;
          343  +  int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0;
          344  +
          345  +  pFrom = manifest_get_by_name(zFrom, 0);
          346  +  manifest_file_rewind(pFrom);
          347  +  pFromFile = manifest_file_next(pFrom,0);
          348  +  pTo = manifest_get_by_name(zTo, 0);
          349  +  manifest_file_rewind(pTo);
          350  +  pToFile = manifest_file_next(pTo,0);
   312    351   
   313         -  manifest_from_name(zFrom, &mFrom);
   314         -  manifest_from_name(zTo, &mTo);
   315         -  iFrom = iTo = 0;
   316         -  while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
          352  +  while( pFromFile || pToFile ){
   317    353       int cmp;
   318         -    if( iFrom>=mFrom.nFile ){
          354  +    if( pFromFile==0 ){
   319    355         cmp = +1;
   320         -    }else if( iTo>=mTo.nFile ){
          356  +    }else if( pToFile==0 ){
   321    357         cmp = -1;
   322    358       }else{
   323         -      cmp = strcmp(mFrom.aFile[iFrom].zName, mTo.aFile[iTo].zName);
          359  +      cmp = strcmp(pFromFile->zName, pToFile->zName);
   324    360       }
   325    361       if( cmp<0 ){
   326         -      printf("DELETED %s\n", mFrom.aFile[iFrom].zName);
   327         -      iFrom++;
          362  +      printf("DELETED %s\n", pFromFile->zName);
          363  +      if( asNewFlag ){
          364  +        diff_manifest_entry(pFromFile, 0, zDiffCmd, ignoreEolWs);
          365  +      }
          366  +      pFromFile = manifest_file_next(pFrom,0);
   328    367       }else if( cmp>0 ){
   329         -      printf("ADDED   %s\n", mTo.aFile[iTo].zName);
   330         -      iTo++;
   331         -    }else if( strcmp(mFrom.aFile[iFrom].zUuid, mTo.aFile[iTo].zUuid)==0 ){
          368  +      printf("ADDED   %s\n", pToFile->zName);
          369  +      if( asNewFlag ){
          370  +        diff_manifest_entry(0, pToFile, zDiffCmd, ignoreEolWs);
          371  +      }
          372  +      pToFile = manifest_file_next(pTo,0);
          373  +    }else if( strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
   332    374         /* No changes */
   333         -      iFrom++;
   334         -      iTo++;
          375  +      pFromFile = manifest_file_next(pFrom,0);
          376  +      pToFile = manifest_file_next(pTo,0);
   335    377       }else{
   336         -      Blob f1, f2;
   337         -      int rid;
   338         -      printf("CHANGED %s\n", mFrom.aFile[iFrom].zName);
   339         -      rid = uuid_to_rid(mFrom.aFile[iFrom].zUuid, 0);
   340         -      content_get(rid, &f1);
   341         -      rid = uuid_to_rid(mTo.aFile[iTo].zUuid, 0);
   342         -      content_get(rid, &f2);
   343         -      diff_file_mem(&f1, &f2, mFrom.aFile[iFrom].zName, zDiffCmd);
   344         -      blob_reset(&f1);
   345         -      blob_reset(&f2);
   346         -      iFrom++;
   347         -      iTo++;
          378  +      printf("CHANGED %s\n", pFromFile->zName);
          379  +      diff_manifest_entry(pFromFile, pToFile, zDiffCmd, ignoreEolWs);
          380  +      pFromFile = manifest_file_next(pFrom,0);
          381  +      pToFile = manifest_file_next(pTo,0);
   348    382       }
   349    383     }
   350         -  manifest_clear(&mFrom);
   351         -  manifest_clear(&mTo);
          384  +  manifest_destroy(pFrom);
          385  +  manifest_destroy(pTo);
   352    386   }
   353    387   
   354    388   /*
   355    389   ** COMMAND: diff
   356    390   ** COMMAND: gdiff
   357    391   **
   358    392   ** Usage: %fossil diff|gdiff ?options? ?FILE?
................................................................................
   371    405   ** no "--to" option then the (possibly edited) files in the current check-out
   372    406   ** are used.
   373    407   **
   374    408   ** The "-i" command-line option forces the use of the internal diff logic
   375    409   ** rather than any external diff program that might be configured using
   376    410   ** the "setting" command.  If no external diff program is configured, then
   377    411   ** the "-i" option is a no-op.  The "-i" option converts "gdiff" into "diff".
          412  +**
          413  +** The "-N" or "--new-file" option causes the complete text of added or
          414  +** deleted files to be displayed.
   378    415   */
   379    416   void diff_cmd(void){
   380    417     int isGDiff;               /* True for gdiff.  False for normal diff */
   381    418     int isInternDiff;          /* True for internal diff */
          419  +  int hasNFlag;              /* True if -N or --new-file flag is used */
   382    420     const char *zFrom;         /* Source version number */
   383    421     const char *zTo;           /* Target version number */
   384    422     const char *zDiffCmd = 0;  /* External diff command. NULL for internal diff */
          423  +  int diffFlags = 0;         /* Flags to control the DIFF */
   385    424   
   386    425     isGDiff = g.argv[1][0]=='g';
   387    426     isInternDiff = find_option("internal","i",0)!=0;
   388    427     zFrom = find_option("from", "r", 1);
   389    428     zTo = find_option("to", 0, 1);
          429  +  hasNFlag = find_option("new-file","N",0)!=0;
          430  +
   390    431   
          432  +  if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
   391    433     if( zTo==0 ){
   392    434       db_must_be_within_tree();
   393    435       verify_all_options();
   394         -    if( !isInternDiff && g.argc==3 ){
          436  +    if( !isInternDiff ){
   395    437         zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
   396    438       }
   397    439       if( g.argc==3 ){
   398         -      diff_one_against_disk(zFrom, zDiffCmd);
          440  +      diff_one_against_disk(zFrom, zDiffCmd, 0);
   399    441       }else{
   400         -      diff_all_against_disk(zFrom, zDiffCmd);
          442  +      diff_all_against_disk(zFrom, zDiffCmd, diffFlags);
   401    443       }
   402    444     }else if( zFrom==0 ){
   403    445       fossil_fatal("must use --from if --to is present");
   404    446     }else{
   405    447       db_find_and_open_repository(1);
   406    448       verify_all_options();
   407         -    if( !isInternDiff && g.argc==3 ){
          449  +    if( !isInternDiff ){
   408    450         zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
   409    451       }
   410    452       if( g.argc==3 ){
   411         -      diff_one_two_versions(zFrom, zTo, zDiffCmd);
          453  +      diff_one_two_versions(zFrom, zTo, zDiffCmd, 0);
   412    454       }else{
   413         -      diff_all_two_versions(zFrom, zTo, zDiffCmd);
          455  +      diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
   414    456       }
   415    457     }
   416    458   }

Changes to src/doc.c.

   288    288     z = zName;
   289    289     for(i=0; zName[i]; i++){
   290    290       if( zName[i]=='.' ) z = &zName[i+1];
   291    291     }
   292    292     len = strlen(z);
   293    293     if( len<sizeof(zSuffix)-1 ){
   294    294       strcpy(zSuffix, z);
   295         -    for(i=0; zSuffix[i]; i++) zSuffix[i] = tolower(zSuffix[i]);
          295  +    for(i=0; zSuffix[i]; i++) zSuffix[i] = fossil_tolower(zSuffix[i]);
   296    296       first = 0;
   297    297       last = sizeof(aMime)/sizeof(aMime[0]);
   298    298       while( first<=last ){
   299    299         int c;
   300    300         i = (first+last)/2;
   301    301         c = strcmp(zSuffix, aMime[i].zSuffix);
   302    302         if( c==0 ) return aMime[i].zMimetype;
................................................................................
   386    386                       " WHERE vid=%d AND fname=%Q", vid, zName);
   387    387       if( rid==0 && db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
   388    388         goto doc_not_found;
   389    389       }
   390    390   
   391    391       if( rid==0 ){
   392    392         Stmt s;
   393         -      Blob baseline;
   394         -      Manifest m;
          393  +      Manifest *pM;
          394  +      ManifestFile *pFile;
   395    395   
   396    396         /* Add the vid baseline to the cache */
   397    397         if( db_int(0, "SELECT count(*) FROM vcache")>10000 ){
   398    398           db_multi_exec("DELETE FROM vcache");
   399    399         }
   400         -      if( content_get(vid, &baseline)==0 ){
   401         -        goto doc_not_found;
   402         -      }
   403         -      if( manifest_parse(&m, &baseline)==0 || m.type!=CFTYPE_MANIFEST ){
          400  +      pM = manifest_get(vid, CFTYPE_MANIFEST);
          401  +      if( pM==0 ){
   404    402           goto doc_not_found;
   405    403         }
   406    404         db_prepare(&s,
   407    405           "INSERT INTO vcache(vid,fname,rid)"
   408    406           " SELECT %d, :fname, rid FROM blob"
   409    407           "  WHERE uuid=:uuid",
   410    408           vid
   411    409         );
   412         -      for(i=0; i<m.nFile; i++){
   413         -        db_bind_text(&s, ":fname", m.aFile[i].zName);
   414         -        db_bind_text(&s, ":uuid", m.aFile[i].zUuid);
          410  +      manifest_file_rewind(pM);
          411  +      while( (pFile = manifest_file_next(pM,0))!=0 ){
          412  +        db_bind_text(&s, ":fname", pFile->zName);
          413  +        db_bind_text(&s, ":uuid", pFile->zUuid);
   415    414           db_step(&s);
   416    415           db_reset(&s);
   417    416         }
   418    417         db_finalize(&s);
   419         -      manifest_clear(&m);
          418  +      manifest_destroy(pM);
   420    419   
   421    420         /* Try again to find the file */
   422    421         rid = db_int(0, "SELECT rid FROM vcache"
   423    422                         " WHERE vid=%d AND fname=%Q", vid, zName);
   424    423       }
   425    424       if( rid==0 ){
   426    425         goto doc_not_found;

Changes to src/encode.c.

    42     42         case '&':   count += 5;       break;
    43     43         case '"':   count += 6;       break;
    44     44         default:    count++;          break;
    45     45       }
    46     46       i++;
    47     47     }
    48     48     i = 0;
    49         -  zOut = malloc( count+1 );
    50         -  if( zOut==0 ) return 0;
           49  +  zOut = fossil_malloc( count+1 );
    51     50     while( n-->0 && (c = *zIn)!=0 ){
    52     51       switch( c ){
    53     52         case '<':   
    54     53           zOut[i++] = '&';
    55     54           zOut[i++] = 'l';
    56     55           zOut[i++] = 't';
    57     56           zOut[i++] = ';';
................................................................................
    98     97   static char *EncodeHttp(const char *zIn, int n, int encodeSlash){
    99     98     int c;
   100     99     int i = 0;
   101    100     int count = 0;
   102    101     char *zOut;
   103    102     int other;
   104    103   # define IsSafeChar(X)  \
   105         -     (isalnum(X) || (X)=='.' || (X)=='$' || (X)=='-' || (X)=='_' || (X)==other)
          104  +     (fossil_isalnum(X) || (X)=='.' || (X)=='$' \
          105  +      || (X)=='~' || (X)=='-' || (X)=='_' || (X)==other)
   106    106   
   107    107     if( zIn==0 ) return 0;
   108    108     if( n<0 ) n = strlen(zIn);
   109    109     other = encodeSlash ? 'a' : '/';
   110    110     while( i<n && (c = zIn[i])!=0 ){
   111    111       if( IsSafeChar(c) || c==' ' ){
   112    112         count++;
   113    113       }else{
   114    114         count += 3;
   115    115       }
   116    116       i++;
   117    117     }
   118    118     i = 0;
   119         -  zOut = malloc( count+1 );
   120         -  if( zOut==0 ) return 0;
          119  +  zOut = fossil_malloc( count+1 );
   121    120     while( n-->0 && (c = *zIn)!=0 ){
   122    121       if( IsSafeChar(c) ){
   123    122         zOut[i++] = c;
   124    123       }else if( c==' ' ){
   125    124         zOut[i++] = '+';
   126    125       }else{
   127    126         zOut[i++] = '%';
................................................................................
   231    230     if( nIn<0 ) nIn = strlen(zIn);
   232    231     for(i=n=0; i<nIn; i++){
   233    232       c = zIn[i];
   234    233       if( c==0 || c==' ' || c=='\n' || c=='\t' || c=='\r' || c=='\f' || c=='\v'
   235    234                || c=='\\' ) n++;
   236    235     }
   237    236     n += nIn;
   238         -  zOut = malloc( n+1 );
          237  +  zOut = fossil_malloc( n+1 );
   239    238     if( zOut ){
   240    239       for(i=j=0; i<nIn; i++){
   241    240         int c = zIn[i];
   242    241         if( c==0 ){
   243    242           zOut[j++] = '\\';
   244    243           zOut[j++] = '0';
   245    244         }else if( c=='\\' ){
   246    245           zOut[j++] = '\\';
   247    246           zOut[j++] = '\\';
   248         -      }else if( isspace(c) ){
          247  +      }else if( fossil_isspace(c) ){
   249    248           zOut[j++] = '\\';
   250    249           switch( c ){
   251    250             case '\n':  c = 'n'; break;
   252    251             case ' ':   c = 's'; break;
   253    252             case '\t':  c = 't'; break;
   254    253             case '\r':  c = 'r'; break;
   255    254             case '\v':  c = 'v'; break;
................................................................................
   266    265   }
   267    266   
   268    267   /*
   269    268   ** Decode a fossilized string in-place.
   270    269   */
   271    270   void defossilize(char *z){
   272    271     int i, j, c;
   273         -  for(i=j=0; z[i]; i++){
   274         -    c = z[i];
          272  +  for(i=0; (c=z[i])!=0 && c!='\\'; i++){}
          273  +  if( c==0 ) return;
          274  +  for(j=i; (c=z[i])!=0; i++){
   275    275       if( c=='\\' && z[i+1] ){
   276    276         i++;
   277    277         switch( z[i] ){
   278    278           case 'n':  c = '\n';  break;
   279    279           case 's':  c = ' ';   break;
   280    280           case 't':  c = '\t';  break;
   281    281           case 'r':  c = '\r';  break;
................................................................................
   307    307   char *encode64(const char *zData, int nData){
   308    308     char *z64;
   309    309     int i, n;
   310    310   
   311    311     if( nData<=0 ){
   312    312       nData = strlen(zData);
   313    313     }
   314         -  z64 = malloc( (nData*4)/3 + 8 );
          314  +  z64 = fossil_malloc( (nData*4)/3 + 8 );
   315    315     for(i=n=0; i+2<nData; i+=3){
   316    316       z64[n++] = zBase[ (zData[i]>>2) & 0x3f ];
   317    317       z64[n++] = zBase[ ((zData[i]<<4) & 0x30) | ((zData[i+1]>>4) & 0x0f) ];
   318    318       z64[n++] = zBase[ ((zData[i+1]<<2) & 0x3c) | ((zData[i+2]>>6) & 0x03) ];
   319    319       z64[n++] = zBase[ zData[i+2] & 0x3f ];
   320    320     }
   321    321     if( i+1<nData ){
................................................................................
   368    368     if( !isInit ){
   369    369       for(i=0; i<128; i++){ trans[i] = 0; }
   370    370       for(i=0; zBase[i]; i++){ trans[zBase[i] & 0x7f] = i; }
   371    371       isInit = 1;
   372    372     }
   373    373     n64 = strlen(z64);
   374    374     while( n64>0 && z64[n64-1]=='=' ) n64--;
   375         -  zData = malloc( (n64*3)/4 + 4 );
          375  +  zData = fossil_malloc( (n64*3)/4 + 4 );
   376    376     for(i=j=0; i+3<n64; i+=4){
   377    377       a = trans[z64[i] & 0x7f];
   378    378       b = trans[z64[i+1] & 0x7f];
   379    379       c = trans[z64[i+2] & 0x7f];
   380    380       d = trans[z64[i+3] & 0x7f];
   381    381       zData[j++] = ((a<<2) & 0xfc) | ((b>>4) & 0x03);
   382    382       zData[j++] = ((b<<4) & 0xf0) | ((c>>2) & 0x0f);
................................................................................
   503    503   */
   504    504   void canonical16(char *z, int n){
   505    505     while( *z && n-- ){
   506    506       *z = zEncode[zDecode[(*z)&0x7f]&0x1f];
   507    507       z++;
   508    508     }
   509    509   }
          510  +
          511  +/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
          512  +static const unsigned char aObscurer[16] = {
          513  +    0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
          514  +    0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
          515  +};
          516  + 
          517  +
          518  +/*
          519  +** Obscure plain text so that it is not easily readable.
          520  +**
          521  +** This is used for storing sensitive information (such as passwords) in a
          522  +** way that prevents their exposure through idle browsing.  This is not
          523  +** encryption.  Anybody who really wants the password can still get it.
          524  +**
          525  +** The text is XOR-ed with a repeating pattern then converted to hex.
          526  +** Space to hold the returned string is obtained from malloc and should
          527  +** be freed by the caller.
          528  +*/
          529  +char *obscure(const char *zIn){
          530  +  int n, i;
          531  +  unsigned char salt;
          532  +  char *zOut;
          533  +  
          534  +  if( zIn==0 ) return 0;
          535  +  n = strlen(zIn);
          536  +  zOut = fossil_malloc( n*2+3 );
          537  +  sqlite3_randomness(1, &salt);
          538  +  zOut[n+1] = (char)salt;
          539  +  for(i=0; i<n; i++) zOut[i+n+2] = zIn[i]^aObscurer[i&0x0f]^salt;
          540  +  encode16((unsigned char*)&zOut[n+1], (unsigned char*)zOut, n+1);
          541  +  return zOut;
          542  +}
          543  +
          544  +/*
          545  +** Undo the obscuring of text performed by obscure().  Or, if the input is
          546  +** not hexadecimal (meaning the input is not the output of obscure()) then
          547  +** do the equivalent of strdup().
          548  +**
          549  +** The result is memory obtained from malloc that should be freed by the caller. 
          550  +*/
          551  +char *unobscure(const char *zIn){
          552  +  int n, i;
          553  +  unsigned char salt;
          554  +  char *zOut;
          555  +  
          556  +  if( zIn==0 ) return 0;
          557  +  n = strlen(zIn);
          558  +  zOut = fossil_malloc( n + 1 );
          559  +  if( n<2
          560  +    || decode16((unsigned char*)zIn, &salt, 2)
          561  +    || decode16((unsigned char*)&zIn[2], (unsigned char*)zOut, n-2)
          562  +  ){
          563  +    memcpy(zOut, zIn, n+1);
          564  +  }else{
          565  +    n = n/2 - 1;
          566  +    for(i=0; i<n; i++) zOut[i] = zOut[i]^aObscurer[i&0x0f]^salt;
          567  +    zOut[n] = 0;
          568  +  }
          569  +  return zOut;
          570  +}
          571  +
          572  +/*
          573  +** Command to test obscure() and unobscure().  These commands are also useful
          574  +** utilities for decoding passwords found in the database.
          575  +**
          576  +** COMMAND: test-obscure
          577  +*/
          578  +void test_obscure_cmd(void){
          579  +  int i;
          580  +  char *z, *z2;
          581  +  for(i=2; i<g.argc; i++){
          582  +    z = obscure(g.argv[i]);
          583  +    z2 = unobscure(z);
          584  +    printf("OBSCURE:    %s -> %s (%s)\n", g.argv[i], z, z2);
          585  +    free(z);
          586  +    free(z2);
          587  +    z = unobscure(g.argv[i]);
          588  +    printf("UNOBSCURE:  %s -> %s\n", g.argv[i], z);
          589  +    free(z);
          590  +  }
          591  +}

Added src/event.c.

            1  +/*
            2  +** Copyright (c) 2010 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the Simplified BSD License (also
            6  +** known as the "2-Clause License" or "FreeBSD License".)
            7  +
            8  +** This program is distributed in the hope that it will be useful,
            9  +** but without any warranty; without even the implied warranty of
           10  +** merchantability or fitness for a particular purpose.
           11  +**
           12  +** Author contact information:
           13  +**   drh@hwaci.com
           14  +**   http://www.hwaci.com/drh/
           15  +**
           16  +*******************************************************************************
           17  +**
           18  +** This file contains code to do formatting of event messages:
           19  +**
           20  +**     Milestones
           21  +**     Blog posts
           22  +**     New articles
           23  +**     Process checkpoints
           24  +**     Announcements
           25  +*/
           26  +#include <assert.h>
           27  +#include <ctype.h>
           28  +#include "config.h"
           29  +#include "event.h"
           30  +
           31  +/*
           32  +** Output a hyperlink to an event given its tagid.
           33  +*/
           34  +void hyperlink_to_event_tagid(int tagid){
           35  +  char *zEventId;
           36  +  char zShort[12];
           37  +
           38  +  zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d",
           39  +                     tagid);
           40  +  sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zEventId);
           41  +  if( g.okHistory ){
           42  +    @ [<a href="%s(g.zTop)/event?name=%s(zEventId)">%s(zShort)</a>]
           43  +  }else{
           44  +    @ [%s(zShort)]
           45  +  }
           46  +  free(zEventId);
           47  +}
           48  +
           49  +/*
           50  +** WEBPAGE: event
           51  +** URL: /event
           52  +** PARAMETERS:
           53  +**
           54  +**  name=EVENTID      // Identify the event to display EVENTID must be complete
           55  +**  detail=BOOLEAN    // Show details if TRUE.  Default is FALSE.  Optional.
           56  +**  aid=ARTIFACTID    // Which specific version of the event.  Optional.
           57  +**
           58  +** Display an existing event identified by EVENTID
           59  +*/
           60  +void event_page(void){
           61  +  int rid = 0;             /* rid of the event artifact */
           62  +  char *zUuid;             /* UUID corresponding to rid */
           63  +  const char *zEventId;    /* Event identifier */
           64  +  char *zETime;            /* Time of the event */
           65  +  char *zATime;            /* Time the artifact was created */
           66  +  int specRid;             /* rid specified by aid= parameter */
           67  +  int prevRid, nextRid;    /* Previous or next edits of this event */
           68  +  Manifest *pEvent;        /* Parsed event artifact */
           69  +  Blob fullbody;           /* Complete content of the event body */
           70  +  Blob title;              /* Title extracted from the event body */
           71  +  Blob tail;               /* Event body that comes after the title */
           72  +  Stmt q1;                 /* Query to search for the event */
           73  +  int showDetail;          /* True to show details */
           74  +
           75  +
           76  +  /* wiki-read privilege is needed in order to read events.
           77  +  */
           78  +  login_check_credentials();
           79  +  if( !g.okRdWiki ){
           80  +    login_needed();
           81  +    return;
           82  +  }
           83  +
           84  +  zEventId = P("name");
           85  +  if( zEventId==0 ){ fossil_redirect_home(); return; }
           86  +  zUuid = (char*)P("aid");
           87  +  specRid = zUuid ? uuid_to_rid(zUuid, 0) : 0;
           88  +  rid = nextRid = prevRid = 0;
           89  +  db_prepare(&q1,
           90  +     "SELECT rid FROM tagxref"
           91  +     " WHERE tagid=(SELECT tagid FROM tag WHERE tagname GLOB 'event-%q*')"
           92  +     " ORDER BY mtime DESC",
           93  +     zEventId
           94  +  );
           95  +  while( db_step(&q1)==SQLITE_ROW ){
           96  +    nextRid = rid;
           97  +    rid = db_column_int(&q1, 0);
           98  +    if( specRid==0 || specRid==rid ){
           99  +      if( db_step(&q1)==SQLITE_ROW ){
          100  +        prevRid = db_column_int(&q1, 0);
          101  +      }
          102  +      break;
          103  +    }
          104  +  }
          105  +  db_finalize(&q1);
          106  +  if( rid==0 || (specRid!=0 && specRid!=rid) ){
          107  +    style_header("No Such Event");
          108  +    @ Cannot locate specified event
          109  +    style_footer();
          110  +    return;
          111  +  }
          112  +  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
          113  +  showDetail = atoi(PD("detail","0"));
          114  +
          115  +  /* Extract the event content.
          116  +  */
          117  +  pEvent = manifest_get(rid, CFTYPE_EVENT);
          118  +  if( pEvent==0 ){
          119  +    fossil_panic("Object #%d is not an event", rid);
          120  +  }
          121  +  blob_init(&fullbody, pEvent->zWiki, -1);
          122  +  if( wiki_find_title(&fullbody, &title, &tail) ){
          123  +    style_header(blob_str(&title));
          124  +  }else{
          125  +    style_header("Event %S", zEventId);
          126  +    tail = fullbody;
          127  +  }
          128  +  if( g.okWrWiki && g.okWrite && nextRid==0 ){
          129  +    style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
          130  +                          g.zTop, zEventId);
          131  +  }
          132  +  zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
          133  +  style_submenu_element("Context", "Context", "%s/timeline?c=%T",
          134  +                        g.zTop, zETime);
          135  +  if( g.okHistory ){
          136  +    if( showDetail ){
          137  +      style_submenu_element("Plain", "Plain", "%s/event?name=%s&amp;aid=%s",
          138  +                            g.zTop, zEventId, zUuid);
          139  +      if( nextRid ){
          140  +        char *zNext;
          141  +        zNext = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nextRid);
          142  +        style_submenu_element("Next", "Next",
          143  +                              "%s/event?name=%s&amp;aid=%s&amp;detail=1",
          144  +                              g.zTop, zEventId, zNext);
          145  +        free(zNext);
          146  +      }
          147  +      if( prevRid ){
          148  +        char *zPrev;
          149  +        zPrev = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", prevRid);
          150  +        style_submenu_element("Prev", "Prev",
          151  +                              "%s/event?name=%s&amp;aid=%s&amp;detail=1",
          152  +                              g.zTop, zEventId, zPrev);
          153  +        free(zPrev);
          154  +      }
          155  +    }else{
          156  +      style_submenu_element("Detail", "Detail",
          157  +                            "%s/event?name=%s&amp;aid=%s&amp;detail=1",
          158  +                            g.zTop, zEventId, zUuid);
          159  +    }
          160  +  }
          161  +
          162  +  if( showDetail && g.okHistory ){
          163  +    int i;
          164  +    const char *zClr = 0;
          165  +    Blob comment;
          166  +
          167  +    zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate);
          168  +    @ <p>Event [<a href="%s(g.zTop)/artifact/%s(zUuid)">%S(zUuid)</a>] at
          169  +    @ [<a href="%s(g.zTop)/timeline?c=%T(zETime)">%s(zETime)</a>]
          170  +    @ entered by user <b>%h(pEvent->zUser)</b> on
          171  +    @ [<a href="%s(g.zTop)/timeline?c=%T(zATime)">%s(zATime)</a>]:</p>
          172  +    @ <blockquote>
          173  +    for(i=0; i<pEvent->nTag; i++){
          174  +      if( strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){
          175  +        zClr = pEvent->aTag[i].zValue;
          176  +      }
          177  +    }
          178  +    if( zClr && zClr[0]==0 ) zClr = 0;
          179  +    if( zClr ){
          180  +      @ <div style="background-color: %h(zClr);">
          181  +    }else{
          182  +      @ <div>
          183  +    }
          184  +    blob_init(&comment, pEvent->zComment, -1);
          185  +    wiki_convert(&comment, 0, WIKI_INLINE);
          186  +    blob_reset(&comment);
          187  +    @ </div>
          188  +    @ </blockquote><hr />
          189  +  }  
          190  +
          191  +  wiki_convert(&tail, 0, 0);
          192  +  style_footer();
          193  +  manifest_destroy(pEvent);
          194  +}
          195  +
          196  +/*
          197  +** WEBPAGE: eventedit
          198  +** URL: /eventedit?name=EVENTID
          199  +**
          200  +** Edit an event.  If name is omitted, create a new event.
          201  +*/
          202  +void eventedit_page(void){
          203  +  char *zTag;
          204  +  int rid = 0;
          205  +  Blob event;
          206  +  const char *zEventId;
          207  +  char *zHtmlPageName;
          208  +  int n;
          209  +  const char *z;
          210  +  char *zBody = (char*)P("w");
          211  +  char *zETime = (char*)P("t");
          212  +  const char *zComment = P("c");
          213  +  const char *zTags = P("g");
          214  +  const char *zClr;
          215  +
          216  +  if( zBody ){
          217  +    zBody = mprintf("%s", zBody);
          218  +  }
          219  +  login_check_credentials();
          220  +  zEventId = P("name");
          221  +  if( zEventId==0 ){
          222  +    zEventId = db_text(0, "SELECT lower(hex(randomblob(20)))");
          223  +  }else{
          224  +    int nEventId = strlen(zEventId);
          225  +    if( nEventId!=40 || !validate16(zEventId, 40) ){
          226  +      fossil_redirect_home();
          227  +      return;
          228  +    }
          229  +  }
          230  +  zTag = mprintf("event-%s", zEventId);
          231  +  rid = db_int(0, 
          232  +    "SELECT rid FROM tagxref"
          233  +    " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
          234  +    " ORDER BY mtime DESC", zTag
          235  +  );
          236  +  free(zTag);
          237  +
          238  +  /* Need both check-in and wiki-write or wiki-create privileges in order
          239  +  ** to edit/create an event.
          240  +  */
          241  +  if( !g.okWrite || (rid && !g.okWrWiki) || (!rid && !g.okNewWiki) ){
          242  +    login_needed();
          243  +    return;
          244  +  }
          245  +
          246  +  /* Figure out the color */
          247  +  if( rid ){
          248  +    zClr = db_text("", "SELECT bgcolor  FROM event WHERE objid=%d", rid);
          249  +  }else{
          250  +    zClr = "";
          251  +  }
          252  +  zClr = PD("clr",zClr);
          253  +  if( strcmp(zClr,"##")==0 ) zClr = PD("cclr","");
          254  +
          255  +
          256  +  /* If editing an existing event, extract the key fields to use as
          257  +  ** a starting point for the edit.
          258  +  */
          259  +  if( rid && (zBody==0 || zETime==0 || zComment==0 || zTags==0) ){
          260  +    Manifest *pEvent;
          261  +    pEvent = manifest_get(rid, CFTYPE_EVENT);
          262  +    if( pEvent && pEvent->type==CFTYPE_EVENT ){
          263  +      if( zBody==0 ) zBody = pEvent->zWiki;
          264  +      if( zETime==0 ){
          265  +        zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
          266  +      }
          267  +      if( zComment==0 ) zComment = pEvent->zComment;
          268  +    }
          269  +    if( zTags==0 ){
          270  +      zTags = db_text(0,
          271  +        "SELECT group_concat(substr(tagname,5),', ')"
          272  +        "  FROM tagxref, tag"
          273  +        " WHERE tagxref.rid=%d"
          274  +        "   AND tagxref.tagid=tag.tagid"
          275  +        "   AND tag.tagname GLOB 'sym-*'",
          276  +        rid
          277  +      );
          278  +    }
          279  +  }
          280  +  zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
          281  +  if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
          282  +    char *zDate;
          283  +    Blob cksum;
          284  +    int nrid;
          285  +    blob_zero(&event);
          286  +    db_begin_transaction();
          287  +    login_verify_csrf_secret();
          288  +    blob_appendf(&event, "C %F\n", zComment);
          289  +    zDate = db_text(0, "SELECT datetime('now')");
          290  +    zDate[10] = 'T';
          291  +    blob_appendf(&event, "D %s\n", zDate);
          292  +    free(zDate);
          293  +    zETime[10] = 'T';
          294  +    blob_appendf(&event, "E %s %s\n", zETime, zEventId);
          295  +    zETime[10] = ' ';
          296  +    if( rid ){
          297  +      char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
          298  +      blob_appendf(&event, "P %s\n", zUuid);
          299  +      free(zUuid);
          300  +    }
          301  +    if( zClr && zClr[0] ){
          302  +      blob_appendf(&event, "T +bgcolor * %F\n", zClr);
          303  +    }
          304  +    if( zTags && zTags[0] ){
          305  +      Blob tags, one;
          306  +      int i, j;
          307  +      Stmt q;
          308  +      char *zBlob;
          309  +
          310  +      /* Load the tags string into a blob */
          311  +      blob_zero(&tags);
          312  +      blob_append(&tags, zTags, -1); 
          313  +
          314  +      /* Collapse all sequences of whitespace and "," characters into
          315  +      ** a single space character */
          316  +      zBlob = blob_str(&tags);
          317  +      for(i=j=0; zBlob[i]; i++, j++){
          318  +        if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){
          319  +          while( fossil_isspace(zBlob[i+1]) ){ i++; }
          320  +          zBlob[j] = ' ';
          321  +        }else{
          322  +          zBlob[j] = zBlob[i];
          323  +        }
          324  +      }
          325  +      blob_resize(&tags, j);
          326  +
          327  +      /* Parse out each tag and load it into a temporary table for sorting */
          328  +      db_multi_exec("CREATE TEMP TABLE newtags(x);");
          329  +      while( blob_token(&tags, &one) ){
          330  +        db_multi_exec("INSERT INTO newtags VALUES(%B)", &one);
          331  +      }
          332  +      blob_reset(&tags);
          333  +
          334  +      /* Extract the tags in sorted order and make an entry in the
          335  +      ** artifact for each. */
          336  +      db_prepare(&q, "SELECT x FROM newtags ORDER BY x");
          337  +      while( db_step(&q)==SQLITE_ROW ){
          338  +        blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0));
          339  +      }
          340  +      db_finalize(&q);
          341  +    }        
          342  +    if( g.zLogin ){
          343  +      blob_appendf(&event, "U %F\n", g.zLogin);
          344  +    }
          345  +    blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody);
          346  +    md5sum_blob(&event, &cksum);
          347  +    blob_appendf(&event, "Z %b\n", &cksum);
          348  +    blob_reset(&cksum);
          349  +    nrid = content_put(&event, 0, 0);
          350  +    db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
          351  +    manifest_crosslink(nrid, &event);
          352  +    blob_reset(&event);
          353  +    content_deltify(rid, nrid, 0);
          354  +    db_end_transaction(0);
          355  +    cgi_redirectf("event?name=%T", zEventId);
          356  +  }
          357  +  if( P("cancel")!=0 ){
          358  +    cgi_redirectf("event?name=%T", zEventId);
          359  +    return;
          360  +  }
          361  +  if( zBody==0 ){
          362  +    zBody = mprintf("<i>Event Text</i>");
          363  +  }
          364  +  zHtmlPageName = mprintf("Edit Event %S", zEventId);
          365  +  style_header(zHtmlPageName);
          366  +  if( P("preview")!=0 ){
          367  +    Blob title, tail, com;
          368  +    @ <p><b>Timeline comment preview:</b></p>
          369  +    @ <blockquote>
          370  +    @ <table border="0">
          371  +    if( zClr && zClr[0] ){
          372  +      @ <tr><td style="background-color: %h(zClr);">
          373  +    }else{
          374  +      @ <tr><td>
          375  +    }
          376  +    blob_zero(&com);
          377  +    blob_append(&com, zComment, -1);
          378  +    wiki_convert(&com, 0, WIKI_INLINE);
          379  +    @ </td></tr></table>
          380  +    @ </blockquote>
          381  +    @ <p><b>Page content preview:</b><p>
          382  +    @ <blockquote>
          383  +    blob_zero(&event);
          384  +    blob_append(&event, zBody, -1);
          385  +    if( wiki_find_title(&event, &title, &tail) ){
          386  +      @ <h2 align="center">%h(blob_str(&title))</h2>
          387  +      wiki_convert(&tail, 0, 0);
          388  +    }else{
          389  +      wiki_convert(&event, 0, 0);
          390  +    }
          391  +    @ </blockquote><hr />
          392  +    blob_reset(&event);
          393  +  }
          394  +  for(n=2, z=zBody; z[0]; z++){
          395  +    if( z[0]=='\n' ) n++;
          396  +  }
          397  +  if( n<20 ) n = 20;
          398  +  if( n>40 ) n = 40;
          399  +  @ <form method="post" action="%s(g.zBaseURL)/eventedit"><div>
          400  +  login_insert_csrf_secret();
          401  +  @ <input type="hidden" name="name" value="%h(zEventId)" />
          402  +  @ <table border="0" cellspacing="10">
          403  +
          404  +  @ <tr><td align="right" valign="top"><b>Event&nbsp;Time:</b></td>
          405  +  @ <td valign="top">
          406  +  @   <input type="text" name="t" size="25" value="%h(zETime)" />
          407  +  @ </td></tr>
          408  +
          409  +  @ <tr><td align="right" valign="top"><b>Timeline&nbsp;Comment:</b></td>
          410  +  @ <td valign="top">
          411  +  @ <textarea name="c" class="eventedit" cols="80" 
          412  +  @  rows="3" wrap="virtual">%h(zComment)</textarea>
          413  +  @ </td></tr>
          414  +
          415  +  @ <tr><td align="right" valign="top"><b>Background&nbsp;Color:</b></td>
          416  +  @ <td valign="top">
          417  +  render_color_chooser(0, zClr, 0, "clr", "cclr");
          418  +  @ </td></tr>
          419  +  
          420  +  @ <tr><td align="right" valign="top"><b>Tags:</b></td>
          421  +  @ <td valign="top">
          422  +  @   <input type="text" name="g" size="40" value="%h(zTags)" />
          423  +  @ </td></tr>
          424  +  
          425  +  @ <tr><td align="right" valign="top"><b>Page&nbsp;Content:</b></td>
          426  +  @ <td valign="top">
          427  +  @ <textarea name="w" class="eventedit" cols="80" 
          428  +  @  rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
          429  +  @ </td></tr>
          430  +
          431  +  @ <tr><td colspan="2">
          432  +  @ <input type="submit" name="preview" value="Preview Your Changes" />
          433  +  @ <input type="submit" name="submit" value="Apply These Changes" />
          434  +  @ <input type="submit" name="cancel" value="Cancel" />
          435  +  @ </td></tr></table>
          436  +  @ </div></form>
          437  +  style_footer();
          438  +}

Changes to src/file.c.

    21     21   #include <sys/types.h>
    22     22   #include <sys/stat.h>
    23     23   #include <unistd.h>
    24     24   #include "file.h"
    25     25   
    26     26   /*
    27     27   ** The file status information from the most recent stat() call.
           28  +**
           29  +** Use _stati64 rather than stat on windows, in order to handle files
           30  +** larger than 2GB.
    28     31   */
    29         -static struct stat fileStat;
           32  +#if defined(_WIN32) && defined(__MSVCRT__)
           33  +  static struct _stati64 fileStat;
           34  +# define stat _stati64
           35  +#else
           36  +  static struct stat fileStat;
           37  +#endif
    30     38   static int fileStatValid = 0;
    31     39   
    32     40   /*
    33     41   ** Fill in the fileStat variable for the file named zFilename.
    34     42   ** If zFilename==0, then use the previous value of fileStat if
    35     43   ** there is a previous value.
    36     44   **
................................................................................
    81     89   
    82     90   /*
    83     91   ** Return TRUE if the named file is an executable.  Return false
    84     92   ** for directories, devices, fifos, symlinks, etc.
    85     93   */
    86     94   int file_isexe(const char *zFilename){
    87     95     if( getStat(zFilename) || !S_ISREG(fileStat.st_mode) ) return 0;
    88         -#ifdef __MINGW32__
           96  +#if defined(_WIN32)
           97  +#  if defined(__DMC__) || defined(_MSC_VER)
           98  +#    define S_IXUSR  _S_IEXEC
           99  +#  endif
    89    100     return ((S_IXUSR)&fileStat.st_mode)!=0;
    90    101   #else
    91    102     return ((S_IXUSR|S_IXGRP|S_IXOTH)&fileStat.st_mode)!=0;
    92    103   #endif
    93    104   }
    94    105   
    95    106   
................................................................................
   143    154     fclose(out);
   144    155   }
   145    156   
   146    157   /*
   147    158   ** Set or clear the execute bit on a file.
   148    159   */
   149    160   void file_setexe(const char *zFilename, int onoff){
   150         -#ifndef __MINGW32__
          161  +#if !defined(_WIN32)
   151    162     struct stat buf;
   152    163     if( stat(zFilename, &buf)!=0 ) return;
   153    164     if( onoff ){
   154    165       if( (buf.st_mode & 0111)!=0111 ){
   155    166         chmod(zFilename, buf.st_mode | 0111);
   156    167       }
   157    168     }else{
   158    169       if( (buf.st_mode & 0111)!=0 ){
   159    170         chmod(zFilename, buf.st_mode & ~0111);
   160    171       }
   161    172     }
   162         -#endif /* __MINGW32__ */
          173  +#endif /* _WIN32 */
   163    174   }
   164    175   
   165    176   /*
   166    177   ** Create the directory named in the argument, if it does not already
   167    178   ** exist.  If forceFlag is 1, delete any prior non-directory object 
   168    179   ** with the same name.
   169    180   **
................................................................................
   172    183   int file_mkdir(const char *zName, int forceFlag){
   173    184     int rc = file_isdir(zName);
   174    185     if( rc==2 ){
   175    186       if( !forceFlag ) return 1;
   176    187       unlink(zName);
   177    188     }
   178    189     if( rc!=1 ){
   179         -#ifdef __MINGW32__
          190  +#if defined(_WIN32)
   180    191       return mkdir(zName);
   181    192   #else
   182    193       return mkdir(zName, 0755);
   183    194   #endif
   184    195     }
   185    196     return 0;
   186    197   }
................................................................................
   229    240   **  * removing /A/../
   230    241   **
   231    242   ** Changes are made in-place.  Return the new name length.
   232    243   */
   233    244   int file_simplify_name(char *z, int n){
   234    245     int i, j;
   235    246     if( n<0 ) n = strlen(z);
   236         -#ifdef __MINGW32__
          247  +#if defined(_WIN32)
   237    248     for(i=0; i<n; i++){
   238    249       if( z[i]=='\\' ) z[i] = '/';
   239    250     }
   240    251   #endif
   241    252     while( n>1 && z[n-1]=='/' ){ n--; }
   242    253     for(i=j=0; i<n; i++){
   243    254       if( z[i]=='/' ){
................................................................................
   264    275   ** Make the name absolute if it is relative.
   265    276   ** Remove redundant / characters
   266    277   ** Remove all /./ path elements.
   267    278   ** Convert /A/../ to just /
   268    279   */
   269    280   void file_canonical_name(const char *zOrigName, Blob *pOut){
   270    281     if( zOrigName[0]=='/' 
   271         -#ifdef __MINGW32__
          282  +#if defined(_WIN32)
   272    283         || zOrigName[0]=='\\'
   273    284         || (strlen(zOrigName)>3 && zOrigName[1]==':'
   274    285              && (zOrigName[2]=='\\' || zOrigName[2]=='/'))
   275    286   #endif
   276    287     ){
   277    288       blob_set(pOut, zOrigName);
   278    289       blob_materialize(pOut);
................................................................................
   286    297       blob_appendf(pOut, "%//%/", zPwd, zOrigName);
   287    298     }
   288    299     blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut)));
   289    300   }
   290    301   
   291    302   /*
   292    303   ** COMMAND:  test-canonical-name
          304  +** Usage: %fossil test-canonical-name FILENAME...
   293    305   **
   294    306   ** Test the operation of the canonical name generator.
          307  +** Also test Fossil's ability to measure attributes of a file.
   295    308   */
   296    309   void cmd_test_canonical_name(void){
   297    310     int i;
   298    311     Blob x;
   299    312     blob_zero(&x);
   300    313     for(i=2; i<g.argc; i++){
   301         -    file_canonical_name(g.argv[i], &x);
          314  +    const char *zName = g.argv[i];
          315  +    file_canonical_name(zName, &x);
   302    316       printf("%s\n", blob_buffer(&x));
   303    317       blob_reset(&x);
          318  +    printf("  file_size   = %lld\n", file_size(zName));
          319  +    printf("  file_mtime  = %lld\n", file_mtime(zName));
          320  +    printf("  file_isfile = %d\n", file_isfile(zName));
          321  +    printf("  file_isexe  = %d\n", file_isexe(zName));
          322  +    printf("  file_isdir  = %d\n", file_isdir(zName));
   304    323     }
   305    324   }
   306    325   
   307    326   /*
   308    327   ** Return TRUE if the given filename is canonical.
   309    328   **
   310    329   ** Canonical names are full pathnames using "/" not "\" and which
   311    330   ** contain no "/./" or "/../" terms.
   312    331   */
   313    332   int file_is_canonical(const char *z){
   314    333     int i;
   315    334     if( z[0]!='/'
   316         -#ifdef __MINGW32__
          335  +#if defined(_WIN32)
   317    336       && (z[0]==0 || z[1]!=':' || z[2]!='/')
   318    337   #endif
   319    338     ) return 0;
   320    339   
   321    340     for(i=0; z[i]; i++){
   322    341       if( z[i]=='\\' ) return 0;
   323    342       if( z[i]=='/' ){

Changes to src/finfo.c.

   129    129       "   AND event.objid=mlink.mid"
   130    130       " ORDER BY event.mtime DESC /*sort*/",
   131    131       TAG_BRANCH,
   132    132       zFilename
   133    133     );
   134    134     blob_zero(&title);
   135    135     blob_appendf(&title, "History of ");
   136         -  hyperlinked_path(zFilename, &title);
          136  +  hyperlinked_path(zFilename, &title, 0);
   137    137     @ <h2>%b(&title)</h2>
   138    138     blob_reset(&title);
   139    139     pGraph = graph_init();
   140    140     @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
   141         -  @ <table cellspacing=0 border=0 cellpadding=0>
          141  +  @ <table class="timelineTable">
   142    142     while( db_step(&q)==SQLITE_ROW ){
   143    143       const char *zDate = db_column_text(&q, 0);
   144    144       const char *zCom = db_column_text(&q, 1);
   145    145       const char *zUser = db_column_text(&q, 2);
   146    146       int fpid = db_column_int(&q, 3);
   147    147       int frid = db_column_int(&q, 4);
   148    148       const char *zPUuid = db_column_text(&q, 5);
................................................................................
   155    155       char zShort[20];
   156    156       char zShortCkin[20];
   157    157       if( zBr==0 ) zBr = "trunk";
   158    158       gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr);
   159    159       if( memcmp(zDate, zPrevDate, 10) ){
   160    160         sprintf(zPrevDate, "%.10s", zDate);
   161    161         @ <tr><td>
   162         -      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
          162  +      @   <div class="divider">%s(zPrevDate)</div>
   163    163         @ </td></tr>
   164    164       }
   165    165       memcpy(zTime, &zDate[11], 5);
   166    166       zTime[5] = 0;
   167         -    @ <tr><td valign="top" align="right">
          167  +    @ <tr><td class="timelineTime">
   168    168       @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td>
   169         -    @ <td width="20" align="left" valign="top"><div id="m%d(gidx)"></div></td>
          169  +    @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td>
   170    170       if( zBgClr && zBgClr[0] ){
   171         -      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
          171  +      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
   172    172       }else{
   173         -      @ <td valign="top" align="left">
          173  +      @ <td class="timelineTableCell">
   174    174       }
   175    175       sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
   176    176       sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
   177    177       if( zUuid ){
   178    178         if( g.okHistory ){
   179    179           @ <a href="%s(g.zTop)/artifact/%s(zUuid)">[%S(zUuid)]</a>
   180    180         }else{
................................................................................
   185    185         @ <b>Deleted</b> by check-in
   186    186       }
   187    187       hyperlink_to_uuid(zShortCkin);
   188    188       @ %h(zCom) (user: 
   189    189       hyperlink_to_user(zUser, zDate, "");
   190    190       @ branch: %h(zBr))
   191    191       if( g.okHistory && zUuid ){
          192  +      const char *z = zFilename;
   192    193         if( fpid ){
   193    194           @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&amp;v2=%s(zUuid)">[diff]</a>
   194    195         }
   195         -      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(zFilename)">
          196  +      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(z)">
   196    197         @ [annotate]</a>
   197    198       }
   198         -    @ </td>
          199  +    @ </td></tr>
   199    200     }
   200    201     db_finalize(&q);
   201    202     if( pGraph ){
   202    203       graph_finish(pGraph, 1);
   203    204       if( pGraph->nErr ){
   204    205         graph_free(pGraph);
   205    206         pGraph = 0;
   206    207       }else{
   207         -      @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
          208  +      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
          209  +      @     </td></tr>
   208    210       }
   209    211     }
   210    212     @ </table>
   211    213     timeline_output_graph_javascript(pGraph);
   212    214     style_footer();
   213    215   }

Changes to src/graph.c.

    19     19   */
    20     20   #include "config.h"
    21     21   #include "graph.h"
    22     22   #include <assert.h>
    23     23   
    24     24   #if INTERFACE
    25     25   
    26         -#define GR_MAX_PARENT 10
    27         -#define GR_MAX_RAIL   32
           26  +#define GR_MAX_PARENT 10      /* Most parents for any one node */
           27  +#define GR_MAX_RAIL   32      /* Max number of "rails" to display */
    28     28   
    29     29   /* The graph appears vertically beside a timeline.  Each row in the
    30     30   ** timeline corresponds to a row in the graph.
    31     31   */
    32     32   struct GraphRow {
    33     33     int rid;                    /* The rid for the check-in */
    34     34     int nParent;                /* Number of parents */
................................................................................
    36     36     char *zBranch;              /* Branch name */
    37     37     char *zBgClr;               /* Background Color */
    38     38   
    39     39     GraphRow *pNext;            /* Next row down in the list of all rows */
    40     40     GraphRow *pPrev;            /* Previous row */
    41     41     
    42     42     int idx;                    /* Row index.  First is 1.  0 used for "none" */
    43         -  u8 isLeaf;                  /* True if no direct child nodes */
           43  +  int idxTop;                 /* Direct descendent highest up on the graph */
           44  +  GraphRow *pChild;           /* Child immediately above this node */
    44     45     u8 isDup;                   /* True if this is duplicate of a prior entry */
    45     46     int iRail;                  /* Which rail this check-in appears on. 0-based.*/
    46     47     int aiRaiser[GR_MAX_RAIL];  /* Raisers from this node to a higher row. */
    47     48     int bDescender;             /* Raiser from bottom of graph to here. */
    48     49     u32 mergeIn;                /* Merge in from other rails */
    49     50     int mergeOut;               /* Merge out to this rail */
    50     51     int mergeUpto;              /* Draw the merge rail up to this level */
................................................................................
    51     52   
    52     53     u32 railInUse;              /* Mask of occupied rails */
    53     54   };
    54     55   
    55     56   /* Context while building a graph
    56     57   */
    57     58   struct GraphContext {
    58         -  int nErr;             /* Number of errors encountered */
    59         -  int mxRail;           /* Number of rails required to render the graph */
    60         -  GraphRow *pFirst;     /* First row in the list */
    61         -  GraphRow *pLast;      /* Last row in the list */
    62         -  int nBranch;          /* Number of distinct branches */
    63         -  char **azBranch;      /* Names of the branches */
           59  +  int nErr;                  /* Number of errors encountered */
           60  +  int mxRail;                /* Number of rails required to render the graph */
           61  +  GraphRow *pFirst;          /* First row in the list */
           62  +  GraphRow *pLast;           /* Last row in the list */
           63  +  int nBranch;               /* Number of distinct branches */
           64  +  char **azBranch;           /* Names of the branches */
    64     65     int nRow;                  /* Number of rows */
    65         -  int railMap[GR_MAX_RAIL];  /* Rail order mapping */
    66     66     int nHash;                 /* Number of slots in apHash[] */
    67         -  GraphRow **apHash;         /* Hash table of rows */
           67  +  GraphRow **apHash;         /* Hash table of GraphRow objects.  Key: rid */
    68     68   };
    69     69   
    70     70   #endif
    71     71   
    72     72   /*
    73     73   ** Malloc for zeroed space.  Panic if unable to provide the
    74     74   ** requested space.
    75     75   */
    76     76   void *safeMalloc(int nByte){
    77         -  void *p = malloc(nByte);
    78         -  if( p==0 ) fossil_panic("out of memory");
           77  +  void *p = fossil_malloc(nByte);
    79     78     memset(p, 0, nByte);
    80     79     return p;
    81     80   }
    82     81   
    83     82   /*
    84     83   ** Create and initialize a GraphContext
    85     84   */
................................................................................
   101    100     for(i=0; i<p->nBranch; i++) free(p->azBranch[i]);
   102    101     free(p->azBranch);
   103    102     free(p->apHash);
   104    103     free(p);
   105    104   }
   106    105   
   107    106   /*
   108         -** Insert a row into the hash table.  If there is already another
   109         -** row with the same rid, overwrite the prior entry if the overwrite
   110         -** flag is set.
          107  +** Insert a row into the hash table.  pRow->rid is the key.  Keys must
          108  +** be unique.  If there is already another row with the same rid,
          109  +** overwrite the prior entry if and only if the overwrite flag is set.
   111    110   */
   112    111   static void hashInsert(GraphContext *p, GraphRow *pRow, int overwrite){
   113    112     int h;
   114    113     h = pRow->rid % p->nHash;
   115    114     while( p->apHash[h] && p->apHash[h]->rid!=pRow->rid ){
   116    115       h++;
   117    116       if( h>=p->nHash ) h = 0;
................................................................................
   133    132     return p->apHash[h];
   134    133   }
   135    134   
   136    135   /*
   137    136   ** Return the canonical pointer for a given branch name.
   138    137   ** Multiple calls to this routine with equivalent strings
   139    138   ** will return the same pointer.
          139  +**
          140  +** The returned value is a pointer to a (readonly) string that
          141  +** has the useful property that strings can be checked for 
          142  +** equality by comparing pointers.
   140    143   **
   141    144   ** Note: also used for background color names.
   142    145   */
   143    146   static char *persistBranchName(GraphContext *p, const char *zBranch){
   144    147     int i;
   145    148     for(i=0; i<p->nBranch; i++){
   146    149       if( strcmp(zBranch, p->azBranch[i])==0 ) return p->azBranch[i];
   147    150     }
   148    151     p->nBranch++;
   149         -  p->azBranch = realloc(p->azBranch, sizeof(char*)*p->nBranch);
   150         -  if( p->azBranch==0 ) fossil_panic("out of memory");
          152  +  p->azBranch = fossil_realloc(p->azBranch, sizeof(char*)*p->nBranch);
   151    153     p->azBranch[p->nBranch-1] = mprintf("%s", zBranch);
   152    154     return p->azBranch[p->nBranch-1];
   153    155   }
   154    156   
   155    157   /*
   156         -** Add a new row t the graph context.  Rows are added from top to bottom.
          158  +** Add a new row to the graph context.  Rows are added from top to bottom.
   157    159   */
   158    160   int graph_add_row(
   159    161     GraphContext *p,     /* The context to which the row is added */
   160    162     int rid,             /* RID for the check-in */
   161    163     int nParent,         /* Number of parents */
   162    164     int *aParent,        /* Array of parents */
   163    165     const char *zBranch, /* Branch for this check-in */
................................................................................
   177    179     if( p->pFirst==0 ){
   178    180       p->pFirst = pRow;
   179    181     }else{
   180    182       p->pLast->pNext = pRow;
   181    183     }
   182    184     p->pLast = pRow;
   183    185     p->nRow++;
   184         -  pRow->idx = p->nRow;
          186  +  pRow->idx = pRow->idxTop = p->nRow;
   185    187     return pRow->idx;
   186    188   }
   187    189   
   188    190   /*
   189    191   ** Return the index of a rail currently not in use for any row between
   190    192   ** top and bottom, inclusive.  
   191    193   */
................................................................................
   217    219           iBest = i;
   218    220         }
   219    221       }
   220    222     }
   221    223     if( iBestDist>1000 ) p->nErr++;
   222    224     return iBest;
   223    225   }
          226  +
          227  +/*
          228  +** Assign all children of node pBottom to the same rail as pBottom.
          229  +*/
          230  +static void assignChildrenToRail(GraphRow *pBottom){
          231  +  int iRail = pBottom->iRail;
          232  +  GraphRow *pCurrent;
          233  +  GraphRow *pPrior;
          234  +  u32 mask = 1<<iRail;
          235  +
          236  +  pBottom->iRail = iRail;
          237  +  pBottom->railInUse |= mask;
          238  +  pPrior = pBottom;
          239  +  for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
          240  +    assert( pPrior->idx > pCurrent->idx );
          241  +    assert( pCurrent->iRail<0 );
          242  +    pCurrent->iRail = iRail;
          243  +    pCurrent->railInUse |= mask;
          244  +    pPrior->aiRaiser[iRail] = pCurrent->idx;
          245  +    while( pPrior->idx > pCurrent->idx ){
          246  +      pPrior->railInUse |= mask;
          247  +      pPrior = pPrior->pPrev;
          248  +      assert( pPrior!=0 );
          249  +    }
          250  +    if( pCurrent->pPrev ){
          251  +      pCurrent->pPrev->railInUse |= mask;
          252  +    }
          253  +  }
          254  +}
          255  +
   224    256   
   225    257   /*
   226    258   ** Compute the complete graph
   227    259   */
   228    260   void graph_finish(GraphContext *p, int omitDescenders){
   229         -  GraphRow *pRow, *pDesc, *pDup, *pLoop;
          261  +  GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
   230    262     int i;
   231    263     u32 mask;
   232    264     u32 inUse;
   233    265     int hasDup = 0;    /* True if one or more isDup entries */
   234    266     const char *zTrunk;
   235    267   
   236    268     if( p==0 || p->pFirst==0 || p->nErr ) return;
................................................................................
   246    278         hasDup = 1;
   247    279         pDup->isDup = 1;
   248    280       }
   249    281       hashInsert(p, pRow, 1);
   250    282     }
   251    283     p->mxRail = -1;
   252    284   
   253         -  /* Purge merge-parents that are out-of-graph
          285  +  /* Purge merge-parents that are out-of-graph.
          286  +  **
          287  +  ** Each node has one primary parent and zero or more "merge" parents.
          288  +  ** A merge parent is a prior checkin from which changes were merged into
          289  +  ** the current check-in.  If a merge parent is not in the visible section
          290  +  ** of this graph, then no arrows will be drawn for it, so remove it from
          291  +  ** the aParent[] array.
   254    292     */
   255    293     for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
   256    294       for(i=1; i<pRow->nParent; i++){
   257    295         if( hashFind(p, pRow->aParent[i])==0 ){
   258    296           pRow->aParent[i] = pRow->aParent[--pRow->nParent];
   259    297           i--;
   260    298         }
   261    299       }
   262    300     }
   263    301   
   264         -  /* Figure out which nodes have no direct children (children on
   265         -  ** the same rail).  Mark such nodes as isLeaf.
          302  +  /* Find the pChild pointer for each node. 
          303  +  **
          304  +  ** The pChild points to node directly above on the same rail.
          305  +  ** The pChild must be in the same branch.  Leaf nodes have a NULL
          306  +  ** pChild.
          307  +  **
          308  +  ** In the case of a fork, choose the pChild that results in the
          309  +  ** longest rail.
   266    310     */
   267         -  memset(p->apHash, 0, sizeof(p->apHash[0])*p->nHash);
   268         -  for(pRow=p->pLast; pRow; pRow=pRow->pPrev) pRow->isLeaf = 1;
   269         -  for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
   270         -    GraphRow *pParent;
   271         -    hashInsert(p, pRow, 0);
   272         -    if( !pRow->isDup
   273         -     && pRow->nParent>0 
   274         -     && (pParent = hashFind(p, pRow->aParent[0]))!=0
   275         -     && pRow->zBranch==pParent->zBranch
   276         -    ){
   277         -      pParent->isLeaf = 0;
          311  +  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
          312  +    if( pRow->isDup ) continue;
          313  +    if( pRow->nParent==0 ) continue;
          314  +    pParent = hashFind(p, pRow->aParent[0]);
          315  +    if( pParent==0 ) continue;
          316  +    if( pParent->zBranch!=pRow->zBranch ) continue;
          317  +    if( pParent->idx <= pRow->idx ) continue;
          318  +    if( pRow->idxTop < pParent->idxTop ){
          319  +      pParent->pChild = pRow;
          320  +      pParent->idxTop = pRow->idxTop;
   278    321       }
   279    322     }
   280    323   
   281    324     /* Identify rows where the primary parent is off screen.  Assign
   282    325     ** each to a rail and draw descenders to the bottom of the screen.
          326  +  **
          327  +  ** Strive to put the "trunk" branch on far left.
   283    328     */
   284    329     zTrunk = persistBranchName(p, "trunk");
   285    330     for(i=0; i<2; i++){
   286         -    for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
          331  +    for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
   287    332         if( i==0 ){
   288    333           if( pRow->zBranch!=zTrunk ) continue;
   289    334         }else {
   290    335           if( pRow->iRail>=0 ) continue;
   291    336         }
   292    337         if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
   293    338           if( omitDescenders ){
   294         -          pRow->iRail = findFreeRail(p, pRow->idx, pRow->idx, 0, 0);
          339  +          pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx, 0, 0);
   295    340           }else{
   296    341             pRow->iRail = ++p->mxRail;
   297    342           }
   298    343           mask = 1<<(pRow->iRail);
   299    344           if( omitDescenders ){
   300    345             if( pRow->pNext ) pRow->pNext->railInUse |= mask;
   301         -          for(pDesc=pRow; pDesc; pDesc=pDesc->pPrev){
   302         -            pDesc->railInUse |= mask;
   303         -            if( pDesc->zBranch==pRow->zBranch && pDesc->isLeaf ) break;
   304         -          }
   305    346           }else{
   306    347             pRow->bDescender = pRow->nParent>0;
   307         -          for(pDesc=pRow; pDesc; pDesc=pDesc->pNext){
   308         -            pDesc->railInUse |= mask;
          348  +          for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
          349  +            pLoop->railInUse |= mask;
   309    350             }
   310    351           }
          352  +        assignChildrenToRail(pRow);
   311    353         }
   312    354       }
   313    355     }
   314    356   
   315    357     /* Assign rails to all rows that are still unassigned.
   316         -  ** The first primary child of a row goes on the same rail as
   317         -  ** that row.
   318    358     */
   319    359     inUse = (1<<(p->mxRail+1))-1;
   320    360     for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
   321    361       int parentRid;
   322         -    if( pRow->iRail>=0 ) continue;
          362  +
          363  +    if( pRow->iRail>=0 ){
          364  +      if( pRow->pChild==0 ) inUse &= ~(1<<pRow->iRail);
          365  +      continue;
          366  +    }
   323    367       if( pRow->isDup ){
   324    368         pRow->iRail = findFreeRail(p, pRow->idx, pRow->idx, inUse, 0);
   325    369         pDesc = pRow;
          370  +      pParent = 0;
   326    371       }else{
   327    372         assert( pRow->nParent>0 );
   328    373         parentRid = pRow->aParent[0];
   329         -      pDesc = hashFind(p, parentRid);
   330         -      if( pDesc==0 ){
          374  +      pParent = hashFind(p, parentRid);
          375  +      if( pParent==0 ){
   331    376           /* Time skew */
   332    377           pRow->iRail = ++p->mxRail;
   333    378           pRow->railInUse = 1<<pRow->iRail;
   334    379           continue;
   335    380         }
   336         -      if( pDesc->aiRaiser[pDesc->iRail]==0 && pDesc->zBranch==pRow->zBranch ){
   337         -        pRow->iRail = pDesc->iRail;
   338         -      }else{
   339         -        pRow->iRail = findFreeRail(p, 0, pDesc->idx, inUse, pDesc->iRail);
   340         -      }
   341         -      pDesc->aiRaiser[pRow->iRail] = pRow->idx;
          381  +      pRow->iRail = findFreeRail(p, 0, pParent->idx, inUse, pParent->iRail);
          382  +      pParent->aiRaiser[pRow->iRail] = pRow->idx;
   342    383       }
   343    384       mask = 1<<pRow->iRail;
   344         -    if( pRow->isLeaf ){
          385  +    if( pRow->pPrev ) pRow->pPrev->railInUse |= mask;
          386  +    if( pRow->pNext ) pRow->pNext->railInUse |= mask;
          387  +    if( pRow->pChild==0 ){
   345    388         inUse &= ~mask;
   346    389       }else{
   347    390         inUse |= mask;
          391  +      assignChildrenToRail(pRow);
   348    392       }
   349         -    for(pLoop=pRow; pLoop && pLoop!=pDesc; pLoop=pLoop->pNext){
   350         -      pLoop->railInUse |= mask;
          393  +    if( pParent ){
          394  +      for(pLoop=pParent; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
          395  +        pLoop->railInUse |= mask;
          396  +      }
   351    397       }
   352         -    pDesc->railInUse |= mask;
   353    398     }
   354    399   
   355    400     /*
   356    401     ** Insert merge rails and merge arrows
   357    402     */
   358    403     for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
   359    404       for(i=1; i<pRow->nParent; i++){
................................................................................
   362    407         if( pDesc==0 ) continue;
   363    408         if( pDesc->mergeOut<0 ){
   364    409           int iTarget = (pRow->iRail + pDesc->iRail)/2;
   365    410           pDesc->mergeOut = findFreeRail(p, pRow->idx, pDesc->idx, 0, iTarget);
   366    411           pDesc->mergeUpto = pRow->idx;
   367    412           mask = 1<<pDesc->mergeOut;
   368    413           pDesc->railInUse |= mask;
   369         -        for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid;
   370         -             pDesc=pDesc->pNext){
   371         -          pDesc->railInUse |= mask;
          414  +        for(pLoop=pRow->pNext; pLoop && pLoop->rid!=parentRid;
          415  +             pLoop=pLoop->pNext){
          416  +          pLoop->railInUse |= mask;
   372    417           }
   373    418         }
   374    419         pRow->mergeIn |= 1<<pDesc->mergeOut;
   375    420       }
   376    421     }
   377    422   
   378    423     /*
................................................................................
   396    441         pRow->mergeIn |= 1<<pDesc->mergeOut;
   397    442       }
   398    443     }
   399    444   
   400    445     /*
   401    446     ** Find the maximum rail number.
   402    447     */
   403         -  for(i=0; i<GR_MAX_RAIL; i++) p->railMap[i] = i;
   404    448     p->mxRail = 0;
   405    449     for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
   406    450       if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
   407    451       if( pRow->mergeOut>p->mxRail ) p->mxRail = pRow->mergeOut;
   408    452     }
   409    453   }

Changes to src/http.c.

    40     40     Blob pw;             /* The nonce with user password appended */
    41     41     Blob sig;            /* The signature field */
    42     42   
    43     43     blob_zero(pLogin);
    44     44     if( g.urlUser==0 || strcmp(g.urlUser, "anonymous")==0 ){
    45     45        return;  /* If no login card for users "nobody" and "anonymous" */
    46     46     }
           47  +  if( g.urlIsSsh ){
           48  +     return;  /* If no login card for SSH: */
           49  +  }
    47     50     blob_zero(&nonce);
    48     51     blob_zero(&pw);
    49     52     sha1sum_blob(pPayload, &nonce);
    50     53     blob_copy(&pw, &nonce);
    51     54     zLogin = g.urlUser;
    52     55     if( g.urlPasswd ){
    53     56       zPw = g.urlPasswd;
................................................................................
    55     58       /* Password failure while doing a sync from the web interface */
    56     59       cgi_printf("*** incorrect or missing password for user %h\n", zLogin);
    57     60       zPw = 0;
    58     61     }else{
    59     62       /* Password failure while doing a sync from the command-line interface */
    60     63       url_prompt_for_password();
    61     64       zPw = g.urlPasswd;
    62         -    if( !g.dontKeepUrl ) db_set("last-sync-pw", zPw, 0);
           65  +    if( !g.dontKeepUrl ) db_set("last-sync-pw", obscure(zPw), 0);
    63     66     }
    64     67   
    65     68     /* The login card wants the SHA1 hash of the password, so convert the
    66     69     ** password to its SHA1 hash it it isn't already a SHA1 hash.
    67     70     **
    68     71     ** Except, if the password begins with "*" then use the characters
    69     72     ** after the "*" as a cleartext password.  Put an "*" at the beginning
................................................................................
    98    101     blob_zero(pHdr);
    99    102     i = strlen(g.urlPath);
   100    103     if( i>0 && g.urlPath[i-1]=='/' ){
   101    104       zSep = "";
   102    105     }else{
   103    106       zSep = "/";
   104    107     }
   105         -  blob_appendf(pHdr, "POST %s%sxfer HTTP/1.0\r\n", g.urlPath, zSep);
          108  +  blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep);
   106    109     if( g.urlProxyAuth ){
   107    110       blob_appendf(pHdr, "Proxy-Authorization: %s\n", g.urlProxyAuth);
   108    111     }
   109    112     blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
   110    113     blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n");
   111    114     if( g.fHttpTrace ){
   112    115       blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
................................................................................
   132    135     Blob hdr;             /* The HTTP request header */
   133    136     int closeConnection;  /* True to close the connection when done */
   134    137     int iLength;          /* Length of the reply payload */
   135    138     int rc;               /* Result code */
   136    139     int iHttpVersion;     /* Which version of HTTP protocol server uses */
   137    140     char *zLine;          /* A single line of the reply header */
   138    141     int i;                /* Loop counter */
          142  +  int isError = 0;      /* True if the reply is an error message */
   139    143   
   140    144     if( transport_open() ){
   141    145       fossil_fatal(transport_errmsg());
   142    146     }
   143    147   
   144    148     /* Construct the login card and prepare the complete payload */
   145    149     blob_zero(&login);
................................................................................
   188    192     
   189    193     /*
   190    194     ** Read and interpret the server reply
   191    195     */
   192    196     closeConnection = 1;
   193    197     iLength = -1;
   194    198     while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){
          199  +    /* printf("[%s]\n", zLine); fflush(stdout); */
   195    200       if( strncasecmp(zLine, "http/1.", 7)==0 ){
   196    201         if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
   197    202         if( rc!=200 && rc!=302 ){
   198    203           int ii;
   199    204           for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
   200    205           while( zLine[ii]==' ' ) ii++;
   201    206           fossil_fatal("server says: %s\n", &zLine[ii]);
................................................................................
   203    208         }
   204    209         if( iHttpVersion==0 ){
   205    210           closeConnection = 1;
   206    211         }else{
   207    212           closeConnection = 0;
   208    213         }
   209    214       }else if( strncasecmp(zLine, "content-length:", 15)==0 ){
   210         -      for(i=15; isspace(zLine[i]); i++){}
          215  +      for(i=15; fossil_isspace(zLine[i]); i++){}
   211    216         iLength = atoi(&zLine[i]);
   212    217       }else if( strncasecmp(zLine, "connection:", 11)==0 ){
   213    218         char c;
   214         -      for(i=11; isspace(zLine[i]); i++){}
          219  +      for(i=11; fossil_isspace(zLine[i]); i++){}
   215    220         c = zLine[i];
   216    221         if( c=='c' || c=='C' ){
   217    222           closeConnection = 1;
   218    223         }else if( c=='k' || c=='K' ){
   219    224           closeConnection = 0;
   220    225         }
   221    226       }else if( rc==302 && strncasecmp(zLine, "location:", 9)==0 ){
   222    227         int i, j;
   223    228         for(i=9; zLine[i] && zLine[i]==' '; i++){}
   224    229         if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine);
   225    230         j = strlen(zLine) - 1; 
   226         -      if( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ) zLine[j-4] = 0;
          231  +      while( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ){
          232  +         j -= 4;
          233  +         zLine[j] = 0;
          234  +      }
   227    235         fossil_print("redirect to %s\n", &zLine[i]);
   228    236         url_parse(&zLine[i]);
   229    237         transport_close();
   230    238         http_exchange(pSend, pReply, useLogin);
   231    239         return;
          240  +    }else if( strncasecmp(zLine, "content-type: text/html", 23)==0 ){
          241  +      isError = 1;
   232    242       }
   233    243     }
   234    244     if( rc!=200 ){
   235    245       fossil_fatal("\"location:\" missing from 302 redirect reply");
   236    246       goto write_err;
   237    247     }
   238    248   
................................................................................
   243    253       fossil_fatal("server did not reply");
   244    254       goto write_err;
   245    255     }
   246    256     blob_zero(pReply);
   247    257     blob_resize(pReply, iLength);
   248    258     iLength = transport_receive(blob_buffer(pReply), iLength);
   249    259     blob_resize(pReply, iLength);
          260  +  if( isError ){
          261  +    char *z;
          262  +    int i, j;
          263  +    z = blob_str(pReply);
          264  +    for(i=j=0; z[i]; i++, j++){
          265  +      if( z[i]=='<' ){
          266  +        while( z[i] && z[i]!='>' ) i++;
          267  +        if( z[i]==0 ) break;
          268  +      }
          269  +      z[j] = z[i];
          270  +    }
          271  +    z[j] = 0;
          272  +    fossil_fatal("server sends error: %s", z);
          273  +  }
   250    274     if( g.fHttpTrace ){
   251         -    printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pReply));
          275  +    /*printf("HTTP RECEIVE:\n%s\n=======================\n",blob_str(pReply));*/
   252    276     }else{
   253    277       blob_uncompress(pReply, pReply);
   254    278     }
   255    279   
   256    280     /*
   257    281     ** Close the connection to the server if appropriate.
   258    282     **

Changes to src/http_socket.c.

    24     24   **
    25     25   ** Low-level sockets are abstracted out into this module because they 
    26     26   ** are handled different on Unix and windows.
    27     27   */
    28     28   
    29     29   #include "config.h"
    30     30   #include "http_socket.h"
    31         -#ifdef __MINGW32__
    32         -#  include <windows.h>
    33         -#  include <winsock2.h>
           31  +#if defined(_WIN32)
           32  +#  include <windows.h>           /* for Sleep once server works again */
           33  +#  define sleep Sleep            /* windows does not have sleep, but Sleep */
           34  +#  if defined(__MINGW32__)
           35  +#    include <ws2tcpip.h>          
           36  +#  endif
    34     37   #else
    35     38   #  include <arpa/inet.h>
    36     39   #  include <sys/socket.h>
    37     40   #  include <netdb.h>
    38     41   #  include <netinet/in.h>
    39     42   #endif
    40     43   #include <assert.h>
................................................................................
    43     46   
    44     47   /*
    45     48   ** There can only be a single socket connection open at a time.
    46     49   ** State information about that socket is stored in the following
    47     50   ** local variables:
    48     51   */
    49     52   static int socketIsInit = 0;    /* True after global initialization */
    50         -#ifdef __MINGW32__
           53  +#if defined(_WIN32)
    51     54   static WSADATA socketInfo;      /* Windows socket initialize data */
    52     55   #endif
    53     56   static int iSocket = -1;        /* The socket on which we talk to the server */
    54     57   static char *socketErrMsg = 0;  /* Text of most recent socket error */
    55     58   
    56     59   
    57     60   /*
................................................................................
    82     85   
    83     86   /*
    84     87   ** Call this routine once before any other use of the socket interface.
    85     88   ** This routine does initial configuration of the socket module.
    86     89   */
    87     90   void socket_global_init(void){
    88     91     if( socketIsInit==0 ){
    89         -#ifdef __MINGW32__
           92  +#if defined(_WIN32)
    90     93       if( WSAStartup(MAKEWORD(2,0), &socketInfo)!=0 ){
    91     94         fossil_panic("can't initialize winsock");
    92     95       }
    93     96   #endif
    94     97       socketIsInit = 1;
    95     98     }
    96     99   }
................................................................................
    97    100   
    98    101   /*
    99    102   ** Call this routine to shutdown the socket module prior to program
   100    103   ** exit.
   101    104   */
   102    105   void socket_global_shutdown(void){
   103    106     if( socketIsInit ){
   104         -#ifdef __MINGW32__
          107  +#if defined(_WIN32)
   105    108       WSACleanup();
   106    109   #endif
   107    110       socket_clear_errmsg();
   108    111       socketIsInit = 0;
   109    112     }
   110    113   }
   111    114   
   112    115   /*
   113    116   ** Close the currently open socket.  If no socket is open, this routine
   114    117   ** is a no-op.
   115    118   */
   116    119   void socket_close(void){
   117    120     if( iSocket>=0 ){
   118         -#ifdef __MINGW32__
          121  +#if defined(_WIN32)
   119    122       closesocket(iSocket);
   120    123   #else
   121    124       close(iSocket);
   122    125   #endif
   123    126       iSocket = -1;
   124    127     }
   125    128   }
................................................................................
   169    172       return 1;
   170    173     }
   171    174     if( connect(iSocket,(struct sockaddr*)&addr,sizeof(addr))<0 ){
   172    175       socket_set_errmsg("cannot connect to host %s:%d", g.urlName, g.urlPort);
   173    176       socket_close();
   174    177       return 1;
   175    178     }
   176         -#ifndef __MINGW32__
          179  +#if !defined(_WIN32)
   177    180     signal(SIGPIPE, SIG_IGN);
   178    181   #endif
   179    182     return 0;
   180    183   }
   181    184   
   182    185   /*
   183    186   ** Send content out over the open socket connection.

Changes to src/http_ssl.c.

    88     88   void ssl_global_init(void){
    89     89     if( sslIsInit==0 ){
    90     90       SSL_library_init();
    91     91       SSL_load_error_strings();
    92     92       ERR_load_BIO_strings();
    93     93       OpenSSL_add_all_algorithms();    
    94     94       sslCtx = SSL_CTX_new(SSLv23_client_method());
           95  +    X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
    95     96       sslIsInit = 1;
    96     97     }
    97     98   }
    98     99   
    99    100   /*
   100    101   ** Call this routine to shutdown the SSL module prior to program exit.
   101    102   */
................................................................................
   126    127   **    g.urlPort       TCP/IP port to use.  Ex: 80
   127    128   **
   128    129   ** Return the number of errors.
   129    130   */
   130    131   int ssl_open(void){
   131    132     X509 *cert;
   132    133     int hasSavedCertificate = 0;
   133         -
          134  +char *connStr ;
   134    135     ssl_global_init();
   135    136   
   136    137     /* Get certificate for current server from global config and
   137    138      * (if we have it in config) add it to certificate store.
   138    139      */
   139    140     cert = ssl_get_certificate();
   140    141     if ( cert!=NULL ){
................................................................................
   148    149     SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
   149    150     if( iBio==NULL ) {
   150    151       ssl_set_errmsg("SSL: cannot open SSL (%s)", 
   151    152                       ERR_reason_error_string(ERR_get_error()));
   152    153       return 1;    
   153    154     }
   154    155     
   155         -  char *connStr = mprintf("%s:%d", g.urlName, g.urlPort);
          156  +  connStr = mprintf("%s:%d", g.urlName, g.urlPort);
   156    157     BIO_set_conn_hostname(iBio, connStr);
   157    158     free(connStr);
   158    159     
   159    160     if( BIO_do_connect(iBio)<=0 ){
   160    161       ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)", 
   161    162           g.urlName, g.urlPort, ERR_reason_error_string(ERR_get_error()));
   162    163       ssl_close();
................................................................................
   176    177       ssl_set_errmsg("No SSL certificate was presented by the peer");
   177    178       ssl_close();
   178    179       return 1;
   179    180     }
   180    181   
   181    182     if( SSL_get_verify_result(ssl) != X509_V_OK ){
   182    183       char *desc, *prompt;
          184  +    char *warning = "";
          185  +    Blob ans;
   183    186       BIO *mem;
   184    187       
   185    188       mem = BIO_new(BIO_s_mem());
   186    189       X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE);
   187    190       BIO_puts(mem, "\n\nIssued By:\n\n");
   188    191       X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE);
   189    192       BIO_write(mem, "", 1); // null-terminate mem buffer
   190    193       BIO_get_mem_data(mem, &desc);
   191    194       
   192         -    char *warning = "";
   193    195       if( hasSavedCertificate ){
   194    196         warning = "WARNING: Certificate doesn't match the "
   195    197                   "saved certificate for this host!";
   196    198       }
   197    199       prompt = mprintf("\nUnknown SSL certificate:\n\n%s\n\n%s\n"
   198    200                        "Accept certificate [a=always/y/N]? ", desc, warning);
   199    201       BIO_free(mem);
   200    202   
   201         -    Blob ans;
   202    203       prompt_user(prompt, &ans);
   203    204       free(prompt);
   204    205       if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
   205    206         X509_free(cert);
   206    207         ssl_set_errmsg("SSL certificate declined");
   207    208         ssl_close();
   208    209         return 1;

Changes to src/http_transport.c.

    36     36     int nRcvd;              /* Number of bytes received */
    37     37     FILE *pFile;            /* File I/O for FILE: */
    38     38     char *zOutFile;         /* Name of outbound file for FILE: */
    39     39     char *zInFile;          /* Name of inbound file for FILE: */
    40     40   } transport = {
    41     41     0, 0, 0, 0, 0, 0, 0
    42     42   };
           43  +
           44  +/*
           45  +** Information about the connection to the SSH subprocess when
           46  +** using the ssh:// sync method.
           47  +*/
           48  +static int sshPid;             /* Process id of ssh subprocess */
           49  +static int sshIn;              /* From ssh subprocess to this process */
           50  +static FILE *sshOut;           /* From this to ssh subprocess */
           51  +
    43     52   
    44     53   /*
    45     54   ** Return the current transport error message.
    46     55   */
    47     56   const char *transport_errmsg(void){
    48     57     #ifdef FOSSIL_ENABLE_SSL
    49     58     if( g.urlIsHttps ){
................................................................................
    61     70     if( pnSent ) *pnSent = transport.nSent;
    62     71     if( pnRcvd ) *pnRcvd = transport.nRcvd;
    63     72     if( resetFlag ){
    64     73       transport.nSent = 0;
    65     74       transport.nRcvd = 0;
    66     75     }
    67     76   }
           77  +
           78  +/*
           79  +** Read text from sshIn.  Zero-terminate and remove trailing
           80  +** whitespace.
           81  +*/
           82  +static void sshin_read(char *zBuf, int szBuf){
           83  +  int got;
           84  +  zBuf[0] = 0;
           85  +  got = read(sshIn, zBuf, szBuf-1);
           86  +  while( got>=0 ){
           87  +    zBuf[got] = 0;
           88  +    if( got==0 || !fossil_isspace(zBuf[got-1]) ) break;
           89  +    got--;
           90  +  }
           91  +}
           92  +
           93  +/*
           94  +** Default SSH command
           95  +*/
           96  +#ifdef __MINGW32__
           97  +static char zDefaultSshCmd[] = "ssh -T";
           98  +#else
           99  +static char zDefaultSshCmd[] = "ssh -e none -T";
          100  +#endif
          101  +
          102  +/*
          103  +** Global initialization of the transport layer
          104  +*/
          105  +void transport_global_startup(void){
          106  +  if( g.urlIsSsh ){
          107  +    /* Only SSH requires a global initialization.  For SSH we need to create
          108  +    ** and run an SSH command to talk to the remote machine.
          109  +    */
          110  +    const char *zSsh;  /* The base SSH command */
          111  +    Blob zCmd;         /* The SSH command */
          112  +    char *zHost;       /* The host name to contact */
          113  +    char zIn[200];     /* An input line received back from remote */
          114  +
          115  +    zSsh = db_get("ssh-command", zDefaultSshCmd);
          116  +    blob_init(&zCmd, zSsh, -1);
          117  +    if( g.urlPort!=g.urlDfltPort ){
          118  +#ifdef __MINGW32__
          119  +      blob_appendf(&zCmd, " -P %d", g.urlPort);
          120  +#else
          121  +      blob_appendf(&zCmd, " -p %d", g.urlPort);
          122  +#endif
          123  +    }
          124  +    if( g.urlUser && g.urlUser[0] ){
          125  +      zHost = mprintf("%s@%s", g.urlUser, g.urlName);
          126  +#ifdef __MINGW32__
          127  +      /* Only win32 (and specifically PLINK.EXE support the -pw option */
          128  +      if( g.urlPasswd && g.urlPasswd[0] ){
          129  +        Blob pw;
          130  +        blob_zero(&pw);
          131  +        if( g.urlPasswd[0]=='*' ){
          132  +          char *zPrompt;
          133  +          zPrompt = mprintf("Password for [%s]: ", zHost);
          134  +          prompt_for_password(zPrompt, &pw, 0);
          135  +          free(zPrompt);
          136  +        }else{
          137  +          blob_init(&pw, g.urlPasswd, -1);
          138  +        }
          139  +        blob_append(&zCmd, " -pw ", -1);
          140  +        shell_escape(&zCmd, blob_str(&pw));
          141  +        blob_reset(&pw);
          142  +      }
          143  +#endif
          144  +    }else{
          145  +      zHost = mprintf("%s", g.urlName);
          146  +    }
          147  +    blob_append(&zCmd, " ", 1);
          148  +    shell_escape(&zCmd, zHost);
          149  +    free(zHost);
          150  +    /* printf("%s\n", blob_str(&zCmd)); */
          151  +    popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
          152  +    if( sshPid==0 ){
          153  +      fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
          154  +    }
          155  +    blob_reset(&zCmd);
          156  +
          157  +    /* Send an "echo" command to the other side to make sure that the
          158  +    ** connection is up and working.
          159  +    */
          160  +    fprintf(sshOut, "echo test\n");
          161  +    fflush(sshOut);
          162  +    sshin_read(zIn, sizeof(zIn));
          163  +    if( memcmp(zIn, "test", 4)!=0 ){
          164  +      pclose2(sshIn, sshOut, sshPid);
          165  +      fossil_fatal("ssh connection failed: [%s]", zIn);
          166  +    }
          167  +  }
          168  +}
    68    169   
    69    170   /*
    70    171   ** Open a connection to the server.  The server is defined by the following
    71    172   ** global variables:
    72    173   **
    73    174   **   g.urlName        Name of the server.  Ex: www.fossil-scm.org
    74    175   **   g.urlPort        TCP/IP port.  Ex: 80
................................................................................
    75    176   **   g.urlIsHttps     Use TLS for the connection
    76    177   **
    77    178   ** Return the number of errors.
    78    179   */
    79    180   int transport_open(void){
    80    181     int rc = 0;
    81    182     if( transport.isOpen==0 ){
    82         -    if( g.urlIsHttps ){
          183  +    if( g.urlIsSsh ){
          184  +      Blob cmd;
          185  +      blob_zero(&cmd);
          186  +      shell_escape(&cmd, g.urlFossil);
          187  +      blob_append(&cmd, " test-http ", -1);
          188  +      shell_escape(&cmd, g.urlPath);
          189  +      /* fprintf(stdout, "%s\n", blob_str(&cmd)); */
          190  +      fprintf(sshOut, "%s\n", blob_str(&cmd));
          191  +      fflush(sshOut);
          192  +      blob_reset(&cmd);
          193  +    }else if( g.urlIsHttps ){
    83    194         #ifdef FOSSIL_ENABLE_SSL
    84    195         rc = ssl_open();
    85    196         if( rc==0 ) transport.isOpen = 1;
    86    197         #else
    87    198         socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
    88    199         rc = 1;
    89    200         #endif
................................................................................
   113    224   void transport_close(void){
   114    225     if( transport.isOpen ){
   115    226       free(transport.pBuf);
   116    227       transport.pBuf = 0;
   117    228       transport.nAlloc = 0;
   118    229       transport.nUsed = 0;
   119    230       transport.iCursor = 0;
   120         -    if( g.urlIsHttps ){
          231  +    if( g.urlIsSsh ){
          232  +      /* No-op */
          233  +    }else if( g.urlIsHttps ){
   121    234         #ifdef FOSSIL_ENABLE_SSL
   122    235         ssl_close();
   123    236         #endif
   124    237       }else if( g.urlIsFile ){
   125    238         if( transport.pFile ){ 
   126    239           fclose(transport.pFile);
   127    240           transport.pFile = 0;
................................................................................
   140    253   /*
   141    254   ** Send content over the wire.
   142    255   */
   143    256   void transport_send(Blob *toSend){
   144    257     char *z = blob_buffer(toSend);
   145    258     int n = blob_size(toSend);
   146    259     transport.nSent += n;
   147         -  if( g.urlIsHttps ){
          260  +  if( g.urlIsSsh ){
          261  +    int sent;
          262  +    sent = fwrite(z, 1, n, sshOut);
          263  +    fflush(sshOut);
          264  +    /* printf("sent %d of %d bytes\n", sent, n); fflush(stdout); */
          265  +  }else if( g.urlIsHttps ){
   148    266       #ifdef FOSSIL_ENABLE_SSL
   149    267       int sent;
   150    268       while( n>0 ){
   151    269         sent = ssl_send(0, z, n);
   152    270         /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
   153    271         if( sent<=0 ) break;
   154    272         n -= sent;
................................................................................
   168    286   }
   169    287   
   170    288   /*
   171    289   ** This routine is called when the outbound message is complete and
   172    290   ** it is time to being recieving a reply.
   173    291   */
   174    292   void transport_flip(void){
   175         -  if( g.urlIsFile ){
          293  +  if( g.urlIsSsh ){
          294  +    fprintf(sshOut, "\n\n");
          295  +  }else if( g.urlIsFile ){
   176    296       char *zCmd;
   177    297       fclose(transport.pFile);
   178    298       zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1",
   179    299          g.argv[0], g.urlName, transport.zOutFile, transport.zInFile
   180    300       );
   181         -    portable_system(zCmd);
          301  +    fossil_system(zCmd);
   182    302       free(zCmd);
   183    303       transport.pFile = fopen(transport.zInFile, "rb");
   184    304     }
   185    305   }
   186    306   
   187    307   /*
   188    308   ** This routine is called when the inbound message has been received
................................................................................
   189    309   ** and it is time to start sending again.
   190    310   */
   191    311   void transport_rewind(void){
   192    312     if( g.urlIsFile ){
   193    313       transport_close();
   194    314     }
   195    315   }
          316  +
          317  +/*
          318  +** Read N bytes of content directly from the wire and write into
          319  +** the buffer.
          320  +*/
          321  +static int transport_fetch(char *zBuf, int N){
          322  +  int got;
          323  +  if( sshIn ){
          324  +    int x;
          325  +    int wanted = N;
          326  +    got = 0;
          327  +    while( wanted>0 ){
          328  +      x = read(sshIn, &zBuf[got], wanted);
          329  +      if( x<=0 ) break;
          330  +      got += x;
          331  +      wanted -= x;
          332  +    }
          333  +  }else if( g.urlIsHttps ){
          334  +    #ifdef FOSSIL_ENABLE_SSL
          335  +    got = ssl_receive(0, zBuf, N);
          336  +    #else
          337  +    got = 0;
          338  +    #endif
          339  +  }else if( g.urlIsFile ){
          340  +    got = fread(zBuf, 1, N, transport.pFile);
          341  +  }else{
          342  +    got = socket_receive(0, zBuf, N);
          343  +  }
          344  +  /* printf("received %d of %d bytes\n", got, N); fflush(stdout);  */
          345  +  return got;
          346  +}
   196    347   
   197    348   /*
   198    349   ** Read N bytes of content from the wire and store in the supplied buffer.
   199    350   ** Return the number of bytes actually received.
   200    351   */
   201    352   int transport_receive(char *zBuf, int N){
   202    353     int onHand;       /* Bytes current held in the transport buffer */
   203    354     int nByte = 0;    /* Bytes of content received */
   204    355   
   205    356     onHand = transport.nUsed - transport.iCursor;
          357  +  /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout);  */
   206    358     if( onHand>0 ){
   207    359       int toMove = onHand;
   208    360       if( toMove>N ) toMove = N;
   209    361       /* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
   210    362       memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
   211    363       transport.iCursor += toMove;
   212    364       if( transport.iCursor>=transport.nUsed ){
................................................................................
   214    366         transport.iCursor = 0;
   215    367       }
   216    368       N -= toMove;
   217    369       zBuf += toMove;
   218    370       nByte += toMove;
   219    371     }
   220    372     if( N>0 ){
   221         -    int got;
   222         -    if( g.urlIsHttps ){
   223         -      #ifdef FOSSIL_ENABLE_SSL
   224         -      got = ssl_receive(0, zBuf, N);
   225         -      /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
   226         -      #else
   227         -      got = 0;
   228         -      #endif
   229         -    }else if( g.urlIsFile ){
   230         -      got = fread(zBuf, 1, N, transport.pFile);
   231         -    }else{
   232         -      got = socket_receive(0, zBuf, N);
   233         -      /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
   234         -    }
          373  +    int got = transport_fetch(zBuf, N);
   235    374       if( got>0 ){
   236    375         nByte += got;
   237    376         transport.nRcvd += got;
   238    377       }
   239    378     }
   240    379     return nByte;
   241    380   }
................................................................................
   245    384   ** The buffer itself might be moved.  And the transport.iCursor value
   246    385   ** might be reset to 0.
   247    386   */
   248    387   static void transport_load_buffer(int N){
   249    388     int i, j;
   250    389     if( transport.nAlloc==0 ){
   251    390       transport.nAlloc = N;
   252         -    transport.pBuf = malloc( N );
   253         -    if( transport.pBuf==0 ) fossil_panic("out of memory");
          391  +    transport.pBuf = fossil_malloc( N );
   254    392       transport.iCursor = 0;
   255    393       transport.nUsed = 0;
   256    394     }
   257    395     if( transport.iCursor>0 ){
   258    396       for(i=0, j=transport.iCursor; j<transport.nUsed; i++, j++){
   259    397         transport.pBuf[i] = transport.pBuf[j];
   260    398       }
   261    399       transport.nUsed -= transport.iCursor;
   262    400       transport.iCursor = 0;
   263    401     }
   264    402     if( transport.nUsed + N > transport.nAlloc ){
   265    403       char *pNew;
   266    404       transport.nAlloc = transport.nUsed + N;
   267         -    pNew = realloc(transport.pBuf, transport.nAlloc);
   268         -    if( pNew==0 ) fossil_panic("out of memory");
          405  +    pNew = fossil_realloc(transport.pBuf, transport.nAlloc);
   269    406       transport.pBuf = pNew;
   270    407     }
   271    408     if( N>0 ){
   272         -    i = transport_receive(&transport.pBuf[transport.nUsed], N);
          409  +    i = transport_fetch(&transport.pBuf[transport.nUsed], N);
   273    410       if( i>0 ){
   274    411         transport.nUsed += i;
   275    412       }
   276    413     }
   277    414   }
   278    415   
   279    416   /*
................................................................................
   298    435           transport.pBuf[i] = 0;
   299    436           transport.iCursor = i;
   300    437           break;
   301    438         }
   302    439       }
   303    440       if( transport.pBuf[i]=='\n' ){
   304    441         transport.iCursor = i+1;
   305         -      while( i>=iStart && isspace(transport.pBuf[i]) ){
          442  +      while( i>=iStart && fossil_isspace(transport.pBuf[i]) ){
   306    443           transport.pBuf[i] = 0;
   307    444           i--;
   308    445         }
   309    446         break;
   310    447       }
   311    448       i++;
   312    449     }
   313    450     /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
   314    451     return &transport.pBuf[iStart];
   315    452   }
   316    453   
   317    454   void transport_global_shutdown(void){
          455  +  if( g.urlIsSsh && sshPid ){
          456  +    printf("Closing SSH tunnel: ");
          457  +    fflush(stdout);
          458  +    pclose2(sshIn, sshOut, sshPid);
          459  +    sshPid = 0;
          460  +  }
   318    461     if( g.urlIsHttps ){
   319    462       #ifdef FOSSIL_ENABLE_SSL
   320    463       ssl_global_shutdown();
   321    464       #endif
   322    465     }else{
   323    466       socket_global_shutdown();
   324    467     }
   325    468   }

Changes to src/info.c.

    63     63         "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
    64     64         rid
    65     65       );
    66     66            /* 01234567890123 */
    67     67       printf("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : "");
    68     68       free(zUuid);
    69     69       free(zDate);
           70  +  }
           71  +  if( zUuid && showComment ){
           72  +    zComment = db_text(0, 
           73  +      "SELECT coalesce(ecomment,comment) || ' (user: ' || coalesce(euser,user,'?') || ')' FROM event WHERE objid=%d",
           74  +      rid
           75  +    );
    70     76     }
    71     77     db_prepare(&q, "SELECT uuid, pid FROM plink JOIN blob ON pid=rid "
    72     78                    " WHERE cid=%d", rid);
    73     79     while( db_step(&q)==SQLITE_ROW ){
    74     80       const char *zUuid = db_column_text(&q, 0);
    75     81       zDate = db_text("", 
    76     82         "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
................................................................................
    94    100     db_finalize(&q);
    95    101     zTags = info_tags_of_checkin(rid, 0);
    96    102     if( zTags && zTags[0] ){
    97    103       printf("tags:         %s\n", zTags);
    98    104     }
    99    105     free(zTags);
   100    106     if( zComment ){
   101         -    printf("comment:\n%s\n", zComment);
          107  +    printf("comment:      ");
          108  +    comment_print(zComment, 14, 79);
   102    109       free(zComment);
   103    110     }
   104    111   }
   105    112   
   106    113   
   107    114   /*
   108    115   ** COMMAND: info
................................................................................
   133    140     if( g.argc==2 ){
   134    141       int vid;
   135    142            /* 012345678901234 */
   136    143       db_record_repository_filename(0);
   137    144       printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
   138    145       printf("repository:   %s\n", db_lget("repository", ""));
   139    146       printf("local-root:   %s\n", g.zLocalRoot);
   140         -#ifdef __MINGW32__
          147  +#if defined(_WIN32)
   141    148       if( g.zHome ){
   142    149         printf("user-home:    %s\n", g.zHome);
   143    150       }
   144    151   #endif
   145    152       printf("project-code: %s\n", db_get("project-code", ""));
   146    153       printf("server-code:  %s\n", db_get("server-code", ""));
   147    154       vid = db_lget_int("checkout", 0);
................................................................................
   185    192       cnt++;
   186    193       if( cnt==1 ){
   187    194         @ <div class="section">Tags And Properties</div>
   188    195         @ <ul>
   189    196       }
   190    197       @ <li>
   191    198       if( tagtype==0 ){
   192         -      @ <b><s>%h(zTagname)</s></b> cancelled
          199  +      @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled
   193    200       }else if( zValue ){
   194         -      @ <b>%h(zTagname)=%h(zValue)</b>
          201  +      @ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
   195    202       }else {
   196         -      @ <b>%h(zTagname)</b>
          203  +      @ <span class="infoTag">%h(zTagname)</span>
   197    204       }
   198    205       if( tagtype==2 ){
   199    206         if( zOrigUuid && zOrigUuid[0] ){
   200    207           @ inherited from
   201    208           hyperlink_to_uuid(zOrigUuid);
   202    209         }else{
   203    210           @ propagates to descendants
................................................................................
   213    220         }else{
   214    221           @ added by
   215    222         }
   216    223         hyperlink_to_uuid(zSrcUuid);
   217    224         @ on
   218    225         hyperlink_to_date(zDate,0);
   219    226       }
          227  +    @ </li>
   220    228     }
   221    229     db_finalize(&q);
   222    230     if( cnt ){
   223    231       @ </ul>
   224    232     }
   225    233   }
   226    234   
   227    235   
   228    236   /*
   229    237   ** Append the difference between two RIDs to the output
   230    238   */
   231         -static void append_diff(int fromid, int toid){
          239  +static void append_diff(const char *zFrom, const char *zTo){
          240  +  int fromid;
          241  +  int toid;
   232    242     Blob from, to, out;
   233         -  content_get(fromid, &from);
   234         -  content_get(toid, &to);
          243  +  if( zFrom ){
          244  +    fromid = uuid_to_rid(zFrom, 0);
          245  +    content_get(fromid, &from);
          246  +  }else{
          247  +    blob_zero(&from);
          248  +  }
          249  +  if( zTo ){
          250  +    toid = uuid_to_rid(zTo, 0);
          251  +    content_get(toid, &to);
          252  +  }else{
          253  +    blob_zero(&to);
          254  +  }
   235    255     blob_zero(&out);
   236         -  text_diff(&from, &to, &out, 5);
          256  +  text_diff(&from, &to, &out, 5, 1);
   237    257     @ %h(blob_str(&out))
   238    258     blob_reset(&from);
   239    259     blob_reset(&to);
   240    260     blob_reset(&out);  
   241    261   }
   242    262   
   243    263   /*
................................................................................
   254    274       if( zNew==0 ){
   255    275         @ <p>Deleted %h(zName)</p>
   256    276       }else if( zOld==0 ){
   257    277         @ <p>Added %h(zName)</p>
   258    278       }else{
   259    279         @ <p>Changes to %h(zName)</p>
   260    280       }
   261         -  }else if( zOld && zNew ){
   262         -    @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
   263         -    @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
   264         -    @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
   265         -    if( !showDiff ){
   266         -      @ &nbsp;&nbsp;
   267         -      @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a>
          281  +    if( showDiff ){
          282  +      @ <blockquote><pre>
          283  +      append_diff(zOld, zNew);
          284  +      @ </pre></blockquote>
          285  +    }
          286  +  }else{
          287  +    if( zOld && zNew ){
          288  +      @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
          289  +      @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
          290  +      @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
          291  +    }else if( zOld ){
          292  +      @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
          293  +      @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
   268    294       }else{
   269         -      int rid1 = uuid_to_rid(zOld, 0);
   270         -      int rid2 = uuid_to_rid(zNew, 0);
          295  +      @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
          296  +      @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a>
          297  +    }
          298  +    if( showDiff ){
   271    299         @ <blockquote><pre>
   272         -      append_diff(rid1, rid2);
          300  +      append_diff(zOld, zNew);
   273    301         @ </pre></blockquote>
          302  +    }else if( zOld && zNew ){
          303  +      @ &nbsp;&nbsp;
          304  +      @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&amp;v2=%S(zNew)">[diff]</a>
   274    305       }
   275         -  }else if( zOld ){
   276         -    @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
   277         -    @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a></p>
   278         -  }else{
   279         -    @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
   280         -    @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a></p>
          306  +    @ </p>
   281    307     }
   282    308   }
   283    309   
   284    310   
   285    311   /*
   286    312   ** WEBPAGE: vinfo
   287    313   ** WEBPAGE: ci
................................................................................
   338    364       zEComment = db_text(0, 
   339    365                      "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
   340    366                      TAG_COMMENT, rid);
   341    367       zUser = db_column_text(&q, 2);
   342    368       zComment = db_column_text(&q, 3);
   343    369       zDate = db_column_text(&q,1);
   344    370       @ <div class="section">Overview</div>
   345         -    @ <p><table class="label-value">
          371  +    @ <table class="label-value">
   346    372       @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
   347    373       if( g.okSetup ){
   348    374         @ (Record ID: %d(rid))
   349    375       }
   350    376       @ </td></tr>
   351    377       @ <tr><th>Date:</th><td>
   352    378       hyperlink_to_date(zDate, "</td></tr>");
................................................................................
   381    407           @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
   382    408         }
   383    409         db_finalize(&q);
   384    410       }
   385    411       if( g.okHistory ){
   386    412         const char *zProjName = db_get("project-name", "unnamed");
   387    413         @ <tr><th>Timelines:</th><td>
   388         -      @    <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
   389         -      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
   390         -      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a>
          414  +      @   <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
          415  +      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
          416  +      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
   391    417         db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
   392    418                        " WHERE rid=%d AND tagtype>0 "
   393    419                        "   AND tag.tagid=tagxref.tagid "
   394    420                        "   AND +tag.tagname GLOB 'sym-*'", rid);
   395    421         while( db_step(&q)==SQLITE_ROW ){
   396    422           const char *zTagName = db_column_text(&q, 0);
   397    423           @  | <a href="%s(g.zTop)/timeline?r=%T(zTagName)">%h(zTagName)</a>
   398    424         }
   399    425         db_finalize(&q);
   400    426         @ </td></tr>
   401    427         @ <tr><th>Other&nbsp;Links:</th>
   402    428         @   <td>
   403    429         @     <a href="%s(g.zTop)/dir?ci=%S(zUuid)">files</a>
   404         -      @   | <a href="%s(g.zTop)/zip/%s(zProjName)-%S(zUuid).zip?uuid=%s(zUuid)">
   405         -      @         ZIP archive</a>
          430  +      if( g.okZip ){
          431  +        @ | <a href="%s(g.zTop)/zip/%s(zProjName)-%S(zUuid).zip?uuid=%s(zUuid)">
          432  +        @         ZIP archive</a>
          433  +      }
   406    434         @   | <a href="%s(g.zTop)/artifact/%S(zUuid)">manifest</a>
   407    435         if( g.okWrite ){
   408    436           @   | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a>
   409    437         }
   410    438         @   </td>
   411    439         @ </tr>
   412    440       }
   413         -    @ </table></p>
          441  +    @ </table>
   414    442     }else{
   415    443       style_header("Check-in Information");
   416    444       login_anonymous_available();
   417    445     }
   418    446     db_finalize(&q);
   419    447     showTags(rid, "");
   420    448     @ <div class="section">Changes</div>
................................................................................
   513    541     }else{
   514    542       style_header("Wiki Information");
   515    543       rid = 0;
   516    544     }
   517    545     db_finalize(&q);
   518    546     showTags(rid, "wiki-*");
   519    547     if( rid ){
   520         -    Blob content;
   521         -    Manifest m;
   522         -    memset(&m, 0, sizeof(m));
   523         -    blob_zero(&m.content);
   524         -    content_get(rid, &content);
   525         -    manifest_parse(&m, &content);
   526         -    if( m.type==CFTYPE_WIKI ){
          548  +    Manifest *pWiki;
          549  +    pWiki = manifest_get(rid, CFTYPE_WIKI);
          550  +    if( pWiki ){
   527    551         Blob wiki;
   528         -      blob_init(&wiki, m.zWiki, -1);
          552  +      blob_init(&wiki, pWiki->zWiki, -1);
   529    553         @ <div class="section">Content</div>
   530    554         wiki_convert(&wiki, 0, 0);
   531    555         blob_reset(&wiki);
   532    556       }
   533         -    manifest_clear(&m);
          557  +    manifest_destroy(pWiki);
   534    558     }
   535    559     style_footer();
   536    560   }
   537    561   
   538    562   /*
   539    563   ** Show a webpage error message
   540    564   */
................................................................................
   550    574     style_footer();
   551    575   }
   552    576   
   553    577   /*
   554    578   ** Find an checkin based on query parameter zParam and parse its
   555    579   ** manifest.  Return the number of errors.
   556    580   */
   557         -static int vdiff_parse_manifest(const char *zParam, int *pRid, Manifest *pM){
          581  +static Manifest *vdiff_parse_manifest(const char *zParam, int *pRid){
   558    582     int rid;
   559         -  Blob content;
   560    583   
   561    584     *pRid = rid = name_to_rid_www(zParam);
   562    585     if( rid==0 ){
   563    586       webpage_error("Missing \"%s\" query parameter.", zParam);
   564         -    return 1;
          587  +    return 0;
   565    588     }
   566    589     if( !is_a_version(rid) ){
   567    590       webpage_error("Artifact %s is not a checkin.", P(zParam));
   568         -    return 1;
          591  +    return 0;
   569    592     }
   570         -  content_get(rid, &content);
   571         -  manifest_parse(pM, &content);
   572         -  return 0;
          593  +  return manifest_get(rid, CFTYPE_MANIFEST);
   573    594   }
   574    595   
   575    596   /*
   576    597   ** Output a description of a check-in
   577    598   */
   578    599   void checkin_description(int rid){
   579    600     Stmt q;
................................................................................
   598    619     }
   599    620     db_finalize(&q);
   600    621   }
   601    622   
   602    623   
   603    624   /*
   604    625   ** WEBPAGE: vdiff
   605         -** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN
          626  +** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN
   606    627   **
   607    628   ** Show all differences between two checkins.  
   608    629   */
   609    630   void vdiff_page(void){
   610    631     int ridFrom, ridTo;
   611    632     int showDetail = 0;
   612         -  int iFrom, iTo;
   613         -  Manifest mFrom, mTo;
          633  +  Manifest *pFrom, *pTo;
          634  +  ManifestFile *pFileFrom, *pFileTo;
   614    635   
   615    636     login_check_credentials();
   616    637     if( !g.okRead ){ login_needed(); return; }
   617    638     login_anonymous_available();
   618    639   
   619         -  if( vdiff_parse_manifest("from", &ridFrom, &mFrom) ) return;
   620         -  if( vdiff_parse_manifest("to", &ridTo, &mTo) ) return;
          640  +  pFrom = vdiff_parse_manifest("from", &ridFrom);
          641  +  if( pFrom==0 ) return;
          642  +  pTo = vdiff_parse_manifest("to", &ridTo);
          643  +  if( pTo==0 ) return;
   621    644     showDetail = atoi(PD("detail","0"));
   622    645     style_header("Check-in Differences");
   623    646     @ <h2>Difference From:</h2><blockquote>
   624    647     checkin_description(ridFrom);
   625    648     @ </blockquote><h2>To:</h2><blockquote>
   626    649     checkin_description(ridTo);
   627         -  @ </blockquote><hr><p>
          650  +  @ </blockquote><hr /><p>
   628    651   
   629         -  iFrom = iTo = 0;
   630         -  while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
          652  +  manifest_file_rewind(pFrom);
          653  +  pFileFrom = manifest_file_next(pFrom, 0);
          654  +  manifest_file_rewind(pTo);
          655  +  pFileTo = manifest_file_next(pTo, 0);
          656  +  while( pFileFrom || pFileTo ){
   631    657       int cmp;
   632         -    if( iFrom>=mFrom.nFile ){
          658  +    if( pFileFrom==0 ){
   633    659         cmp = +1;
   634         -    }else if( iTo>=mTo.nFile ){
          660  +    }else if( pFileTo==0 ){
   635    661         cmp = -1;
   636    662       }else{
   637         -      cmp = strcmp(mFrom.aFile[iFrom].zName, mTo.aFile[iTo].zName);
          663  +      cmp = strcmp(pFileFrom->zName, pFileTo->zName);
   638    664       }
   639    665       if( cmp<0 ){
   640         -      append_file_change_line(mFrom.aFile[iFrom].zName, 
   641         -                              mFrom.aFile[iFrom].zUuid, 0, 0);
   642         -      iFrom++;
          666  +      append_file_change_line(pFileFrom->zName, 
          667  +                              pFileFrom->zUuid, 0, 0);
          668  +      pFileFrom = manifest_file_next(pFrom, 0);
   643    669       }else if( cmp>0 ){
   644         -      append_file_change_line(mTo.aFile[iTo].zName, 
   645         -                              0, mTo.aFile[iTo].zUuid, 0);
   646         -      iTo++;
   647         -    }else if( strcmp(mFrom.aFile[iFrom].zUuid, mTo.aFile[iTo].zUuid)==0 ){
          670  +      append_file_change_line(pFileTo->zName, 
          671  +                              0, pFileTo->zUuid, 0);
          672  +      pFileTo = manifest_file_next(pTo, 0);
          673  +    }else if( strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
   648    674         /* No changes */
   649         -      iFrom++;
   650         -      iTo++;
          675  +      pFileFrom = manifest_file_next(pFrom, 0);
          676  +      pFileTo = manifest_file_next(pTo, 0);
   651    677       }else{
   652         -      append_file_change_line(mFrom.aFile[iFrom].zName, 
   653         -                              mFrom.aFile[iFrom].zUuid,
   654         -                              mTo.aFile[iTo].zUuid, showDetail);
   655         -      iFrom++;
   656         -      iTo++;
          678  +      append_file_change_line(pFileFrom->zName, 
          679  +                              pFileFrom->zUuid,
          680  +                              pFileTo->zUuid, showDetail);
          681  +      pFileFrom = manifest_file_next(pFrom, 0);
          682  +      pFileTo = manifest_file_next(pTo, 0);
   657    683       }
   658    684     }
   659         -  manifest_clear(&mFrom);
   660         -  manifest_clear(&mTo);
          685  +  manifest_destroy(pFrom);
          686  +  manifest_destroy(pTo);
   661    687   
   662    688     style_footer();
   663    689   }
   664    690   
   665    691   /*
   666    692   ** Write a description of an object to the www reply.
   667    693   **
................................................................................
   759    785       if( pDownloadName && blob_size(pDownloadName)==0 ){
   760    786         blob_appendf(pDownloadName, "%s.wiki", zPagename);
   761    787       }
   762    788     }
   763    789     db_finalize(&q);
   764    790     if( nWiki==0 ){
   765    791       db_prepare(&q,
   766         -      "SELECT datetime(mtime), user, comment, type, uuid"
          792  +      "SELECT datetime(mtime), user, comment, type, uuid, tagid"
   767    793         "  FROM event, blob"
   768    794         " WHERE event.objid=%d"
   769    795         "   AND blob.rid=%d",
   770    796         rid, rid
   771    797       );
   772    798       while( db_step(&q)==SQLITE_ROW ){
   773    799         const char *zDate = db_column_text(&q, 0);
................................................................................
   780    806         }
   781    807         if( zType[0]=='w' ){
   782    808           @ Wiki edit
   783    809         }else if( zType[0]=='t' ){
   784    810           @ Ticket change
   785    811         }else if( zType[0]=='c' ){
   786    812           @ Manifest of check-in
          813  +      }else if( zType[0]=='e' ){
          814  +        @ Instance of event
          815  +        hyperlink_to_event_tagid(db_column_int(&q, 5));
   787    816         }else{
   788    817           @ Control file referencing
   789    818         }
   790         -      hyperlink_to_uuid(zUuid);
          819  +      if( zType[0]!='e' ){
          820  +        hyperlink_to_uuid(zUuid);
          821  +      }
   791    822         @ - %w(zCom) by
   792    823         hyperlink_to_user(zUser,zDate," on");
   793    824         hyperlink_to_date(zDate, ".");
   794    825         if( pDownloadName && blob_size(pDownloadName)==0 ){
   795    826           blob_appendf(pDownloadName, "%.10s.txt", zUuid);
   796    827         }
   797    828         cnt++;
................................................................................
   862    893     login_check_credentials();
   863    894     if( !g.okRead ){ login_needed(); return; }
   864    895     v1 = name_to_rid_www("v1");
   865    896     v2 = name_to_rid_www("v2");
   866    897     if( v1==0 || v2==0 ) fossil_redirect_home();
   867    898     style_header("Diff");
   868    899     @ <h2>Differences From:</h2>
   869         -  @ <blockquote>
          900  +  @ <blockquote><p>
   870    901     object_description(v1, 1, 0);
   871         -  @ </blockquote>
          902  +  @ </p></blockquote>
   872    903     @ <h2>To:</h2>
   873         -  @ <blockquote>
          904  +  @ <blockquote><p>
   874    905     object_description(v2, 1, 0);
   875         -  @ </blockquote>
   876         -  @ <hr>
          906  +  @ </p></blockquote>
          907  +  @ <hr />
   877    908     @ <blockquote><pre>
   878    909     content_get(v1, &c1);
   879    910     content_get(v2, &c2);
   880    911     blob_zero(&diff);
   881         -  text_diff(&c1, &c2, &diff, 4);
          912  +  text_diff(&c1, &c2, &diff, 4, 1);
   882    913     blob_reset(&c1);
   883    914     blob_reset(&c2);
   884    915     @ %h(blob_str(&diff))
   885    916     @ </pre></blockquote>
   886    917     blob_reset(&diff);
   887    918     style_footer();
   888    919   }
................................................................................
   976   1007     rid = name_to_rid_www("name");
   977   1008     login_check_credentials();
   978   1009     if( !g.okRead ){ login_needed(); return; }
   979   1010     if( rid==0 ) fossil_redirect_home();
   980   1011     if( g.okAdmin ){
   981   1012       const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
   982   1013       if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
   983         -      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
         1014  +      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
   984   1015               g.zTop, zUuid);
   985   1016       }else{
   986   1017         style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
   987   1018               g.zTop, zUuid);
   988   1019       }
   989   1020     }
   990   1021     style_header("Hex Artifact Content");
   991   1022     zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid);
   992   1023     @ <h2>Artifact %s(zUuid):</h2>
   993         -  @ <blockquote>
         1024  +  @ <blockquote><p>
   994   1025     blob_zero(&downloadName);
   995   1026     object_description(rid, 0, &downloadName);
   996   1027     style_submenu_element("Download", "Download", 
   997   1028           "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
   998         -  @ </blockquote>
   999         -  @ <hr>
         1029  +  @ </p></blockquote>
         1030  +  @ <hr />
  1000   1031     content_get(rid, &content);
  1001   1032     @ <blockquote><pre>
  1002   1033     hexdump(&content);
  1003   1034     @ </pre></blockquote>
  1004   1035     style_footer();
  1005   1036   }
  1006   1037   
................................................................................
  1008   1039   ** Look for "ci" and "filename" query parameters.  If found, try to
  1009   1040   ** use them to extract the record ID of an artifact for the file.
  1010   1041   */
  1011   1042   int artifact_from_ci_and_filename(void){
  1012   1043     const char *zFilename;
  1013   1044     const char *zCI;
  1014   1045     int cirid;
  1015         -  Blob content;
  1016         -  Manifest m;
  1017         -  int i;
         1046  +  Manifest *pManifest;
         1047  +  ManifestFile *pFile;
  1018   1048   
  1019   1049     zCI = P("ci");
  1020   1050     if( zCI==0 ) return 0;
  1021   1051     zFilename = P("filename");
  1022   1052     if( zFilename==0 ) return 0;
  1023   1053     cirid = name_to_rid_www("ci");
  1024         -  if( !content_get(cirid, &content) ) return 0;
  1025         -  if( !manifest_parse(&m, &content) ) return 0;
  1026         -  if( m.type!=CFTYPE_MANIFEST ) return 0;
  1027         -  for(i=0; i<m.nFile; i++){
  1028         -    if( strcmp(zFilename, m.aFile[i].zName)==0 ){
  1029         -      return db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", m.aFile[i].zUuid);
         1054  +  pManifest = manifest_get(cirid, CFTYPE_MANIFEST);
         1055  +  if( pManifest==0 ) return 0;
         1056  +  manifest_file_rewind(pManifest);
         1057  +  while( (pFile = manifest_file_next(pManifest,0))!=0 ){
         1058  +    if( strcmp(zFilename, pFile->zName)==0 ){
         1059  +      int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
         1060  +      manifest_destroy(pManifest);
         1061  +      return rid;
  1030   1062       }
  1031   1063     }
  1032   1064     return 0;
  1033   1065   }
  1034   1066   
  1035   1067   
  1036   1068   /*
................................................................................
  1058   1090   
  1059   1091     login_check_credentials();
  1060   1092     if( !g.okRead ){ login_needed(); return; }
  1061   1093     if( rid==0 ) fossil_redirect_home();
  1062   1094     if( g.okAdmin ){
  1063   1095       const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  1064   1096       if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
  1065         -      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
         1097  +      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
  1066   1098               g.zTop, zUuid);
  1067   1099       }else{
  1068   1100         style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
  1069   1101               g.zTop, zUuid);
  1070   1102       }
  1071   1103     }
  1072   1104     style_header("Artifact Content");
  1073   1105     zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
  1074   1106     @ <h2>Artifact %s(zUuid)</h2>
  1075         -  @ <blockquote>
         1107  +  @ <blockquote><p>
  1076   1108     blob_zero(&downloadName);
  1077   1109     object_description(rid, 0, &downloadName);
  1078   1110     style_submenu_element("Download", "Download", 
  1079   1111             "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
  1080   1112     zMime = mimetype_from_name(blob_str(&downloadName));
  1081   1113     if( zMime ){
  1082   1114       if( strcmp(zMime, "text/html")==0 ){
  1083   1115         if( P("txt") ){
  1084   1116           style_submenu_element("Html", "Html",
  1085   1117                                 "%s/artifact?name=%s", g.zTop, zUuid);
  1086   1118         }else{
  1087   1119           renderAsHtml = 1;
  1088   1120           style_submenu_element("Text", "Text",
  1089         -                              "%s/artifact?name=%s&txt=1", g.zTop, zUuid);
         1121  +                              "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
  1090   1122         }
  1091   1123       }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){
  1092   1124         if( P("txt") ){
  1093   1125           style_submenu_element("Wiki", "Wiki",
  1094   1126                                 "%s/artifact?name=%s", g.zTop, zUuid);
  1095   1127         }else{
  1096   1128           renderAsWiki = 1;
  1097   1129           style_submenu_element("Text", "Text",
  1098         -                              "%s/artifact?name=%s&txt=1", g.zTop, zUuid);
         1130  +                              "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
  1099   1131         }
  1100   1132       }
  1101   1133     }
  1102         -  @ </blockquote>
  1103         -  @ <hr>
         1134  +  @ </p></blockquote>
         1135  +  @ <hr />
  1104   1136     content_get(rid, &content);
  1105   1137     if( renderAsWiki ){
  1106   1138       wiki_convert(&content, 0, 0);
  1107   1139     }else if( renderAsHtml ){
  1108   1140       @ <div>
  1109   1141       cgi_append_content(blob_buffer(&content), blob_size(&content));
  1110   1142       @ </div>
................................................................................
  1113   1145       @ <blockquote>
  1114   1146       if( zMime==0 ){
  1115   1147         @ <pre>
  1116   1148         @ %h(blob_str(&content))
  1117   1149         @ </pre>
  1118   1150         style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
  1119   1151       }else if( strncmp(zMime, "image/", 6)==0 ){
  1120         -      @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img>
         1152  +      @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&amp;m=%s(zMime)"></img>
  1121   1153         style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
  1122   1154       }else{
  1123   1155         @ <pre>
  1124   1156         hexdump(&content);
  1125   1157         @ </pre>
  1126   1158       }
  1127   1159       @ </blockquote>
................................................................................
  1133   1165   ** WEBPAGE: tinfo
  1134   1166   ** URL: /tinfo?name=ARTIFACTID
  1135   1167   **
  1136   1168   ** Show the details of a ticket change control artifact.
  1137   1169   */
  1138   1170   void tinfo_page(void){
  1139   1171     int rid;
  1140         -  Blob content;
  1141   1172     char *zDate;
  1142   1173     const char *zUuid;
  1143   1174     char zTktName[20];
  1144         -  Manifest m;
         1175  +  Manifest *pTktChng;
  1145   1176   
  1146   1177     login_check_credentials();
  1147   1178     if( !g.okRdTkt ){ login_needed(); return; }
  1148   1179     rid = name_to_rid_www("name");
  1149   1180     if( rid==0 ){ fossil_redirect_home(); }
  1150   1181     zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  1151   1182     if( g.okAdmin ){
  1152   1183       if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
  1153         -      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
         1184  +      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
  1154   1185               g.zTop, zUuid);
  1155   1186       }else{
  1156   1187         style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
  1157   1188               g.zTop, zUuid);
  1158   1189       }
  1159   1190     }
  1160         -  content_get(rid, &content);
  1161         -  if( manifest_parse(&m, &content)==0 ){
  1162         -    fossil_redirect_home();
  1163         -  }
  1164         -  if( m.type!=CFTYPE_TICKET ){
         1191  +  pTktChng = manifest_get(rid, CFTYPE_TICKET);
         1192  +  if( pTktChng==0 ){
  1165   1193       fossil_redirect_home();
  1166   1194     }
  1167   1195     style_header("Ticket Change Details");
  1168         -  zDate = db_text(0, "SELECT datetime(%.12f)", m.rDate);
  1169         -  memcpy(zTktName, m.zTicketUuid, 10);
         1196  +  zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
         1197  +  memcpy(zTktName, pTktChng->zTicketUuid, 10);
  1170   1198     zTktName[10] = 0;
  1171   1199     if( g.okHistory ){
  1172         -    @ <h2>Changes to ticket <a href="%s(m.zTicketUuid)">%s(zTktName)</a></h2>
         1200  +    @ <h2>Changes to ticket
         1201  +    @ <a href="%s(pTktChng->zTicketUuid)">%s(zTktName)</a></h2>
  1173   1202       @
  1174         -    @ <p>By %h(m.zUser) on %s(zDate).  See also:
         1203  +    @ <p>By %h(pTktChng->zUser) on %s(zDate).  See also:
  1175   1204       @ <a href="%s(g.zTop)/artifact/%T(zUuid)">artifact content</a>, and
  1176         -    @ <a href="%s(g.zTop)/tkthistory/%s(m.zTicketUuid)">ticket history</a>
  1177         -    @ </p>
         1205  +    @ <a href="%s(g.zTop)/tkthistory/%s(pTktChng->zTicketUuid)">ticket
         1206  +    @ history</a></p>
  1178   1207     }else{
  1179   1208       @ <h2>Changes to ticket %s(zTktName)</h2>
  1180   1209       @
  1181         -    @ <p>By %h(m.zUser) on %s(zDate).
         1210  +    @ <p>By %h(pTktChng->zUser) on %s(zDate).
  1182   1211       @ </p>
  1183   1212     }
  1184   1213     @
  1185   1214     @ <ol>
  1186   1215     free(zDate);
  1187         -  ticket_output_change_artifact(&m);
  1188         -  manifest_clear(&m);
         1216  +  ticket_output_change_artifact(pTktChng);
         1217  +  manifest_destroy(pTktChng);
  1189   1218     style_footer();
  1190   1219   }
  1191   1220   
  1192   1221   
  1193   1222   /*
  1194   1223   ** WEBPAGE: info
  1195   1224   ** URL: info/ARTIFACTID
................................................................................
  1240   1269     if( db_exists("SELECT 1 FROM plink WHERE pid=%d", rid) ){
  1241   1270       ci_page();
  1242   1271     }else
  1243   1272     {
  1244   1273       artifact_page();
  1245   1274     }
  1246   1275   }
         1276  +
         1277  +/*
         1278  +** Generate HTML that will present the user with a selection of
         1279  +** potential background colors for timeline entries.
         1280  +*/
         1281  +void render_color_chooser(
         1282  +  int fPropagate,             /* Default value for propagation */
         1283  +  const char *zDefaultColor,  /* The current default color */
         1284  +  const char *zIdPropagate,   /* ID of form element checkbox.  NULL for none */
         1285  +  const char *zId,            /* The ID of the form element */
         1286  +  const char *zIdCustom       /* ID of text box for custom color */
         1287  +){
         1288  +  static const struct SampleColors {
         1289  +     const char *zCName;
         1290  +     const char *zColor;
         1291  +  } aColor[] = {
         1292  +     { "(none)",  "" },
         1293  +     { "#f2dcdc", "#f2dcdc" },
         1294  +     { "#f0ffc0", "#f0ffc0" },
         1295  +     { "#bde5d6", "#bde5d6" },
         1296  +     { "#c0ffc0", "#c0ffc0" },
         1297  +     { "#c0fff0", "#c0fff0" },
         1298  +     { "#c0f0ff", "#c0f0ff" },
         1299  +     { "#d0c0ff", "#d0c0ff" },
         1300  +     { "#ffc0ff", "#ffc0ff" },
         1301  +     { "#ffc0d0", "#ffc0d0" },
         1302  +     { "#fff0c0", "#fff0c0" },
         1303  +     { "#c0c0c0", "#c0c0c0" },
         1304  +     { "custom",  "##"      },
         1305  +  };
         1306  +  int nColor = sizeof(aColor)/sizeof(aColor[0])-1;
         1307  +  int stdClrFound = 0;
         1308  +  int i;
         1309  +
         1310  +  @ <table border="0" cellpadding="0" cellspacing="1">
         1311  +  if( zIdPropagate ){
         1312  +    @ <tr><td colspan="6" align="left">
         1313  +    if( fPropagate ){
         1314  +      @ <input type="checkbox" name="%s(zIdPropagate)" checked="checked" />
         1315  +    }else{
         1316  +      @ <input type="checkbox" name="%s(zIdPropagate)" />
         1317  +    }
         1318  +    @ Propagate color to descendants</td></tr>
         1319  +  }
         1320  +  @ <tr>
         1321  +  for(i=0; i<nColor; i++){
         1322  +    if( aColor[i].zColor[0] ){
         1323  +      @ <td style="background-color: %h(aColor[i].zColor);">
         1324  +    }else{
         1325  +      @ <td>
         1326  +    }
         1327  +    if( strcmp(zDefaultColor, aColor[i].zColor)==0 ){
         1328  +      @ <input type="radio" name="%s(zId)" value="%h(aColor[i].zColor)"
         1329  +      @  checked="checked" />
         1330  +      stdClrFound=1;
         1331  +    }else{
         1332  +      @ <input type="radio" name="%s(zId)" value="%h(aColor[i].zColor)" />
         1333  +    }
         1334  +    @ %h(aColor[i].zCName)</td>
         1335  +    if( (i%6)==5 && i+1<nColor ){
         1336  +      @ </tr><tr>
         1337  +    }
         1338  +  }
         1339  +  @ </tr><tr>
         1340  +  if (stdClrFound){
         1341  +    @ <td colspan="6">
         1342  +    @ <input type="radio" name="%s(zId)" value="%h(aColor[nColor].zColor)" />
         1343  +  }else{
         1344  +    @ <td style="background-color: %h(zDefaultColor);" colspan="6">
         1345  +    @ <input type="radio" name="%s(zId)" value="%h(aColor[nColor].zColor)"
         1346  +    @  checked="checked" />
         1347  +  }
         1348  +  @ %h(aColor[i].zCName)&nbsp;
         1349  +  @ <input type="text" name="%s(zIdCustom)"
         1350  +  @  id="%s(zIdCustom)" class="checkinUserColor"
         1351  +  @  value="%h(stdClrFound?"":zDefaultColor)" />
         1352  +  @ </td>
         1353  +  @ </tr>
         1354  +  @ </table>
         1355  +}
  1247   1356   
  1248   1357   /*
  1249   1358   ** WEBPAGE: ci_edit
  1250   1359   ** URL:  ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
  1251   1360   **
  1252   1361   ** Present a dialog for updating properties of a baseline:
  1253   1362   **
................................................................................
  1270   1379     const char *zNewBrFlag;
  1271   1380     const char *zNewBranch;
  1272   1381     const char *zCloseFlag;
  1273   1382     int fPropagateColor;
  1274   1383     char *zUuid;
  1275   1384     Blob comment;
  1276   1385     Stmt q;
  1277         -  static const struct SampleColors {
  1278         -     const char *zCName;
  1279         -     const char *zColor;
  1280         -  } aColor[] = {
  1281         -     { "(none)",  "" },
  1282         -     { "#f2dcdc", "#f2dcdc" },
  1283         -     { "#f0ffc0", "#f0ffc0" },
  1284         -     { "#bde5d6", "#bde5d6" },
  1285         -     { "#c0ffc0", "#c0ffc0" },
  1286         -     { "#c0fff0", "#c0fff0" },
  1287         -     { "#c0f0ff", "#c0f0ff" },
  1288         -     { "#d0c0ff", "#d0c0ff" },
  1289         -     { "#ffc0ff", "#ffc0ff" },
  1290         -     { "#ffc0d0", "#ffc0d0" },
  1291         -     { "#fff0c0", "#fff0c0" },
  1292         -     { "#c0c0c0", "#c0c0c0" },
  1293         -  };
  1294         -  int nColor = sizeof(aColor)/sizeof(aColor[0]);
  1295         -  int i;
  1296   1386     
  1297   1387     login_check_credentials();
  1298   1388     if( !g.okWrite ){ login_needed(); return; }
  1299   1389     rid = name_to_rid(P("r"));
  1300   1390     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
  1301   1391     zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
  1302   1392                           "  FROM event WHERE objid=%d", rid);
................................................................................
  1312   1402     zDate = db_text(0, "SELECT datetime(mtime)"
  1313   1403                        "  FROM event WHERE objid=%d", rid);
  1314   1404     if( zDate==0 ) fossil_redirect_home();
  1315   1405     zNewDate = PD("dt",zDate);
  1316   1406     zColor = db_text("", "SELECT bgcolor"
  1317   1407                           "  FROM event WHERE objid=%d", rid);
  1318   1408     zNewColor = PD("clr",zColor);
         1409  +  if( strcmp(zNewColor,"##")==0 ){
         1410  +    zNewColor = P("clrcust");
         1411  +  }
  1319   1412     fPropagateColor = P("pclr")!=0;
  1320   1413     zNewTagFlag = P("newtag") ? " checked" : "";
  1321   1414     zNewTag = PD("tagname","");
  1322   1415     zNewBrFlag = P("newbr") ? " checked" : "";
  1323   1416     zNewBranch = PD("brname","");
  1324   1417     zCloseFlag = P("close") ? " checked" : "";
  1325   1418     if( P("apply") ){
................................................................................
  1424   1517     if( P("preview") ){
  1425   1518       Blob suffix;
  1426   1519       int nTag = 0;
  1427   1520       @ <b>Preview:</b>
  1428   1521       @ <blockquote>
  1429   1522       @ <table border=0>
  1430   1523       if( zNewColor && zNewColor[0] ){
  1431         -      @ <tr><td bgcolor="%h(zNewColor)">
         1524  +      @ <tr><td style="background-color: %h(zNewColor);">
  1432   1525       }else{
  1433   1526         @ <tr><td>
  1434   1527       }
  1435   1528       wiki_convert(&comment, 0, WIKI_INLINE);
  1436   1529       blob_zero(&suffix);
  1437   1530       blob_appendf(&suffix, "(user: %h", zNewUser);
  1438   1531       db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
................................................................................
  1449   1542         nTag++;
  1450   1543       }
  1451   1544       db_finalize(&q);
  1452   1545       blob_appendf(&suffix, ")");
  1453   1546       @ %s(blob_str(&suffix))
  1454   1547       @ </td></tr></table>
  1455   1548       @ </blockquote>
  1456         -    @ <hr>
         1549  +    @ <hr />
  1457   1550       blob_reset(&suffix);
  1458   1551     }
  1459   1552     @ <p>Make changes to attributes of check-in
  1460   1553     @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p>
  1461         -  @ <form action="%s(g.zBaseURL)/ci_edit" method="POST">
         1554  +  @ <form action="%s(g.zBaseURL)/ci_edit" method="post"><div>
  1462   1555     login_insert_csrf_secret();
  1463         -  @ <input type="hidden" name="r" value="%S(zUuid)">
         1556  +  @ <input type="hidden" name="r" value="%S(zUuid)" />
  1464   1557     @ <table border="0" cellspacing="10">
  1465   1558   
  1466   1559     @ <tr><td align="right" valign="top"><b>User:</b></td>
  1467   1560     @ <td valign="top">
  1468         -  @   <input type="text" name="u" size="20" value="%h(zNewUser)">
         1561  +  @   <input type="text" name="u" size="20" value="%h(zNewUser)" />
  1469   1562     @ </td></tr>
  1470   1563   
  1471   1564     @ <tr><td align="right" valign="top"><b>Comment:</b></td>
  1472   1565     @ <td valign="top">
  1473   1566     @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
  1474   1567     @ </td></tr>
  1475   1568   
  1476   1569     @ <tr><td align="right" valign="top"><b>Check-in Time:</b></td>
  1477   1570     @ <td valign="top">
  1478         -  @   <input type="text" name="dt" size="20" value="%h(zNewDate)">
         1571  +  @   <input type="text" name="dt" size="20" value="%h(zNewDate)" />
  1479   1572     @ </td></tr>
  1480   1573   
  1481   1574     @ <tr><td align="right" valign="top"><b>Background Color:</b></td>
  1482   1575     @ <td valign="top">
  1483         -  @ <table border=0 cellpadding=0 cellspacing=1>
  1484         -  @ <tr><td colspan="6" align="left">
  1485         -  if( fPropagateColor ){
  1486         -    @ <input type="checkbox" name="pclr" checked>
  1487         -  }else{
  1488         -    @ <input type="checkbox" name="pclr">
  1489         -  }
  1490         -  @ Propagate color to descendants</input></td></tr>
  1491         -  @ <tr>
  1492         -  for(i=0; i<nColor; i++){
  1493         -    if( aColor[i].zColor[0] ){
  1494         -      @ <td bgcolor="%h(aColor[i].zColor)">
  1495         -    }else{
  1496         -      @ <td>
  1497         -    }
  1498         -    if( strcmp(zNewColor, aColor[i].zColor)==0 ){
  1499         -      @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked>
  1500         -    }else{
  1501         -      @ <input type="radio" name="clr" value="%h(aColor[i].zColor)">
  1502         -    }
  1503         -    @ %h(aColor[i].zCName)</input></td>
  1504         -    if( (i%6)==5 && i+1<nColor ){
  1505         -      @ </tr><tr>
  1506         -    }
  1507         -  }
  1508         -  @ </tr>
  1509         -  @ </table>
         1576  +  render_color_chooser(fPropagateColor, zNewColor, "pclr", "clr", "clrcust");
  1510   1577     @ </td></tr>
  1511   1578   
  1512   1579     @ <tr><td align="right" valign="top"><b>Tags:</b></td>
  1513   1580     @ <td valign="top">
  1514         -  @ <input type="checkbox" name="newtag"%s(zNewTagFlag)>
         1581  +  @ <input type="checkbox" name="newtag"%s(zNewTagFlag) />
  1515   1582     @ Add the following new tag name to this check-in:
  1516         -  @ <input type="text" width="15" name="tagname" value="%h(zNewTag)">
         1583  +  @ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)" />
  1517   1584     db_prepare(&q,
  1518   1585        "SELECT tag.tagid, tagname FROM tagxref, tag"
  1519   1586        " WHERE tagxref.rid=%d AND tagtype>0 AND tagxref.tagid=tag.tagid"
  1520   1587        " ORDER BY CASE WHEN tagname GLOB 'sym-*' THEN substr(tagname,5)"
  1521   1588        "               ELSE tagname END",
  1522   1589        rid
  1523   1590     );
  1524   1591     while( db_step(&q)==SQLITE_ROW ){
  1525   1592       int tagid = db_column_int(&q, 0);
  1526   1593       const char *zTagName = db_column_text(&q, 1);
  1527   1594       char zLabel[30];
  1528   1595       sprintf(zLabel, "c%d", tagid);
  1529   1596       if( P(zLabel) ){
  1530         -      @ <br><input type="checkbox" name="c%d(tagid)" checked>
         1597  +      @ <br /><input type="checkbox" name="c%d(tagid)" checked="checked" />
  1531   1598       }else{
  1532         -      @ <br><input type="checkbox" name="c%d(tagid)">
         1599  +      @ <br /><input type="checkbox" name="c%d(tagid)" />
  1533   1600       }
  1534   1601       if( strncmp(zTagName, "sym-", 4)==0 ){
  1535   1602         @ Cancel tag <b>%h(&zTagName[4])</b>
  1536   1603       }else{
  1537   1604         @ Cancel special tag <b>%h(zTagName)</b>
  1538   1605       }
  1539   1606     }
  1540   1607     db_finalize(&q);
  1541   1608     @ </td></tr>
  1542   1609   
  1543   1610     @ <tr><td align="right" valign="top"><b>Branching:</b></td>
  1544   1611     @ <td valign="top">
  1545         -  @ <input type="checkbox" name="newbr"%s(zNewBrFlag)>
         1612  +  @ <input type="checkbox" name="newbr"%s(zNewBrFlag) />
  1546   1613     @ Make this check-in the start of a new branch named:
  1547         -  @ <input type="text" width="15" name="brname" value="%h(zNewBranch)">
         1614  +  @ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)" />
  1548   1615     @ </td></tr>
  1549   1616   
  1550   1617     if( is_a_leaf(rid)
  1551   1618      && !db_exists("SELECT 1 FROM tagxref "
  1552   1619                    " WHERE tagid=%d AND rid=%d AND tagtype>0",
  1553   1620                    TAG_CLOSED, rid)
  1554   1621     ){
  1555   1622       @ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td>
  1556   1623       @ <td valign="top">
  1557         -    @ <input type="checkbox" name="close"%s(zCloseFlag)>
         1624  +    @ <input type="checkbox" name="close"%s(zCloseFlag) />
  1558   1625       @ Mark this leaf as "closed" so that it no longer appears on the
  1559   1626       @ "leaves" page and is no longer labeled as a "<b>Leaf</b>".
  1560   1627       @ </td></tr>
  1561   1628     }
  1562   1629   
  1563   1630   
  1564   1631     @ <tr><td colspan="2">
  1565         -  @ <input type="submit" name="preview" value="Preview">
  1566         -  @ <input type="submit" name="apply" value="Apply Changes">
  1567         -  @ <input type="submit" name="cancel" value="Cancel">
         1632  +  @ <input type="submit" name="preview" value="Preview" />
         1633  +  @ <input type="submit" name="apply" value="Apply Changes" />
         1634  +  @ <input type="submit" name="cancel" value="Cancel" />
  1568   1635     @ </td></tr>
  1569   1636     @ </table>
  1570         -  @ </form>
         1637  +  @ </div></form>
  1571   1638     style_footer();
  1572   1639   }

Changes to src/login.c.

    35     35   ** not really the point.  The anonymous login keeps search-engine
    36     36   ** crawlers and site download tools like wget from walking change
    37     37   ** logs and downloading diffs of very version of the archive that
    38     38   ** has ever existed, and things like that.
    39     39   */
    40     40   #include "config.h"
    41     41   #include "login.h"
    42         -#ifdef __MINGW32__
           42  +#if defined(_WIN32)  
    43     43   #  include <windows.h>           /* for Sleep */
    44         -#  define sleep Sleep            /* windows does not have sleep, but Sleep */
           44  +#  if defined(__MINGW32__) || defined(_MSC_VER)
           45  +#    define sleep Sleep            /* windows does not have sleep, but Sleep */
           46  +#  endif
    45     47   #endif
    46     48   #include <time.h>
    47     49   
    48     50   /*
    49     51   ** Return the name of the login cookie
    50     52   */
    51     53   static char *login_cookie_name(void){
    52     54     static char *zCookieName = 0;
    53     55     if( zCookieName==0 ){
    54         -    int n = strlen(g.zTop);
    55         -    zCookieName = malloc( n*2+16 );
    56         -                      /* 0123456789 12345 */
    57         -    strcpy(zCookieName, "fossil_login_");
    58         -    encode16((unsigned char*)g.zTop, (unsigned char*)&zCookieName[13], n);
           56  +    unsigned int h = 0;
           57  +    const char *z = g.zBaseURL;
           58  +    while( *z ){ h = (h<<3) ^ (h>>26) ^ *(z++); }
           59  +    zCookieName = mprintf("fossil_login_%08x", h);
    59     60     }
    60     61     return zCookieName;
    61     62   }
    62     63   
    63     64   /*
    64     65   ** Redirect to the page specified by the "g" query parameter.
    65     66   ** Or if there is no "g" query parameter, redirect to the homepage.
................................................................................
   149    150     if( g.okPassword && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
   150    151       zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin);
   151    152       if( db_int(1, "SELECT 0 FROM user"
   152    153                     " WHERE uid=%d AND (pw=%Q OR pw=%Q)", 
   153    154                     g.userUid, zPasswd, zSha1Pw) ){
   154    155         sleep(1);
   155    156         zErrMsg = 
   156         -         @ <p><font color="red">
          157  +         @ <p><span class="loginError">
   157    158            @ You entered an incorrect old password while attempting to change
   158    159            @ your password.  Your password is unchanged.
   159         -         @ </font></p>
          160  +         @ </span></p>
   160    161         ;
   161    162       }else if( strcmp(zNew1,zNew2)!=0 ){
   162    163         zErrMsg = 
   163         -         @ <p><font color="red">
          164  +         @ <p><span class="loginError">
   164    165            @ The two copies of your new passwords do not match.
   165    166            @ Your password is unchanged.
   166         -         @ </font></p>
          167  +         @ </span></p>
   167    168         ;
   168    169       }else{
   169    170         char *zNewPw = sha1_shared_secret(zNew1, g.zLogin);
   170    171         db_multi_exec(
   171    172            "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
   172    173         );
   173    174         redirect_to_g();
................................................................................
   202    203           "   AND login NOT IN ('anonymous','nobody','developer','reader')"
   203    204           "   AND (pw=%Q OR pw=%Q)",
   204    205           zUsername, zPasswd, zSha1Pw
   205    206       );
   206    207       if( uid<=0 ){
   207    208         sleep(1);
   208    209         zErrMsg = 
   209         -         @ <p><font color="red">
          210  +         @ <p><span class="loginError">
   210    211            @ You entered an unknown user or an incorrect password.
   211         -         @ </font></p>
          212  +         @ </span></p>
   212    213         ;
   213    214       }else{
   214    215         char *zCookie;
   215    216         const char *zCookieName = login_cookie_name();
   216    217         const char *zExpire = db_get("cookie-expire","8766");
   217    218         int expires = atoi(zExpire)*3600;
   218    219         const char *zIpAddr = PD("REMOTE_ADDR","nil");
................................................................................
   225    226           zCookie, zIpAddr, expires, uid
   226    227         );
   227    228         redirect_to_g();
   228    229       }
   229    230     }
   230    231     style_header("Login/Logout");
   231    232     @ %s(zErrMsg)
   232         -  @ <form action="login" method="POST">
          233  +  @ <form action="login" method="post">
   233    234     if( P("g") ){
   234         -    @ <input type="hidden" name="g" value="%h(P("g"))">
          235  +    @ <input type="hidden" name="g" value="%h(P("g"))" />
   235    236     }
   236         -  @ <table align="left" hspace="10">
          237  +  @ <table class="login_out">
   237    238     @ <tr>
   238         -  @   <td align="right">User ID:</td>
          239  +  @   <td class="login_out_label">User ID:</td>
   239    240     if( anonFlag ){
   240         -    @   <td><input type="text" id="u" name="u" value="anonymous" size=30></td>
          241  +    @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
   241    242     }else{
   242         -    @   <td><input type="text" id="u" name="u" value="" size=30></td>
          243  +    @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
   243    244     }
   244    245     @ </tr>
   245    246     @ <tr>
   246         -  @  <td align="right">Password:</td>
   247         -  @   <td><input type="password" id="p" name="p" value="" size=30></td>
          247  +  @  <td class="login_out_label">Password:</td>
          248  +  @   <td><input type="password" id="p" name="p" value="" size="30" /></td>
   248    249     @ </tr>
   249    250     if( g.zLogin==0 ){
   250    251       zAnonPw = db_text(0, "SELECT pw FROM user"
   251    252                            " WHERE login='anonymous'"
   252    253                            "   AND cap!=''");
   253    254     }
   254    255     @ <tr>
   255    256     @   <td></td>
   256         -  @   <td><input type="submit" name="in" value="Login"></td>
          257  +  @   <td><input type="submit" name="in" value="Login" /></td>
   257    258     @ </tr>
   258    259     @ </table>
   259         -  @ <script>document.getElementById('u').focus()</script>
          260  +  @ <script type="text/JavaScript">document.getElementById('u').focus()</script>
   260    261     if( g.zLogin==0 ){
   261    262       @ <p>Enter
   262    263     }else{
   263    264       @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
   264    265       @ <p>To change your login to a different user, enter
   265    266     }
   266    267     @ your user-id and password at the left and press the
................................................................................
   269    270     @ the login to take.</p>
   270    271     if( zAnonPw ){
   271    272       unsigned int uSeed = captcha_seed();
   272    273       char const *zDecoded = captcha_decode(uSeed);
   273    274       int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
   274    275       char *zCaptcha = captcha_render(zDecoded);
   275    276   
   276         -    @ <input type="hidden" name="cs" value="%u(uSeed)"/>
   277         -    @ <p>Visitors may enter <b>anonymous</b> as the user-ID with
          277  +    @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
          278  +    @ Visitors may enter <b>anonymous</b> as the user-ID with
   278    279       @ the 8-character hexadecimal password shown below:</p>
   279         -    @ <center><table border="1" cellpadding="10"><tr><td><pre>
          280  +    @ <div class="captcha"><table class="captcha"><tr><td><pre>
   280    281       @ %s(zCaptcha)
   281    282       @ </pre></td></tr></table>
   282    283       if( bAutoCaptcha ) {
   283    284           @ <input type="button" value="Fill out captcha"
   284    285           @  onclick="document.getElementById('u').value='anonymous';
   285         -        @           document.getElementById('p').value='%s(zDecoded)';"/>
          286  +        @           document.getElementById('p').value='%s(zDecoded)';" />
   286    287       }
   287         -    @ </center>
          288  +    @ </div>
   288    289       free(zCaptcha);
   289    290     }
   290    291     if( g.zLogin ){
   291         -    @ <br clear="both"><hr>
          292  +    @ <hr />
   292    293       @ <p>To log off the system (and delete your login cookie)
   293         -    @  press the following button:<br>
   294         -    @ <input type="submit" name="out" value="Logout"></p>
          294  +    @  press the following button:<br />
          295  +    @ <input type="submit" name="out" value="Logout" /></p>
   295    296     }
   296    297     @ </form>
   297    298     if( g.okPassword ){
   298         -    @ <br clear="both"><hr>
          299  +    @ <hr />
   299    300       @ <p>To change your password, enter your old password and your
   300    301       @ new password twice below then press the "Change Password"
   301    302       @ button.</p>
   302         -    @ <form action="login" method="POST">
          303  +    @ <form action="login" method="post">
   303    304       @ <table>
   304         -    @ <tr><td align="right">Old Password:</td>
   305         -    @ <td><input type="password" name="p" size=30></td></tr>
   306         -    @ <tr><td align="right">New Password:</td>
   307         -    @ <td><input type="password" name="n1" size=30></td></tr>
   308         -    @ <tr><td align="right">Repeat New Password:</td>
   309         -    @ <td><input type="password" name="n2" size=30></td></tr>
          305  +    @ <tr><td class="login_out_label">Old Password:</td>
          306  +    @ <td><input type="password" name="p" size="30" /></td></tr>
          307  +    @ <tr><td class="login_out_label">New Password:</td>
          308  +    @ <td><input type="password" name="n1" size="30" /></td></tr>
          309  +    @ <tr><td class="login_out_label">Repeat New Password:</td>
          310  +    @ <td><input type="password" name="n2" size="30" /></td></tr>
   310    311       @ <tr><td></td>
   311         -    @ <td><input type="submit" value="Change Password"></td></tr>
          312  +    @ <td><input type="submit" value="Change Password" /></td></tr>
   312    313       @ </table>
   313    314       @ </form>
   314    315     }
   315    316     style_footer();
   316    317   }
   317    318   
   318    319   
................................................................................
   349    350       g.noPswd = 1;
   350    351       strcpy(g.zCsrfToken, "localhost");
   351    352     }
   352    353   
   353    354     /* Check the login cookie to see if it matches a known valid user.
   354    355     */
   355    356     if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
   356         -    if( isdigit(zCookie[0]) ){
          357  +    if( fossil_isdigit(zCookie[0]) ){
   357    358         /* Cookies of the form "uid/randomness".  There must be a
   358    359         ** corresponding entry in the user table. */
   359    360         uid = db_int(0, 
   360    361               "SELECT uid FROM user"
   361    362               " WHERE uid=%d"
   362    363               "   AND cookie=%Q"
   363    364               "   AND ipaddr=%Q"
................................................................................
   592    593   */
   593    594   void login_anonymous_available(void){
   594    595     if( !g.okHistory &&
   595    596         db_exists("SELECT 1 FROM user"
   596    597                   " WHERE login='anonymous'"
   597    598                   "   AND cap LIKE '%%h%%'") ){
   598    599       const char *zUrl = PD("REQUEST_URI", "index");
   599         -    @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
   600         -    @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
          600  +    @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
          601  +    @ Use <a href="%s(g.zTop)/login?anon=1&amp;g=%T(zUrl)">anonymous login</a>
   601    602       @ to enable hyperlinks.</p>
   602    603     }
   603    604   }
   604    605   
   605    606   /*
   606    607   ** While rendering a form, call this routine to add the Anti-CSRF token
   607    608   ** as a hidden element of the form.
   608    609   */
   609    610   void login_insert_csrf_secret(void){
   610         -  @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)">
          611  +  @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" />
   611    612   }
   612    613   
   613    614   /*
   614    615   ** Before using the results of a form, first call this routine to verify
   615    616   ** that ths Anti-CSRF token is present and is valid.  If the Anti-CSRF token
   616    617   ** is missing or is incorrect, that indicates a cross-site scripting attach
   617    618   ** so emits an error message and abort.

Changes to src/main.c.

    81     81     Th_Interp *interp;      /* The TH1 interpreter */
    82     82     FILE *httpIn;           /* Accept HTTP input from here */
    83     83     FILE *httpOut;          /* Send HTTP output here */
    84     84     int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
    85     85     int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
    86     86     int *aCommitFile;       /* Array of files to be committed */
    87     87     int markPrivate;        /* All new artifacts are private if true */
           88  +  int clockSkewSeen;      /* True if clocks on client and server out of sync */
    88     89   
    89     90     int urlIsFile;          /* True if a "file:" url */
    90     91     int urlIsHttps;         /* True if a "https:" url */
           92  +  int urlIsSsh;           /* True if an "ssh:" url */
    91     93     char *urlName;          /* Hostname for http: or filename for file: */
    92     94     char *urlHostname;      /* The HOST: parameter on http headers */
    93     95     char *urlProtocol;      /* "http" or "https" */
    94     96     int urlPort;            /* TCP port number for http: or https: */
    95     97     int urlDfltPort;        /* The default port for the given protocol */
    96     98     char *urlPath;          /* Pathname for http: */
    97     99     char *urlUser;          /* User id for http: */
    98    100     char *urlPasswd;        /* Password for http: */
    99    101     char *urlCanonical;     /* Canonical representation of the URL */
   100    102     char *urlProxyAuth;     /* Proxy-Authorizer: string */
          103  +  char *urlFossil;        /* The path of the ?fossil=path suffix on ssh: */
   101    104     int dontKeepUrl;        /* Do not persist the URL */
   102    105   
   103    106     const char *zLogin;     /* Login name.  "" if not logged in. */
   104    107     int noPswd;             /* Logged in without password (on 127.0.0.1) */
   105    108     int userUid;            /* Integer user id */
   106    109   
   107    110     /* Information used to populate the RCVFROM table */
................................................................................
   218    221   /*
   219    222   ** This procedure runs first.
   220    223   */
   221    224   int main(int argc, char **argv){
   222    225     const char *zCmdName = "unknown";
   223    226     int idx;
   224    227     int rc;
          228  +  int mightBeCgi;
   225    229   
   226    230     sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
   227    231     g.now = time(0);
   228    232     g.argc = argc;
   229    233     g.argv = argv;
   230         -  if( getenv("GATEWAY_INTERFACE")!=0 ){
   231         -    zCmdName = "cgi";
   232         -  }else if( argc<2 ){
   233         -    fprintf(stderr, "Usage: %s COMMAND ...\n"
   234         -                    "\"%s help\" for a list of available commands\n"
   235         -                    "\"%s help COMMAND\" for specific details\n",
   236         -                    argv[0], argv[0], argv[0]);
   237         -    fossil_exit(1);
          234  +  mightBeCgi = getenv("GATEWAY_INTERFACE")!=0;
          235  +  if( argc<2 ){
          236  +    if( mightBeCgi ){
          237  +      zCmdName = "cgi";
          238  +    }else{
          239  +      fprintf(stderr, "Usage: %s COMMAND ...\n"
          240  +                      "\"%s help\" for a list of available commands\n"
          241  +                      "\"%s help COMMAND\" for specific details\n",
          242  +                      argv[0], argv[0], argv[0]);
          243  +      fossil_exit(1);
          244  +    }
   238    245     }else{
   239    246       g.fQuiet = find_option("quiet", 0, 0)!=0;
   240    247       g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
   241    248       g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
   242    249       g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
   243    250       g.zLogin = find_option("user", "U", 1);
   244    251       zCmdName = argv[1];
   245    252     }
   246    253     rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
          254  +  if( rc==1 && mightBeCgi ){
          255  +    rc = name_search("cgi", aCommand, count(aCommand), &idx);
          256  +  }
   247    257     if( rc==1 ){
   248    258       fprintf(stderr,"%s: unknown command: %s\n"
   249    259                      "%s: use \"help\" for more information\n",
   250    260                      argv[0], zCmdName, argv[0]);
   251    261       fossil_exit(1);
   252    262     }else if( rc==2 ){
   253    263       fprintf(stderr,"%s: ambiguous command prefix: %s\n"
................................................................................
   286    296     static int once = 1;
   287    297     mainInFatalError = 1;
   288    298     va_start(ap, zFormat);
   289    299     z = vmprintf(zFormat, ap);
   290    300     va_end(ap);
   291    301     if( g.cgiOutput && once ){
   292    302       once = 0;
   293         -    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
          303  +    cgi_printf("<p class=\"generalError\">%h</p>", z);
   294    304       cgi_reply();
   295    305     }else{
   296    306       fprintf(stderr, "%s: %s\n", g.argv[0], z);
   297    307     }
   298    308     db_force_rollback();
   299    309     fossil_exit(1);
   300    310   }
................................................................................
   303    313     va_list ap;
   304    314     mainInFatalError = 1;
   305    315     va_start(ap, zFormat);
   306    316     z = vmprintf(zFormat, ap);
   307    317     va_end(ap);
   308    318     if( g.cgiOutput ){
   309    319       g.cgiOutput = 0;
   310         -    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
          320  +    cgi_printf("<p class=\"generalError\">%h</p>", z);
   311    321       cgi_reply();
   312    322     }else{
   313    323       fprintf(stderr, "%s: %s\n", g.argv[0], z);
   314    324     }
   315    325     db_force_rollback();
   316    326     fossil_exit(1);
   317    327   }
................................................................................
   331    341     if( mainInFatalError ) return;
   332    342     mainInFatalError = 1;
   333    343     va_start(ap, zFormat);
   334    344     z = vmprintf(zFormat, ap);
   335    345     va_end(ap);
   336    346     if( g.cgiOutput ){
   337    347       g.cgiOutput = 0;
   338         -    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
          348  +    cgi_printf("<p class=\"generalError\">%h</p>", z);
   339    349       cgi_reply();
   340    350     }else{
   341    351       fprintf(stderr, "%s: %s\n", g.argv[0], z);
   342    352     }
   343    353     db_force_rollback();
   344    354     fossil_exit(1);
   345    355   }
................................................................................
   349    359   void fossil_warning(const char *zFormat, ...){
   350    360     char *z;
   351    361     va_list ap;
   352    362     va_start(ap, zFormat);
   353    363     z = vmprintf(zFormat, ap);
   354    364     va_end(ap);
   355    365     if( g.cgiOutput ){
   356         -    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
          366  +    cgi_printf("<p class=\"generalError\">%h</p>", z);
   357    367     }else{
   358    368       fprintf(stderr, "%s: %s\n", g.argv[0], z);
   359    369     }
   360    370   }
          371  +
          372  +/*
          373  +** Malloc and free routines that cannot fail
          374  +*/
          375  +void *fossil_malloc(size_t n){
          376  +  void *p = malloc(n);
          377  +  if( p==0 ) fossil_panic("out of memory");
          378  +  return p;
          379  +}
          380  +void fossil_free(void *p){
          381  +  free(p);
          382  +}
          383  +void *fossil_realloc(void *p, size_t n){
          384  +  p = realloc(p, n);
          385  +  if( p==0 ) fossil_panic("out of memory");
          386  +  return p;
          387  +}
          388  +
          389  +/*
          390  +** This function implements a cross-platform "system()" interface.
          391  +*/
          392  +int fossil_system(const char *zOrigCmd){
          393  +  int rc;
          394  +#if defined(_WIN32)
          395  +  /* On windows, we have to put double-quotes around the entire command.
          396  +  ** Who knows why - this is just the way windows works.
          397  +  */
          398  +  char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
          399  +  rc = system(zNewCmd);
          400  +  free(zNewCmd);
          401  +#else
          402  +  /* On unix, evaluate the command directly.
          403  +  */
          404  +  rc = system(zOrigCmd);
          405  +#endif 
          406  +  return rc; 
          407  +}
          408  +
          409  +
   361    410   
   362    411   /*
   363    412   ** Return a name for an SQLite error code
   364    413   */
   365    414   static const char *sqlite_error_code_name(int iCode){
   366    415     static char zCode[30];
   367    416     switch( iCode & 0xff ){
................................................................................
   586    635       }else{
   587    636         putchar(*z);
   588    637         z++;
   589    638       }
   590    639     }
   591    640     putchar('\n');
   592    641   }
          642  +
          643  +/*
          644  +** WEBPAGE: help
          645  +** URL: /help?cmd=CMD
          646  +*/
          647  +void help_page(void){
          648  +    const char * zCmd = P("cmd");
          649  +    
          650  +    style_header("Command line help %s%s",zCmd?" - ":"",zCmd?zCmd:"");
          651  +    if( zCmd ){
          652  +      int rc, idx;
          653  +      char *z, *s, *d;
          654  +
          655  +      @ <h1>%s(zCmd)</h1>
          656  +      rc = name_search(zCmd, aCommand, count(aCommand), &idx);
          657  +      if( rc==1 ){
          658  +        @ unknown command: %s(zCmd)
          659  +      }else if( rc==2 ){
          660  +        @ ambiguous command prefix: %s(zCmd)
          661  +      }else{
          662  +        z = (char*)aCmdHelp[idx];
          663  +        if( z==0 ){
          664  +          @ no help available for the %s(aCommand[idx].zName) command
          665  +        }else{
          666  +          z=s=d=mprintf("%s",z);
          667  +	  while( *s ){
          668  +	    if( *s=='%' && strncmp(s, "%fossil", 7)==0 ){
          669  +	      s++;
          670  +	    }else{
          671  +	      *d++ = *s++;
          672  +	    }
          673  +	  }
          674  +	  *d = 0;
          675  +	  @ <pre>%s(z)</pre>
          676  +	  free(z);
          677  +	}
          678  +      }
          679  +      @ <hr/><a href="help">available commands</a> in fossil
          680  +      @ version %s(MANIFEST_VERSION" "MANIFEST_DATE) UTC
          681  +    }else{
          682  +      int i;
          683  +      
          684  +      @ <h1>Available commands</h1>
          685  +      for(i=0; i<count(aCommand); i++){
          686  +        if( strncmp(aCommand[i].zName,"test",4)==0 ) continue;
          687  +        @ <kbd><a href="help?cmd=%s(aCommand[i].zName)">
          688  +        @ %s(aCommand[i].zName)</a></kbd>
          689  +      }
          690  +      @ <hr/>fossil version %s(MANIFEST_VERSION" "MANIFEST_DATE) UTC
          691  +    }
          692  +    style_footer();
          693  +}
   593    694   
   594    695   /*
   595    696   ** Set the g.zBaseURL value to the full URL for the toplevel of
   596    697   ** the fossil tree.  Set g.zTop to g.zBaseURL without the
   597    698   ** leading "http://" and the host and port.
   598    699   */
   599    700   void set_base_url(void){
................................................................................
   628    729   ** zRepo might be a directory itself.  In that case chroot into
   629    730   ** the directory zRepo.
   630    731   **
   631    732   ** Assume the user-id and group-id of the repository, or if zRepo
   632    733   ** is a directory, of that directory.
   633    734   */
   634    735   static char *enter_chroot_jail(char *zRepo){
   635         -#if !defined(__MINGW32__)
          736  +#if !defined(_WIN32)
   636    737     if( getuid()==0 ){
   637    738       int i;
   638    739       struct stat sStat;
   639    740       Blob dir;
   640    741       char *zDir;
   641    742   
   642    743       file_canonical_name(zRepo, &dir);
................................................................................
   700    801       while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
   701    802       zRepo = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
   702    803   
   703    804       /* To avoid mischief, make sure the repository basename contains no
   704    805       ** characters other than alphanumerics, "-", and "_".
   705    806       */
   706    807       for(j=strlen(g.zRepositoryName)+1, k=0; k<i-1; j++, k++){
   707         -      if( !isalnum(zRepo[j]) && zRepo[j]!='-' ) zRepo[j] = '_';
          808  +      if( !fossil_isalnum(zRepo[j]) && zRepo[j]!='-' ) zRepo[j] = '_';
   708    809       }
   709    810       if( zRepo[0]=='/' && zRepo[1]=='/' ) zRepo++;
   710    811   
   711    812       if( file_size(zRepo)<1024 ){
   712    813         if( zNotFound ){
   713    814           cgi_redirect(zNotFound);
   714    815         }else{
................................................................................
   806    907     if( g.argc==3 && strcmp(g.argv[1],"cgi")==0 ){
   807    908       zFile = g.argv[2];
   808    909     }else{
   809    910       zFile = g.argv[1];
   810    911     }
   811    912     g.httpOut = stdout;
   812    913     g.httpIn = stdin;
   813         -#ifdef __MINGW32__
          914  +#if defined(_WIN32)
   814    915     /* Set binary mode on windows to avoid undesired translations
   815    916     ** between \n and \r\n. */
   816    917     setmode(_fileno(g.httpOut), _O_BINARY);
   817    918     setmode(_fileno(g.httpIn), _O_BINARY);
   818    919   #endif
   819    920   #ifdef __EMX__
   820    921     /* Similar hack for OS/2 */
................................................................................
   912   1013   ** not select a valid repository and the --notfound option is available,
   913   1014   ** then the server redirects (HTTP code 302) to the URL of --notfound.
   914   1015   */
   915   1016   void cmd_http(void){
   916   1017     const char *zIpAddr;
   917   1018     const char *zNotFound;
   918   1019     zNotFound = find_option("notfound", 0, 1);
         1020  +  g.cgiOutput = 1;
   919   1021     if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
   920         -    cgi_panic("no repository specified");
         1022  +    fossil_fatal("no repository specified");
   921   1023     }
   922         -  g.cgiOutput = 1;
   923   1024     g.fullHttpReply = 1;
   924   1025     if( g.argc==6 ){
   925   1026       g.httpIn = fopen(g.argv[3], "rb");
   926   1027       g.httpOut = fopen(g.argv[4], "wb");
   927   1028       zIpAddr = g.argv[5];
   928   1029     }else{
   929   1030       g.httpIn = stdin;
................................................................................
   933   1034     find_server_repository(0);
   934   1035     g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
   935   1036     cgi_handle_http_request(zIpAddr);
   936   1037     process_one_web_page(zNotFound);
   937   1038   }
   938   1039   
   939   1040   /*
         1041  +** Note that the following command is used by ssh:// processing.
         1042  +**
   940   1043   ** COMMAND: test-http
   941   1044   ** Works like the http command but gives setup permission to all users.
   942   1045   */
   943   1046   void cmd_test_http(void){
   944   1047     login_set_capabilities("s");
   945         -  cmd_http();
         1048  +  g.httpIn = stdin;
         1049  +  g.httpOut = stdout;
         1050  +  find_server_repository(0);
         1051  +  g.cgiOutput = 1;
         1052  +  g.fullHttpReply = 1;
         1053  +  cgi_handle_http_request(0);
         1054  +  process_one_web_page(0);
   946   1055   }
   947   1056   
   948         -#ifndef __MINGW32__
         1057  +#if !defined(_WIN32)
   949   1058   #if !defined(__DARWIN__) && !defined(__APPLE__)
   950   1059   /*
   951   1060   ** Search for an executable on the PATH environment variable.
   952   1061   ** Return true (1) if found and false (0) if not found.
   953   1062   */
   954   1063   static int binaryOnPath(const char *zBinary){
   955   1064     const char *zPath = getenv("PATH");
................................................................................
   980   1089   ** Open a socket and begin listening and responding to HTTP requests on
   981   1090   ** TCP port 8080, or on any other TCP port defined by the -P or
   982   1091   ** --port option.  The optional argument is the name of the repository.
   983   1092   ** The repository argument may be omitted if the working directory is
   984   1093   ** within an open checkout.
   985   1094   **
   986   1095   ** The "ui" command automatically starts a web browser after initializing
   987         -** the web server.
         1096  +** the web server.  The "ui" command also binds to 127.0.0.1 and so will
         1097  +** only process HTTP traffic from the local machine.
   988   1098   **
   989   1099   ** In the "server" command, the REPOSITORY can be a directory (aka folder)
   990   1100   ** that contains one or more respositories with names ending in ".fossil".
   991   1101   ** In that case, the first element of the URL is used to select among the
   992   1102   ** various repositories.
   993   1103   */
   994   1104   void cmd_webserver(void){
   995   1105     int iPort, mxPort;        /* Range of TCP ports allowed */
   996   1106     const char *zPort;        /* Value of the --port option */
   997   1107     char *zBrowser;           /* Name of web browser program */
   998   1108     char *zBrowserCmd = 0;    /* Command to launch the web browser */
   999   1109     int isUiCmd;              /* True if command is "ui", not "server' */
  1000   1110     const char *zNotFound;    /* The --notfound option or NULL */
         1111  +  int flags = 0;            /* Server flags */
  1001   1112   
  1002         -#ifdef __MINGW32__
         1113  +#if defined(_WIN32)
  1003   1114     const char *zStopperFile;    /* Name of file used to terminate server */
  1004   1115     zStopperFile = find_option("stopper", 0, 1);
  1005   1116   #endif
  1006   1117   
  1007   1118     g.thTrace = find_option("th-trace", 0, 0)!=0;
  1008   1119     if( g.thTrace ){
  1009   1120       blob_zero(&g.thLog);
  1010   1121     }
  1011   1122     zPort = find_option("port", "P", 1);
  1012   1123     zNotFound = find_option("notfound", 0, 1);
  1013   1124     if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  1014   1125     isUiCmd = g.argv[1][0]=='u';
         1126  +  if( isUiCmd ) flags |= HTTP_SERVER_LOCALHOST;
  1015   1127     find_server_repository(isUiCmd);
  1016   1128     if( zPort ){
  1017   1129       iPort = mxPort = atoi(zPort);
  1018   1130     }else{
  1019   1131       iPort = db_get_int("http-port", 8080);
  1020   1132       mxPort = iPort+100;
  1021   1133     }
  1022         -#ifndef __MINGW32__
         1134  +#if !defined(_WIN32)
  1023   1135     /* Unix implementation */
  1024   1136     if( isUiCmd ){
  1025   1137   #if !defined(__DARWIN__) && !defined(__APPLE__)
  1026   1138       zBrowser = db_get("web-browser", 0);
  1027   1139       if( zBrowser==0 ){
  1028   1140         static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
  1029   1141         int i;
................................................................................
  1037   1149       }
  1038   1150   #else
  1039   1151       zBrowser = db_get("web-browser", "open");
  1040   1152   #endif
  1041   1153       zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);
  1042   1154     }
  1043   1155     db_close();
  1044         -  if( cgi_http_server(iPort, mxPort, zBrowserCmd) ){
         1156  +  if( cgi_http_server(iPort, mxPort, zBrowserCmd, flags) ){
  1045   1157       fossil_fatal("unable to listen on TCP socket %d", iPort);
  1046   1158     }
  1047   1159     g.httpIn = stdin;
  1048   1160     g.httpOut = stdout;
  1049   1161     if( g.fHttpTrace || g.fSqlTrace ){
  1050   1162       fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
  1051   1163     }
................................................................................
  1057   1169   #else
  1058   1170     /* Win32 implementation */
  1059   1171     if( isUiCmd ){
  1060   1172       zBrowser = db_get("web-browser", "start");
  1061   1173       zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
  1062   1174     }
  1063   1175     db_close();
  1064         -  win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound);
         1176  +  win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound, flags);
  1065   1177   #endif
  1066   1178   }
         1179  +
         1180  +/*
         1181  +** COMMAND: sqlite3
         1182  +**
         1183  +** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS?
         1184  +**
         1185  +** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS.
         1186  +** If DATABASE is omitted, then the repository that serves the working
         1187  +** directory is opened.
         1188  +**
         1189  +** WARNING:  Careless use of this command can corrupt a Fossil repository
         1190  +** in ways that are unrecoverable.  Be sure you know what you are doing before
         1191  +** running any SQL commands that modifies the repository database.
         1192  +*/
         1193  +void sqlite3_cmd(void){
         1194  +  extern int sqlite3_shell(int, char**);
         1195  +  sqlite3_shell(g.argc-1, g.argv+1);
         1196  +}
         1197  +
         1198  +/*
         1199  +** This routine is called by the patched sqlite3 command-line shell in order
         1200  +** to load the name and database connection for the open Fossil database.
         1201  +*/
         1202  +void fossil_open(sqlite3 **pDb, const char **pzRepoName){
         1203  +  db_must_be_within_tree();
         1204  +  *pDb = 0;
         1205  +  *pzRepoName = g.zRepositoryName;
         1206  +}

Changes to src/main.mk.

    33     33     $(SRCDIR)/delta.c \
    34     34     $(SRCDIR)/deltacmd.c \
    35     35     $(SRCDIR)/descendants.c \
    36     36     $(SRCDIR)/diff.c \
    37     37     $(SRCDIR)/diffcmd.c \
    38     38     $(SRCDIR)/doc.c \
    39     39     $(SRCDIR)/encode.c \
           40  +  $(SRCDIR)/event.c \
    40     41     $(SRCDIR)/file.c \
    41     42     $(SRCDIR)/finfo.c \
    42     43     $(SRCDIR)/graph.c \
    43     44     $(SRCDIR)/http.c \
    44     45     $(SRCDIR)/http_socket.c \
    45     46     $(SRCDIR)/http_ssl.c \
    46     47     $(SRCDIR)/http_transport.c \
................................................................................
    49     50     $(SRCDIR)/main.c \
    50     51     $(SRCDIR)/manifest.c \
    51     52     $(SRCDIR)/md5.c \
    52     53     $(SRCDIR)/merge.c \
    53     54     $(SRCDIR)/merge3.c \
    54     55     $(SRCDIR)/name.c \
    55     56     $(SRCDIR)/pivot.c \
           57  +  $(SRCDIR)/popen.c \
    56     58     $(SRCDIR)/pqueue.c \
    57     59     $(SRCDIR)/printf.c \
    58     60     $(SRCDIR)/rebuild.c \
    59     61     $(SRCDIR)/report.c \
    60     62     $(SRCDIR)/rss.c \
    61     63     $(SRCDIR)/schema.c \
    62     64     $(SRCDIR)/search.c \
................................................................................
   105    107     delta_.c \
   106    108     deltacmd_.c \
   107    109     descendants_.c \
   108    110     diff_.c \
   109    111     diffcmd_.c \
   110    112     doc_.c \
   111    113     encode_.c \
          114  +  event_.c \
   112    115     file_.c \
   113    116     finfo_.c \
   114    117     graph_.c \
   115    118     http_.c \
   116    119     http_socket_.c \
   117    120     http_ssl_.c \
   118    121     http_transport_.c \
................................................................................
   121    124     main_.c \
   122    125     manifest_.c \
   123    126     md5_.c \
   124    127     merge_.c \
   125    128     merge3_.c \
   126    129     name_.c \
   127    130     pivot_.c \
          131  +  popen_.c \
   128    132     pqueue_.c \
   129    133     printf_.c \
   130    134     rebuild_.c \
   131    135     report_.c \
   132    136     rss_.c \
   133    137     schema_.c \
   134    138     search_.c \
................................................................................
   177    181    $(OBJDIR)/delta.o \
   178    182    $(OBJDIR)/deltacmd.o \
   179    183    $(OBJDIR)/descendants.o \
   180    184    $(OBJDIR)/diff.o \
   181    185    $(OBJDIR)/diffcmd.o \
   182    186    $(OBJDIR)/doc.o \
   183    187    $(OBJDIR)/encode.o \
          188  + $(OBJDIR)/event.o \
   184    189    $(OBJDIR)/file.o \
   185    190    $(OBJDIR)/finfo.o \
   186    191    $(OBJDIR)/graph.o \
   187    192    $(OBJDIR)/http.o \
   188    193    $(OBJDIR)/http_socket.o \
   189    194    $(OBJDIR)/http_ssl.o \
   190    195    $(OBJDIR)/http_transport.o \
................................................................................
   193    198    $(OBJDIR)/main.o \
   194    199    $(OBJDIR)/manifest.o \
   195    200    $(OBJDIR)/md5.o \
   196    201    $(OBJDIR)/merge.o \
   197    202    $(OBJDIR)/merge3.o \
   198    203    $(OBJDIR)/name.o \
   199    204    $(OBJDIR)/pivot.o \
          205  + $(OBJDIR)/popen.o \
   200    206    $(OBJDIR)/pqueue.o \
   201    207    $(OBJDIR)/printf.o \
   202    208    $(OBJDIR)/rebuild.o \
   203    209    $(OBJDIR)/report.o \
   204    210    $(OBJDIR)/rss.o \
   205    211    $(OBJDIR)/schema.o \
   206    212    $(OBJDIR)/search.o \
................................................................................
   256    262   	$(TCLSH) test/tester.tcl $(APPNAME)
   257    263   
   258    264   VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest
   259    265   	awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >VERSION.h
   260    266   	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >>VERSION.h
   261    267   	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n", substr($$2,1,10),substr($$2,12)}'  $(SRCDIR)/../manifest >>VERSION.h
   262    268   
   263         -$(APPNAME):	headers $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o
   264         -	$(TCC) -o $(APPNAME) $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(LIB)
          269  +EXTRAOBJ =  $(OBJDIR)/sqlite3.o  $(OBJDIR)/shell.o  $(OBJDIR)/th.o  $(OBJDIR)/th_lang.o
          270  +
          271  +$(APPNAME):	headers $(OBJ) $(EXTRAOBJ)
          272  +	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
   265    273   
   266    274   # This rule prevents make from using its default rules to try build
   267    275   # an executable named "manifest" out of the file named "manifest.c"
   268    276   #
   269    277   $(SRCDIR)/../manifest:	
   270    278   	# noop
   271    279   
   272    280   clean:	
   273    281   	rm -f $(OBJDIR)/*.o *_.c $(APPNAME) VERSION.h
   274    282   	rm -f translate makeheaders mkindex page_index.h headers
   275         -	rm -f add.h allrepo.h attach.h bag.h blob.h branch.h browse.h captcha.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h finfo.h graph.h http.h http_socket.h http_ssl.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h schema.h search.h setup.h sha1.h shun.h skins.h stat.h style.h sync.h tag.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h
          283  +	rm -f add.h allrepo.h attach.h bag.h blob.h branch.h browse.h captcha.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h event.h file.h finfo.h graph.h http.h http_socket.h http_ssl.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h popen.h pqueue.h printf.h rebuild.h report.h rss.h schema.h search.h setup.h sha1.h shun.h skins.h stat.h style.h sync.h tag.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h
   276    284   
   277    285   page_index.h: $(TRANS_SRC) mkindex
   278    286   	./mkindex $(TRANS_SRC) >$@
   279    287   headers:	page_index.h makeheaders VERSION.h
   280         -	./makeheaders  add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h
          288  +	./makeheaders  add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h
   281    289   	touch headers
   282    290   headers: Makefile
   283    291   Makefile:
   284    292   add_.c:	$(SRCDIR)/add.c translate
   285    293   	./translate $(SRCDIR)/add.c >add_.c
   286    294   
   287    295   $(OBJDIR)/add.o:	add_.c add.h  $(SRCDIR)/config.h
................................................................................
   445    453   encode_.c:	$(SRCDIR)/encode.c translate
   446    454   	./translate $(SRCDIR)/encode.c >encode_.c
   447    455   
   448    456   $(OBJDIR)/encode.o:	encode_.c encode.h  $(SRCDIR)/config.h
   449    457   	$(XTCC) -o $(OBJDIR)/encode.o -c encode_.c
   450    458   
   451    459   encode.h:	headers
          460  +event_.c:	$(SRCDIR)/event.c translate
          461  +	./translate $(SRCDIR)/event.c >event_.c
          462  +
          463  +$(OBJDIR)/event.o:	event_.c event.h  $(SRCDIR)/config.h
          464  +	$(XTCC) -o $(OBJDIR)/event.o -c event_.c
          465  +
          466  +event.h:	headers
   452    467   file_.c:	$(SRCDIR)/file.c translate
   453    468   	./translate $(SRCDIR)/file.c >file_.c
   454    469   
   455    470   $(OBJDIR)/file.o:	file_.c file.h  $(SRCDIR)/config.h
   456    471   	$(XTCC) -o $(OBJDIR)/file.o -c file_.c
   457    472   
   458    473   file.h:	headers
................................................................................
   557    572   pivot_.c:	$(SRCDIR)/pivot.c translate
   558    573   	./translate $(SRCDIR)/pivot.c >pivot_.c
   559    574   
   560    575   $(OBJDIR)/pivot.o:	pivot_.c pivot.h  $(SRCDIR)/config.h
   561    576   	$(XTCC) -o $(OBJDIR)/pivot.o -c pivot_.c
   562    577   
   563    578   pivot.h:	headers
          579  +popen_.c:	$(SRCDIR)/popen.c translate
          580  +	./translate $(SRCDIR)/popen.c >popen_.c
          581  +
          582  +$(OBJDIR)/popen.o:	popen_.c popen.h  $(SRCDIR)/config.h
          583  +	$(XTCC) -o $(OBJDIR)/popen.o -c popen_.c
          584  +
          585  +popen.h:	headers
   564    586   pqueue_.c:	$(SRCDIR)/pqueue.c translate
   565    587   	./translate $(SRCDIR)/pqueue.c >pqueue_.c
   566    588   
   567    589   $(OBJDIR)/pqueue.o:	pqueue_.c pqueue.h  $(SRCDIR)/config.h
   568    590   	$(XTCC) -o $(OBJDIR)/pqueue.o -c pqueue_.c
   569    591   
   570    592   pqueue.h:	headers
................................................................................
   770    792   $(OBJDIR)/zip.o:	zip_.c zip.h  $(SRCDIR)/config.h
   771    793   	$(XTCC) -o $(OBJDIR)/zip.o -c zip_.c
   772    794   
   773    795   zip.h:	headers
   774    796   $(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
   775    797   	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
   776    798   
          799  +$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c
          800  +	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
          801  +
   777    802   $(OBJDIR)/th.o:	$(SRCDIR)/th.c
   778    803   	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
   779    804   
   780    805   $(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
   781    806   	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
   782    807   

Changes to src/makeheaders.c.

    11     11   */
    12     12   #include <stdio.h>
    13     13   #include <stdlib.h>
    14     14   #include <ctype.h>
    15     15   #include <memory.h>
    16     16   #include <sys/stat.h>
    17     17   #include <assert.h>
    18         -#ifndef WIN32
    19         -# include <unistd.h>
    20         -#else
           18  +#if defined( __MINGW32__) ||  defined(__DMC__) || defined(_MSC_VER) || defined(__POCC__)
           19  +#  ifndef WIN32
           20  +#    define WIN32
           21  +#  endif
    21     22   # include <string.h>
           23  +#else
           24  +# include <unistd.h>
    22     25   #endif
    23     26   
    24     27   /*
    25     28   ** Macros for debugging.
    26     29   */
    27     30   #ifdef DEBUG
    28     31   static int debugMask = 0;
................................................................................
  2139   2142       ** and EXPORT_INTERFACE and LOCAL_INTERFACE
  2140   2143       */
  2141   2144       zArg = &zCmd[2];
  2142   2145       while( *zArg && isspace(*zArg) && *zArg!='\n' ){
  2143   2146         zArg++;
  2144   2147       }
  2145   2148       if( *zArg==0 || *zArg=='\n' ){ return 0; }
  2146         -    nArg = pToken->nText + (int)pToken->zText - (int)zArg;
         2149  +    nArg = pToken->nText + (int)(pToken->zText - zArg);
  2147   2150       if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
  2148   2151         PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
  2149   2152       }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
  2150   2153         PushIfMacro(0,0,0,pToken->nLine,PS_Export);
  2151   2154       }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
  2152   2155         PushIfMacro(0,0,0,pToken->nLine,PS_Local);
  2153   2156       }else{
................................................................................
  2158   2161       ** Push an #ifdef.
  2159   2162       */
  2160   2163       zArg = &zCmd[5];
  2161   2164       while( *zArg && isspace(*zArg) && *zArg!='\n' ){
  2162   2165         zArg++;
  2163   2166       }
  2164   2167       if( *zArg==0 || *zArg=='\n' ){ return 0; }
  2165         -    nArg = pToken->nText + (int)pToken->zText - (int)zArg;
         2168  +    nArg = pToken->nText + (int)(pToken->zText - zArg);
  2166   2169       PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
  2167   2170     }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
  2168   2171       /*
  2169   2172       ** Push an #ifndef.
  2170   2173       */
  2171   2174       zArg = &zCmd[6];
  2172   2175       while( *zArg && isspace(*zArg) && *zArg!='\n' ){
  2173   2176         zArg++;
  2174   2177       }
  2175   2178       if( *zArg==0 || *zArg=='\n' ){ return 0; }
  2176         -    nArg = pToken->nText + (int)pToken->zText - (int)zArg;
         2179  +    nArg = pToken->nText + (int)(pToken->zText - zArg);
  2177   2180       PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
  2178   2181     }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
  2179   2182       /*
  2180   2183       ** Invert the #if on the top of the stack 
  2181   2184       */
  2182   2185       if( ifStack==0 ){
  2183   2186         fprintf(stderr,"%s:%d: '#else' without an '#if'\n",zFilename,
................................................................................
  2795   2798         nErr++;
  2796   2799       }
  2797   2800     }else if( strncmp(zOldVersion,zTopLine,nTopLine)!=0 ){
  2798   2801       if( report ) fprintf(report,"error!\n");
  2799   2802       fprintf(stderr,
  2800   2803          "%s: Can't overwrite this file because it wasn't previously\n"
  2801   2804          "%*s  generated by 'makeheaders'.\n",
  2802         -       pFile->zHdr, strlen(pFile->zHdr), "");
         2805  +       pFile->zHdr, (int)strlen(pFile->zHdr), "");
  2803   2806       nErr++;
  2804   2807     }else if( strcmp(zOldVersion,zNewVersion)!=0 ){
  2805   2808       if( report ) fprintf(report,"updated\n");
  2806   2809       if( WriteFile(pFile->zHdr,zNewVersion) ){
  2807   2810         fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr);
  2808   2811         nErr++;
  2809   2812       }
................................................................................
  2950   2953         }
  2951   2954       }
  2952   2955       if( nLabel==0 ) continue;
  2953   2956       zLabel[nLabel] = 0;
  2954   2957       InsertExtraDecl(pDecl);
  2955   2958       zDecl = pDecl->zDecl;
  2956   2959       if( zDecl==0 ) zDecl = pDecl->zFwd;
  2957         -    printf("%s %s %s %d %d %d %d %d %d\n",
         2960  +    printf("%s %s %s %p %d %d %d %d %d\n",
  2958   2961          pDecl->zName,
  2959   2962          zLabel,
  2960   2963          pDecl->zFile,
  2961         -       pDecl->pComment ? (int)pDecl->pComment/sizeof(Token) : 0,
         2964  +       pDecl->pComment,
  2962   2965          pDecl->pComment ? pDecl->pComment->nText+1 : 0,
  2963         -       pDecl->zIf ? strlen(pDecl->zIf)+1 : 0,
  2964         -       zDecl ? strlen(zDecl) : 0,
         2966  +       pDecl->zIf ? (int)strlen(pDecl->zIf)+1 : 0,
         2967  +       zDecl ? (int)strlen(zDecl) : 0,
  2965   2968          pDecl->pComment ? pDecl->pComment->nLine : 0,
  2966   2969          pDecl->tokenCode.nText ? pDecl->tokenCode.nText+1 : 0
  2967   2970       );
  2968   2971       if( pDecl->pComment ){
  2969   2972         printf("%.*s\n",pDecl->pComment->nText, pDecl->pComment->zText);
  2970   2973       }
  2971   2974       if( pDecl->zIf ){

Changes to src/makemake.tcl.

    27     27     delta
    28     28     deltacmd
    29     29     descendants
    30     30     diff
    31     31     diffcmd
    32     32     doc
    33     33     encode
           34  +  event
    34     35     file
    35     36     finfo
    36     37     graph
    37     38     http
    38     39     http_socket
    39     40     http_transport
    40     41     info
................................................................................
    42     43     main
    43     44     manifest
    44     45     md5
    45     46     merge
    46     47     merge3
    47     48     name
    48     49     pivot
           50  +  popen
    49     51     pqueue
    50     52     printf
    51     53     rebuild
    52     54     report
    53     55     rss
    54     56     schema
    55     57     search
................................................................................
    78     80     zip
    79     81     http_ssl
    80     82   }
    81     83   
    82     84   # Name of the final application
    83     85   #
    84     86   set name fossil
    85         -
           87  +if { 0 == $argc } {
    86     88   puts {# DO NOT EDIT
    87     89   #
    88     90   # This file is automatically generated.  Instead of editing this
    89     91   # file, edit "makemake.tcl" then run "tclsh makemake.tcl >main.mk"
    90     92   # to regenerate this file.
    91     93   #
    92     94   # This file is included by linux-gcc.mk or linux-mingw.mk or possible
................................................................................
   144    146   		$(SRCDIR)/../manifest.uuid >VERSION.h
   145    147   	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}' \
   146    148   		$(SRCDIR)/../manifest.uuid >>VERSION.h
   147    149   	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n",\
   148    150   		substr($$2,1,10),substr($$2,12)}' \
   149    151   		$(SRCDIR)/../manifest >>VERSION.h
   150    152   
   151         -$(APPNAME):	headers $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o
   152         -	$(TCC) -o $(APPNAME) $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(LIB)
          153  +EXTRAOBJ = \
          154  +  $(OBJDIR)/sqlite3.o \
          155  +  $(OBJDIR)/shell.o \
          156  +  $(OBJDIR)/th.o \
          157  +  $(OBJDIR)/th_lang.o
          158  +
          159  +$(APPNAME):	headers $(OBJ) $(EXTRAOBJ)
          160  +	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
   153    161   
   154    162   # This rule prevents make from using its default rules to try build
   155    163   # an executable named "manifest" out of the file named "manifest.c"
   156    164   #
   157    165   $(SRCDIR)/../manifest:	
   158    166   	# noop
   159    167   
................................................................................
   197    205   set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1}
   198    206   append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4"
   199    207   #append opt " -DSQLITE_ENABLE_FTS3=1"
   200    208   append opt " -Dlocaltime=fossil_localtime"
   201    209   append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0"
   202    210   puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
   203    211   
          212  +puts "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c"
          213  +set opt {-Dmain=sqlite3_shell}
          214  +append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
          215  +puts "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
          216  +
   204    217   puts "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
   205    218   puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
   206    219   
   207    220   puts "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
   208    221   puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
          222  +exit
          223  +}
          224  +if { "dmc" == [lindex $argv 0] } {
          225  +
          226  +puts {# DO NOT EDIT
          227  +#
          228  +# This file is automatically generated.  Instead of editing this
          229  +# file, edit "makemake.tcl" then run
          230  +# "tclsh src/makemake.tcl dmc > win/Makefile.dmc"
          231  +# to regenerate this file.
          232  +B      = ..
          233  +SRCDIR = $B\src
          234  +OBJDIR = .
          235  +O      = .obj
          236  +E      = .exe
          237  +
          238  +
          239  +# Maybe DMDIR, SSL or INCL needs adjustment
          240  +DMDIR  = c:\DM
          241  +INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(DMDIR)\extra\include
          242  +
          243  +#SSL   =  -DFOSSIL_ENABLE_SSL=1
          244  +SSL    =
          245  +
          246  +DMCDEF =  -Dstrncasecmp=memicmp -Dstrcasecmp=stricmp
          247  +I18N   =  -DFOSSIL_I18N=0
          248  +
          249  +CFLAGS = -o 
          250  +BCC    = $(DMDIR)\bin\dmc $(CFLAGS)
          251  +TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(I18N) $(SSL) $(INCL)
          252  +LIBS   = $(DMDIR)\extra\lib\ zlib wsock32
          253  +}
          254  +puts -nonewline "SRC   = "
          255  +foreach s [lsort $src] {
          256  +  puts -nonewline "${s}_.c "
          257  +}
          258  +puts "\n"
          259  +puts -nonewline "OBJ   = "
          260  +foreach s [lsort $src] {
          261  +  puts -nonewline "\$(OBJDIR)\\$s\$O "
          262  +}
          263  +puts "\$(OBJDIR)\\sqlite3\$O \$(OBJDIR)\\th\$O \$(OBJDIR)\\th_lang\$O "
          264  +puts {
          265  +
          266  +APPNAME = $(OBJDIR)\fossil$(E)
          267  +
          268  +all: $(APPNAME)
          269  +
          270  +$(APPNAME) : translate$E mkindex$E headers  $(OBJ) $(OBJDIR)\link
          271  +	cd $(OBJDIR) 
          272  +	$(DMDIR)\bin\link @link
          273  +
          274  +$(OBJDIR)\link: $B\win\Makefile.dmc}
          275  +puts -nonewline "\t+echo "
          276  +foreach s [lsort $src] {
          277  +  puts -nonewline "$s "
          278  +}
          279  +puts "sqlite3 th th_lang > \$@"
          280  +puts "\t+echo fossil >> \$@"
          281  +puts "\t+echo fossil >> \$@"
          282  +puts "\t+echo \$(LIBS) >> \$@\n\n"
          283  +
          284  +puts {
          285  +translate$E: $(SRCDIR)\translate.c
          286  +	$(BCC) -o$@ $**
          287  +
          288  +makeheaders$E: $(SRCDIR)\makeheaders.c
          289  +	$(BCC) -o$@ $**
          290  +
          291  +mkindex$E: $(SRCDIR)\mkindex.c
          292  +	$(BCC) -o$@ $**
          293  +
          294  +version$E: $B\win\version.c
          295  +	$(BCC) -o$@ $**
          296  +
          297  +$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
          298  +	$(TCC) -o$@ -c -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 $**
          299  +
          300  +$(OBJDIR)\th$O : $(SRCDIR)\th.c
          301  +	$(TCC) -o$@ -c $**
          302  +
          303  +$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
          304  +	$(TCC) -o$@ -c $**
          305  +
          306  +VERSION.h : version$E $B\manifest.uuid $B\manifest
          307  +	+$** > $@
          308  +
          309  +page_index.h: mkindex$E $(SRC) 
          310  +	+$** > $@
          311  +
          312  +clean:
          313  +	-del $(OBJDIR)\*.obj
          314  +	-del *.obj *_.c *.h *.map
          315  +
          316  +realclean:
          317  +	-del $(APPNAME) translate$E mkindex$E makeheaders$E version$E
          318  +
          319  +}
          320  +foreach s [lsort $src] {
          321  +  puts "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
          322  +  puts "\t\$(TCC) -o\$@ -c ${s}_.c\n"
          323  +  puts "${s}_.c : \$(SRCDIR)\\$s.c"
          324  +  puts "\t+translate\$E \$** > \$@\n"
          325  +}
          326  +
          327  +puts -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
          328  +foreach s [lsort $src] {
          329  +  puts -nonewline "${s}_.c:$s.h "
          330  +}
          331  +puts "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
          332  +puts "\t@copy /Y nul: headers"
          333  +exit
          334  +}
          335  +
          336  +if { "msc" == [lindex $argv 0] } {
          337  +
          338  +puts {# DO NOT EDIT
          339  +#
          340  +# This file is automatically generated.  Instead of editing this
          341  +# file, edit "makemake.tcl" then run
          342  +# "tclsh src/makemake.tcl msc > win/Makefile.msc"
          343  +# to regenerate this file.
          344  +B      = ..
          345  +SRCDIR = $B\src
          346  +OBJDIR = .
          347  +O      = .obj
          348  +E      = .exe
          349  +
          350  +# Maybe MSCDIR, SSL, ZLIB, or INCL needs adjustment
          351  +MSCDIR = c:\msc
          352  +
          353  +# Uncomment below for SSL support
          354  +SSL =
          355  +SSLLIB =
          356  +#SSL = -DFOSSIL_ENABLE_SSL=1
          357  +#SSLLIB  = ssleay32.lib libeay32.lib user32.lib gdi32.lib advapi32.lib
          358  +
          359  +# zlib options
          360  +# When using precompiled from http://zlib.net/zlib125-dll.zip
          361  +#ZINCDIR = C:\zlib125-dll\include
          362  +#ZLIBDIR = C:\zlib125-dll\lib
          363  +#ZLIB    = zdll.lib
          364  +ZINCDIR = $(MSCDIR)\extra\include
          365  +ZLIBDIR = $(MSCDIR)\extra\lib
          366  +ZLIB    = zlib.lib
          367  +
          368  +INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)
          369  +
          370  +MSCDEF =  -Dstrncasecmp=memicmp -Dstrcasecmp=stricmp
          371  +I18N   =  -DFOSSIL_I18N=0
          372  +
          373  +CFLAGS = -nologo -MT -O2
          374  +BCC    = $(CC) $(CFLAGS)
          375  +TCC    = $(CC) -c $(CFLAGS) $(MSCDEF) $(I18N) $(SSL) $(INCL)
          376  +LIBS   = $(ZLIB) ws2_32.lib $(SSLLIB)
          377  +LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
          378  +}
          379  +puts -nonewline "SRC   = "
          380  +foreach s [lsort $src] {
          381  +  puts -nonewline "${s}_.c "
          382  +}
          383  +puts "\n"
          384  +puts -nonewline "OBJ   = "
          385  +foreach s [lsort $src] {
          386  +  puts -nonewline "\$(OBJDIR)\\$s\$O "
          387  +}
          388  +puts "\$(OBJDIR)\\sqlite3\$O \$(OBJDIR)\\th\$O \$(OBJDIR)\\th_lang\$O "
          389  +puts {
          390  +
          391  +APPNAME = $(OBJDIR)\fossil$(E)
          392  +
          393  +all: $(OBJDIR) $(APPNAME)
          394  +
          395  +$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\linkopts
          396  +	cd $(OBJDIR) 
          397  +	link -LINK -OUT:$@ $(LIBDIR) @linkopts
          398  +
          399  +$(OBJDIR)\linkopts: $B\win\Makefile.msc}
          400  +puts -nonewline "\techo "
          401  +foreach s [lsort $src] {
          402  +  puts -nonewline "$s "
          403  +}
          404  +puts "sqlite3 th th_lang > \$@"
          405  +puts "\techo \$(LIBS) >> \$@\n\n"
          406  +
          407  +puts {
          408  +
          409  +$(OBJDIR):
          410  +	@-mkdir $@
          411  +
          412  +translate$E: $(SRCDIR)\translate.c
          413  +	$(BCC) $**
          414  +
          415  +makeheaders$E: $(SRCDIR)\makeheaders.c
          416  +	$(BCC) $**
          417  +
          418  +mkindex$E: $(SRCDIR)\mkindex.c
          419  +	$(BCC) $**
          420  +
          421  +version$E: $B\win\version.c
          422  +	$(BCC) $**
          423  +
          424  +$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
          425  +	$(TCC) /Fo$@ -c -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 $**
          426  +
          427  +$(OBJDIR)\th$O : $(SRCDIR)\th.c
          428  +	$(TCC) /Fo$@ -c $**
          429  +
          430  +$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
          431  +	$(TCC) /Fo$@ -c $**
          432  +
          433  +VERSION.h : version$E $B\manifest.uuid $B\manifest
          434  +	$** > $@
          435  +
          436  +page_index.h: mkindex$E $(SRC) 
          437  +	$** > $@
          438  +
          439  +clean:
          440  +	-del $(OBJDIR)\*.obj
          441  +	-del *.obj *_.c *.h *.map
          442  +	-del headers linkopts
          443  +
          444  +realclean:
          445  +	-del $(APPNAME) translate$E mkindex$E makeheaders$E version$E
          446  +
          447  +}
          448  +foreach s [lsort $src] {
          449  +  puts "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
          450  +  puts "\t\$(TCC) /Fo\$@ -c ${s}_.c\n"
          451  +  puts "${s}_.c : \$(SRCDIR)\\$s.c"
          452  +  puts "\ttranslate\$E \$** > \$@\n"
          453  +}
          454  +
          455  +puts -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E "
          456  +foreach s [lsort $src] {
          457  +  puts -nonewline "${s}_.c:$s.h "
          458  +}
          459  +puts "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
          460  +puts "\t@copy /Y nul: headers"
          461  +	
          462  +}

Added src/makeskins.c.

            1  +/*
            2  +** Copyright (c) 2010 Michael T. Richter, assigned to the Fossil SCM project.
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the Simplified BSD License (also
            6  +** known as the "2-Clause License" or "FreeBSD License".)
            7  +**
            8  +** This program is distributed in the hope that it will be useful,
            9  +** but without any warranty; without even the implied warranty of
           10  +** merchantability or fitness for a particular purpose.
           11  +**
           12  +** Author contact information:
           13  +**   ttmrichter@gmail.com
           14  +**
           15  +*******************************************************************************
           16  +**
           17  +** This utility is a preprocessor that takes raw CSS and HTML files, along with
           18  +** plain text descriptions, and generates the skins.c file that is used to embed
           19  +** the distributed default skins into Fossil.
           20  +**
           21  +** The intent of the utility is to make adding new skins to a Fossil build
           22  +** easier without involving error-prone C programming.
           23  +**
           24  +** This utility must be run BEFORE the translate program is executed on the C
           25  +** source files.  (This is in retrospect obvious since it generates one of the
           26  +** said C files.)
           27  +*/
           28  +#include <stdio.h>
           29  +#include <ctype.h>
           30  +#include <stdlib.h>
           31  +#include <string.h>
           32  +
           33  +int main(int argc, char **argv){
           34  +  if( argc==3 ){
           35  +    /*
           36  +    ** 1. Validate the arguments: <skins> and <src> directory.
           37  +    ** 2. Open the <src>/skins.c file.
           38  +    ** 3. Write the initial boilerplate.
           39  +    ** 4. Walk the directory structure of <skins>.
           40  +    ** 5. For each one:
           41  +    **    a) Store the title and author information. (info.txt)
           42  +    **    b) Write out the description as a comment. (info.txt)
           43  +    **    c) Write out the CSS information.          (style.css)
           44  +    **    d) Write out the header information.       (header.html)
           45  +    **    e) Write out the footer information.       (footer.html)
           46  +    ** 6. Write out the built-in skins table.
           47  +    ** 7. Write the trailing boilerplate.
           48  +    */
           49  +  }else{
           50  +    /* error -- need a pair of directories */
           51  +  }
           52  +  return 0;
           53  +}

Changes to src/manifest.c.

    24     24   #include "manifest.h"
    25     25   #include <assert.h>
    26     26   
    27     27   #if INTERFACE
    28     28   /*
    29     29   ** Types of control files
    30     30   */
           31  +#define CFTYPE_ANY        0
    31     32   #define CFTYPE_MANIFEST   1
    32     33   #define CFTYPE_CLUSTER    2
    33     34   #define CFTYPE_CONTROL    3
    34     35   #define CFTYPE_WIKI       4
    35     36   #define CFTYPE_TICKET     5
    36     37   #define CFTYPE_ATTACHMENT 6
           38  +#define CFTYPE_EVENT      7
           39  +
           40  +/*
           41  +** A single F-card within a manifest
           42  +*/
           43  +struct ManifestFile { 
           44  +  char *zName;           /* Name of a file */
           45  +  char *zUuid;           /* UUID of the file */
           46  +  char *zPerm;           /* File permissions */
           47  +  char *zPrior;          /* Prior name if the name was changed */
           48  +};
           49  +
    37     50   
    38     51   /*
    39     52   ** A parsed manifest or cluster.
    40     53   */
    41     54   struct Manifest {
    42     55     Blob content;         /* The original content blob */
    43     56     int type;             /* Type of artifact.  One of CFTYPE_xxxxx */
           57  +  int rid;              /* The blob-id for this manifest */
           58  +  char *zBaseline;      /* Baseline manifest.  The B card. */
           59  +  Manifest *pBaseline;  /* The actual baseline manifest */
    44     60     char *zComment;       /* Decoded comment.  The C card. */
    45     61     double rDate;         /* Date and time from D card.  0.0 if no D card. */
    46     62     char *zUser;          /* Name of the user from the U card. */
    47     63     char *zRepoCksum;     /* MD5 checksum of the baseline content.  R card. */
    48     64     char *zWiki;          /* Text of the wiki page.  W card. */
    49     65     char *zWikiTitle;     /* Name of the wiki page. L card. */
           66  +  double rEventDate;    /* Date of an event.  E card. */
           67  +  char *zEventId;       /* UUID for an event.  E card. */
    50     68     char *zTicketUuid;    /* UUID for a ticket. K card. */
    51     69     char *zAttachName;    /* Filename of an attachment. A card. */
    52     70     char *zAttachSrc;     /* UUID of document being attached. A card. */
    53     71     char *zAttachTarget;  /* Ticket or wiki that attachment applies to.  A card */
    54     72     int nFile;            /* Number of F cards */
    55     73     int nFileAlloc;       /* Slots allocated in aFile[] */
    56         -  struct { 
    57         -    char *zName;           /* Name of a file */
    58         -    char *zUuid;           /* UUID of the file */
    59         -    char *zPerm;           /* File permissions */
    60         -    char *zPrior;          /* Prior name if the name was changed */
    61         -    int iRename;           /* index of renamed name in prior/next manifest */
    62         -  } *aFile;             /* One entry for each F card */
           74  +  int iFile;            /* Index of current file in iterator */
           75  +  ManifestFile *aFile;  /* One entry for each F-card */
    63     76     int nParent;          /* Number of parents. */
    64     77     int nParentAlloc;     /* Slots allocated in azParent[] */
    65     78     char **azParent;      /* UUIDs of parents.  One for each P card argument */
    66     79     int nCChild;          /* Number of cluster children */
    67     80     int nCChildAlloc;     /* Number of closts allocated in azCChild[] */
    68     81     char **azCChild;      /* UUIDs of referenced objects in a cluster. M cards */
    69     82     int nTag;             /* Number of T Cards */
................................................................................
    78     91     struct { 
    79     92       char *zName;           /* Key or field name */
    80     93       char *zValue;          /* Value of the field */
    81     94     } *aField;            /* One for each J card */
    82     95   };
    83     96   #endif
    84     97   
           98  +/*
           99  +** A cache of parsed manifests.  This reduces the number of
          100  +** calls to manifest_parse() when doing a rebuild.
          101  +*/
          102  +#define MX_MANIFEST_CACHE 6
          103  +static struct {
          104  +  int nxAge;
          105  +  int aAge[MX_MANIFEST_CACHE];
          106  +  Manifest *apManifest[MX_MANIFEST_CACHE];
          107  +} manifestCache;
          108  +
    85    109   
    86    110   /*
    87    111   ** Clear the memory allocated in a manifest object
    88    112   */
    89         -void manifest_clear(Manifest *p){
    90         -  blob_reset(&p->content);
    91         -  free(p->aFile);
    92         -  free(p->azParent);
    93         -  free(p->azCChild);
    94         -  free(p->aTag);
    95         -  free(p->aField);
    96         -  memset(p, 0, sizeof(*p));
          113  +void manifest_destroy(Manifest *p){
          114  +  if( p ){
          115  +    blob_reset(&p->content);
          116  +    free(p->aFile);
          117  +    free(p->azParent);
          118  +    free(p->azCChild);
          119  +    free(p->aTag);
          120  +    free(p->aField);
          121  +    if( p->pBaseline ) manifest_destroy(p->pBaseline);
          122  +    fossil_free(p);
          123  +  }
          124  +}
          125  +
          126  +/*
          127  +** Add an element to the manifest cache using LRU replacement.
          128  +*/
          129  +void manifest_cache_insert(Manifest *p){
          130  +  while( p ){
          131  +    int i;
          132  +    Manifest *pBaseline = p->pBaseline;
          133  +    p->pBaseline = 0;
          134  +    for(i=0; i<MX_MANIFEST_CACHE; i++){
          135  +      if( manifestCache.apManifest[i]==0 ) break;
          136  +    }
          137  +    if( i>=MX_MANIFEST_CACHE ){
          138  +      int oldest = 0;
          139  +      int oldestAge = manifestCache.aAge[0];
          140  +      for(i=1; i<MX_MANIFEST_CACHE; i++){
          141  +        if( manifestCache.aAge[i]<oldestAge ){
          142  +          oldest = i;
          143  +          oldestAge = manifestCache.aAge[i];
          144  +        }
          145  +      }
          146  +      manifest_destroy(manifestCache.apManifest[oldest]);
          147  +      i = oldest;
          148  +    }
          149  +    manifestCache.aAge[i] = ++manifestCache.nxAge;
          150  +    manifestCache.apManifest[i] = p;
          151  +    p = pBaseline;
          152  +  }
          153  +}
          154  +
          155  +/*
          156  +** Try to extract a line from the manifest cache. Return 1 if found.
          157  +** Return 0 if not found.
          158  +*/
          159  +static Manifest *manifest_cache_find(int rid){
          160  +  int i;
          161  +  Manifest *p;
          162  +  for(i=0; i<MX_MANIFEST_CACHE; i++){
          163  +    if( manifestCache.apManifest[i] && manifestCache.apManifest[i]->rid==rid ){
          164  +      p = manifestCache.apManifest[i];
          165  +      manifestCache.apManifest[i] = 0;
          166  +      return p;
          167  +    }
          168  +  }
          169  +  return 0;
          170  +}
          171  +
          172  +/*
          173  +** Clear the manifest cache.
          174  +*/
          175  +void manifest_cache_clear(void){
          176  +  int i;
          177  +  for(i=0; i<MX_MANIFEST_CACHE; i++){
          178  +    if( manifestCache.apManifest[i] ){
          179  +      manifest_destroy(manifestCache.apManifest[i]);
          180  +    }
          181  +  }
          182  +  memset(&manifestCache, 0, sizeof(manifestCache));
          183  +}
          184  +
          185  +#ifdef FOSSIL_DONT_VERIFY_MANIFEST_MD5SUM
          186  +# define md5sum_init(X)
          187  +# define md5sum_step_text(X,Y)
          188  +#endif
          189  +
          190  +/*
          191  +** Remove the PGP signature from the artifact, if there is one.
          192  +*/
          193  +static void remove_pgp_signature(char **pz, int *pn){
          194  +  char *z = *pz;
          195  +  int n = *pn;
          196  +  int i;
          197  +  if( memcmp(z, "-----BEGIN PGP SIGNED MESSAGE-----", 34)!=0 ) return;
          198  +  for(i=34; i<n && (z[i-1]!='\n' || z[i-2]!='\n'); i++){}
          199  +  if( i>=n ) return;
          200  +  z += i;
          201  +  n -= i;
          202  +  *pz = z;
          203  +  for(i=n-1; i>=0; i--){
          204  +    if( z[i]=='\n' && memcmp(&z[i],"\n-----BEGIN PGP SIGNATURE-", 25)==0 ){
          205  +      n = i+1;
          206  +      break;
          207  +    }
          208  +  }
          209  +  *pn = n;
          210  +  return;
          211  +}
          212  +
          213  +/*
          214  +** Verify the Z-card checksum on the artifact, if there is such a
          215  +** checksum.  Return 0 if there is no Z-card.  Return 1 if the Z-card
          216  +** exists and is correct.  Return 2 if the Z-card exists and has the wrong
          217  +** value.
          218  +**
          219  +**   0123456789 123456789 123456789 123456789 
          220  +**   Z aea84f4f863865a8d59d0384e4d2a41c
          221  +*/
          222  +static int verify_z_card(const char *z, int n){
          223  +  if( n<35 ) return 0;
          224  +  if( z[n-35]!='Z' || z[n-34]!=' ' ) return 0;
          225  +  md5sum_init();
          226  +  md5sum_step_text(z, n-35);
          227  +  if( memcmp(&z[n-33], md5sum_finish(0), 32)==0 ){
          228  +    return 1;
          229  +  }else{
          230  +    return 2;
          231  +  }
          232  +}
          233  +
          234  +/*
          235  +** A structure used for rapid parsing of the Manifest file
          236  +*/
          237  +typedef struct ManifestText ManifestText;
          238  +struct ManifestText {
          239  +  char *z;           /* The first character of the next token */
          240  +  char *zEnd;        /* One character beyond the end of the manifest */
          241  +  int atEol;         /* True if z points to the start of a new line */
          242  +};
          243  +
          244  +/*
          245  +** Return a pointer to the next token.  The token is zero-terminated.
          246  +** Return NULL if there are no more tokens on the current line.
          247  +*/
          248  +static char *next_token(ManifestText *p, int *pLen){
          249  +  char *z;
          250  +  char *zStart;
          251  +  int c;
          252  +  if( p->atEol ) return 0;
          253  +  zStart = z = p->z;
          254  +  while( (c=(*z))!=' ' && c!='\n' ){ z++; }
          255  +  *z = 0;
          256  +  p->z = &z[1];
          257  +  p->atEol = c=='\n';
          258  +  if( pLen ) *pLen = z - zStart;
          259  +  return zStart;
          260  +}
          261  +
          262  +/*
          263  +** Return the card-type for the next card.  Or, return 0 if there are no
          264  +** more cards or if we are not at the end of the current card.
          265  +*/
          266  +static char next_card(ManifestText *p){
          267  +  char c;
          268  +  if( !p->atEol || p->z>=p->zEnd ) return 0;
          269  +  c = p->z[0];
          270  +  if( p->z[1]==' ' ){
          271  +    p->z += 2;
          272  +    p->atEol = 0;
          273  +  }else if( p->z[1]=='\n' ){
          274  +    p->z += 2;
          275  +    p->atEol = 1;
          276  +  }else{
          277  +    c = 0;
          278  +  }
          279  +  return c;
    97    280   }
    98    281   
    99    282   /*
   100    283   ** Parse a blob into a Manifest object.  The Manifest object
   101    284   ** takes over the input blob and will free it when the
   102    285   ** Manifest object is freed.  Zeros are inserted into the blob
   103    286   ** as string terminators so that blob should not be used again.
................................................................................
   119    302   ** The file consists of zero or more cards, one card per line.
   120    303   ** (Except: the content of the W card can extend of multiple lines.)
   121    304   ** Each card is divided into tokens by a single space character.
   122    305   ** The first token is a single upper-case letter which is the card type.
   123    306   ** The card type determines the other parameters to the card.
   124    307   ** Cards must occur in lexicographical order.
   125    308   */
   126         -int manifest_parse(Manifest *p, Blob *pContent){
   127         -  int seenHeader = 0;
          309  +static Manifest *manifest_parse(Blob *pContent, int rid){
          310  +  Manifest *p;
   128    311     int seenZ = 0;
   129    312     int i, lineNo=0;
   130         -  Blob line, token, a1, a2, a3, a4;
          313  +  ManifestText x;
   131    314     char cPrevType = 0;
          315  +  char cType;
          316  +  char *z;
          317  +  int n;
          318  +  char *zUuid;
          319  +  int sz = 0;
   132    320   
          321  +  /* Every control artifact ends with a '\n' character.  Exit early
          322  +  ** if that is not the case for this artifact.
          323  +  */
          324  +  z = blob_buffer(pContent);
          325  +  n = blob_size(pContent);
          326  +  if( n<=0 || z[n-1]!='\n' ){
          327  +    blob_reset(pContent);
          328  +    return 0;
          329  +  }
          330  +
          331  +  /* Strip off the PGP signature if there is one.  Then verify the
          332  +  ** Z-card.
          333  +  */
          334  +  remove_pgp_signature(&z, &n);
          335  +  if( verify_z_card(z, n)==0 ){
          336  +    blob_reset(pContent);
          337  +    return 0;
          338  +  }
          339  +
          340  +  /* Verify that the first few characters of the artifact look like
          341  +  ** a control artifact.
          342  +  */
          343  +  if( n<10 || z[0]<'A' || z[0]>'Z' || z[1]!=' ' ){
          344  +    blob_reset(pContent);
          345  +    return 0;
          346  +  }
          347  +
          348  +  /* Allocate a Manifest object to hold the parsed control artifact.
          349  +  */
          350  +  p = fossil_malloc( sizeof(*p) );
   133    351     memset(p, 0, sizeof(*p));
   134    352     memcpy(&p->content, pContent, sizeof(p->content));
          353  +  p->rid = rid;
   135    354     blob_zero(pContent);
   136    355     pContent = &p->content;
   137    356   
   138         -  blob_zero(&a1);
   139         -  blob_zero(&a2);
   140         -  blob_zero(&a3);
   141         -  md5sum_init();
   142         -  while( blob_line(pContent, &line) ){
   143         -    char *z = blob_buffer(&line);
          357  +  /* Begin parsing, card by card.
          358  +  */
          359  +  x.z = z;
          360  +  x.zEnd = &z[n];
          361  +  x.atEol = 1;
          362  +  while( (cType = next_card(&x))!=0 && cType>=cPrevType ){
   144    363       lineNo++;
   145         -    if( z[0]=='-' ){
   146         -      if( strncmp(z, "-----BEGIN PGP ", 15)!=0 ){
   147         -        goto manifest_syntax_error;
   148         -      }
   149         -      if( seenHeader ){
   150         -        break;
   151         -      }
   152         -      while( blob_line(pContent, &line)>2 ){}
   153         -      if( blob_line(pContent, &line)==0 ) break;
   154         -      z = blob_buffer(&line);
   155         -    }
   156         -    if( z[0]<cPrevType ){
   157         -      /* Lines of a manifest must occur in lexicographical order */
   158         -      goto manifest_syntax_error;
   159         -    }
   160         -    cPrevType = z[0];
   161         -    seenHeader = 1;
   162         -    if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
   163         -    switch( z[0] ){
          364  +    switch( cType ){
   164    365         /*
   165    366         **     A <filename> <target> ?<source>?
   166    367         **
   167    368         ** Identifies an attachment to either a wiki page or a ticket.
   168    369         ** <source> is the artifact that is the attachment.  <source>
   169    370         ** is omitted to delete an attachment.  <target> is the name of
   170    371         ** a wiki page or ticket to which that attachment is connected.
   171    372         */
   172    373         case 'A': {
   173    374           char *zName, *zTarget, *zSrc;
   174         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   175         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   176         -        if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
          375  +        int nTarget = 0, nSrc = 0;
          376  +        zName = next_token(&x, 0);
          377  +        zTarget = next_token(&x, &nTarget);
          378  +        zSrc = next_token(&x, &nSrc);
          379  +        if( zName==0 || zTarget==0 ) goto manifest_syntax_error;      
   177    380           if( p->zAttachName!=0 ) goto manifest_syntax_error;
   178         -        zName = blob_terminate(&a1);
   179         -        zTarget = blob_terminate(&a2);
   180         -        blob_token(&line, &a3);
   181         -        zSrc = blob_terminate(&a3);
   182    381           defossilize(zName);
   183    382           if( !file_is_simple_pathname(zName) ){
   184    383             goto manifest_syntax_error;
   185    384           }
   186    385           defossilize(zTarget);
   187         -        if( (blob_size(&a2)!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
          386  +        if( (nTarget!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
   188    387              && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
   189    388             goto manifest_syntax_error;
   190    389           }
   191         -        if( blob_size(&a3)>0
   192         -         && (blob_size(&a3)!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){
          390  +        if( zSrc && (nSrc!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){
   193    391             goto manifest_syntax_error;
   194    392           }
   195    393           p->zAttachName = (char*)file_tail(zName);
   196    394           p->zAttachSrc = zSrc;
   197    395           p->zAttachTarget = zTarget;
   198    396           break;
   199    397         }
          398  +
          399  +      /*
          400  +      **    B <uuid>
          401  +      **
          402  +      ** A B-line gives the UUID for the baselinen of a delta-manifest.
          403  +      */
          404  +      case 'B': {
          405  +        if( p->zBaseline ) goto manifest_syntax_error;
          406  +        p->zBaseline = next_token(&x, &sz);
          407  +        if( p->zBaseline==0 ) goto manifest_syntax_error;
          408  +        if( sz!=UUID_SIZE ) goto manifest_syntax_error;
          409  +        if( !validate16(p->zBaseline, UUID_SIZE) ) goto manifest_syntax_error;
          410  +        break;
          411  +      }
          412  +
   200    413   
   201    414         /*
   202    415         **     C <comment>
   203    416         **
   204    417         ** Comment text is fossil-encoded.  There may be no more than
   205    418         ** one C line.  C lines are required for manifests and are
   206    419         ** disallowed on all other control files.
   207    420         */
   208    421         case 'C': {
   209         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   210    422           if( p->zComment!=0 ) goto manifest_syntax_error;
   211         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   212         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   213         -        p->zComment = blob_terminate(&a1);
          423  +        p->zComment = next_token(&x, 0);
          424  +        if( p->zComment==0 ) goto manifest_syntax_error;
   214    425           defossilize(p->zComment);
   215    426           break;
   216    427         }
   217    428   
   218    429         /*
   219    430         **     D <timestamp>
   220    431         **
   221    432         ** The timestamp should be ISO 8601.   YYYY-MM-DDtHH:MM:SS
   222    433         ** There can be no more than 1 D line.  D lines are required
   223    434         ** for all control files except for clusters.
   224    435         */
   225    436         case 'D': {
   226         -        char *zDate;
   227         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   228         -        if( p->rDate!=0.0 ) goto manifest_syntax_error;
   229         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   230         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   231         -        zDate = blob_terminate(&a1);
   232         -        p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate);
          437  +        if( p->rDate>0.0 ) goto manifest_syntax_error;
          438  +        p->rDate = db_double(0.0, "SELECT julianday(%Q)", next_token(&x,0));
          439  +        if( p->rDate<=0.0 ) goto manifest_syntax_error;
          440  +        break;
          441  +      }
          442  +
          443  +      /*
          444  +      **     E <timestamp> <uuid>
          445  +      **
          446  +      ** An "event" card that contains the timestamp of the event in the 
          447  +      ** format YYYY-MM-DDtHH:MM:SS and a unique identifier for the event.
          448  +      ** The event timestamp is distinct from the D timestamp.  The D
          449  +      ** timestamp is when the artifact was created whereas the E timestamp
          450  +      ** is when the specific event is said to occur.
          451  +      */
          452  +      case 'E': {
          453  +        if( p->rEventDate>0.0 ) goto manifest_syntax_error;
          454  +        p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
          455  +        if( p->rEventDate<=0.0 ) goto manifest_syntax_error;
          456  +        p->zEventId = next_token(&x, &sz);
          457  +        if( sz!=UUID_SIZE ) goto manifest_syntax_error;
          458  +        if( !validate16(p->zEventId, UUID_SIZE) ) goto manifest_syntax_error;
   233    459           break;
   234    460         }
   235    461   
   236    462         /*
   237         -      **     F <filename> <uuid> ?<permissions>? ?<old-name>?
          463  +      **     F <filename> ?<uuid>? ?<permissions>? ?<old-name>?
   238    464         **
   239    465         ** Identifies a file in a manifest.  Multiple F lines are
   240    466         ** allowed in a manifest.  F lines are not allowed in any
   241    467         ** other control file.  The filename and old-name are fossil-encoded.
   242    468         */
   243    469         case 'F': {
   244         -        char *zName, *zUuid, *zPerm, *zPriorName;
   245         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   246         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   247         -        if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
   248         -        zName = blob_terminate(&a1);
   249         -        zUuid = blob_terminate(&a2);
   250         -        blob_token(&line, &a3);
   251         -        zPerm = blob_terminate(&a3);
   252         -        if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error;
   253         -        if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
          470  +        char *zName, *zPerm, *zPriorName;
          471  +        zName = next_token(&x,0);
          472  +        if( zName==0 ) goto manifest_syntax_error;
   254    473           defossilize(zName);
   255    474           if( !file_is_simple_pathname(zName) ){
   256    475             goto manifest_syntax_error;
   257    476           }
   258         -        blob_token(&line, &a4);
   259         -        zPriorName = blob_terminate(&a4);
   260         -        if( zPriorName[0] ){
          477  +        zUuid = next_token(&x, &sz);
          478  +        if( p->zBaseline==0 || zUuid!=0 ){
          479  +          if( sz!=UUID_SIZE ) goto manifest_syntax_error;
          480  +          if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
          481  +        }
          482  +        zPerm = next_token(&x,0);
          483  +        zPriorName = next_token(&x,0);
          484  +        if( zPriorName ){
   261    485             defossilize(zPriorName);
   262    486             if( !file_is_simple_pathname(zPriorName) ){
   263    487               goto manifest_syntax_error;
   264    488             }
   265         -        }else{
   266         -          zPriorName = 0;
   267    489           }
   268    490           if( p->nFile>=p->nFileAlloc ){
   269    491             p->nFileAlloc = p->nFileAlloc*2 + 10;
   270         -          p->aFile = realloc(p->aFile, p->nFileAlloc*sizeof(p->aFile[0]) );
   271         -          if( p->aFile==0 ) fossil_panic("out of memory");
          492  +          p->aFile = fossil_realloc(p->aFile, 
          493  +                                    p->nFileAlloc*sizeof(p->aFile[0]) );
   272    494           }
   273    495           i = p->nFile++;
   274    496           p->aFile[i].zName = zName;
   275    497           p->aFile[i].zUuid = zUuid;
   276    498           p->aFile[i].zPerm = zPerm;
   277    499           p->aFile[i].zPrior = zPriorName;
   278         -        p->aFile[i].iRename = -1;
   279    500           if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){
   280    501             goto manifest_syntax_error;
   281    502           }
   282    503           break;
   283    504         }
   284    505   
   285    506         /*
................................................................................
   288    509         ** Specifies a name value pair for ticket.  If the first character
   289    510         ** of <name> is "+" then the <value> is appended to any preexisting
   290    511         ** value.  If <value> is omitted then it is understood to be an
   291    512         ** empty string.
   292    513         */
   293    514         case 'J': {
   294    515           char *zName, *zValue;
   295         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   296         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   297         -        blob_token(&line, &a2);
   298         -        if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error;
   299         -        zName = blob_terminate(&a1);
   300         -        zValue = blob_terminate(&a2);
          516  +        zName = next_token(&x,0);
          517  +        zValue = next_token(&x,0);
          518  +        if( zName==0 ) goto manifest_syntax_error;
          519  +        if( zValue==0 ) zValue = "";
   301    520           defossilize(zValue);
   302    521           if( p->nField>=p->nFieldAlloc ){
   303    522             p->nFieldAlloc = p->nFieldAlloc*2 + 10;
   304         -          p->aField = realloc(p->aField,
          523  +          p->aField = fossil_realloc(p->aField,
   305    524                                  p->nFieldAlloc*sizeof(p->aField[0]) );
   306         -          if( p->aField==0 ) fossil_panic("out of memory");
   307    525           }
   308    526           i = p->nField++;
   309    527           p->aField[i].zName = zName;
   310    528           p->aField[i].zValue = zValue;
   311    529           if( i>0 && strcmp(p->aField[i-1].zName, zName)>=0 ){
   312    530             goto manifest_syntax_error;
   313    531           }
................................................................................
   318    536         /*
   319    537         **    K <uuid>
   320    538         **
   321    539         ** A K-line gives the UUID for the ticket which this control file
   322    540         ** is amending.
   323    541         */
   324    542         case 'K': {
   325         -        char *zUuid;
   326         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   327         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   328         -        zUuid = blob_terminate(&a1);
   329         -        if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
   330         -        if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
   331    543           if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
   332         -        p->zTicketUuid = zUuid;
          544  +        p->zTicketUuid = next_token(&x, &sz);
          545  +        if( sz!=UUID_SIZE ) goto manifest_syntax_error;
          546  +        if( !validate16(p->zTicketUuid, UUID_SIZE) ) goto manifest_syntax_error;
   333    547           break;
   334    548         }
   335    549   
   336    550         /*
   337    551         **     L <wikititle>
   338    552         **
   339    553         ** The wiki page title is fossil-encoded.  There may be no more than
   340    554         ** one L line.
   341    555         */
   342    556         case 'L': {
   343         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   344    557           if( p->zWikiTitle!=0 ) goto manifest_syntax_error;
   345         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   346         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   347         -        p->zWikiTitle = blob_terminate(&a1);
          558  +        p->zWikiTitle = next_token(&x,0);
          559  +        if( p->zWikiTitle==0 ) goto manifest_syntax_error;
   348    560           defossilize(p->zWikiTitle);
   349    561           if( !wiki_name_is_wellformed((const unsigned char *)p->zWikiTitle) ){
   350    562             goto manifest_syntax_error;
   351    563           }
   352    564           break;
   353    565         }
   354    566   
................................................................................
   355    567         /*
   356    568         **    M <uuid>
   357    569         **
   358    570         ** An M-line identifies another artifact by its UUID.  M-lines
   359    571         ** occur in clusters only.
   360    572         */
   361    573         case 'M': {
   362         -        char *zUuid;
   363         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   364         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   365         -        zUuid = blob_terminate(&a1);
   366         -        if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
          574  +        zUuid = next_token(&x, &sz);
          575  +        if( zUuid==0 ) goto manifest_syntax_error;
          576  +        if( sz!=UUID_SIZE ) goto manifest_syntax_error;
   367    577           if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
   368    578           if( p->nCChild>=p->nCChildAlloc ){
   369    579             p->nCChildAlloc = p->nCChildAlloc*2 + 10;
   370         -          p->azCChild = 
   371         -             realloc(p->azCChild, p->nCChildAlloc*sizeof(p->azCChild[0]) );
   372         -          if( p->azCChild==0 ) fossil_panic("out of memory");
          580  +          p->azCChild = fossil_realloc(p->azCChild
          581  +                                 , p->nCChildAlloc*sizeof(p->azCChild[0]) );
   373    582           }
   374    583           i = p->nCChild++;
   375    584           p->azCChild[i] = zUuid;
   376    585           if( i>0 && strcmp(p->azCChild[i-1], zUuid)>=0 ){
   377    586             goto manifest_syntax_error;
   378    587           }
   379    588           break;
................................................................................
   383    592         **     P <uuid> ...
   384    593         **
   385    594         ** Specify one or more other artifacts where are the parents of
   386    595         ** this artifact.  The first parent is the primary parent.  All
   387    596         ** others are parents by merge.
   388    597         */
   389    598         case 'P': {
   390         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   391         -        while( blob_token(&line, &a1) ){
   392         -          char *zUuid;
   393         -          if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
   394         -          zUuid = blob_terminate(&a1);
          599  +        while( (zUuid = next_token(&x, &sz))!=0 ){
          600  +          if( sz!=UUID_SIZE ) goto manifest_syntax_error;
   395    601             if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
   396    602             if( p->nParent>=p->nParentAlloc ){
   397    603               p->nParentAlloc = p->nParentAlloc*2 + 5;
   398         -            p->azParent = realloc(p->azParent, p->nParentAlloc*sizeof(char*));
   399         -            if( p->azParent==0 ) fossil_panic("out of memory");
          604  +            p->azParent = fossil_realloc(p->azParent,
          605  +                               p->nParentAlloc*sizeof(char*));
   400    606             }
   401    607             i = p->nParent++;
   402    608             p->azParent[i] = zUuid;
   403    609           }
   404    610           break;
   405    611         }
   406    612   
   407    613         /*
   408    614         **     R <md5sum>
   409    615         **
   410         -      ** Specify the MD5 checksum of the entire baseline in a
   411         -      ** manifest.
          616  +      ** Specify the MD5 checksum over the name and content of all files
          617  +      ** in the manifest.
   412    618         */
   413    619         case 'R': {
   414         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   415    620           if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
   416         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   417         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   418         -        if( blob_size(&a1)!=32 ) goto manifest_syntax_error;
   419         -        p->zRepoCksum = blob_terminate(&a1);
          621  +        p->zRepoCksum = next_token(&x, &sz);
          622  +        if( sz!=32 ) goto manifest_syntax_error;
   420    623           if( !validate16(p->zRepoCksum, 32) ) goto manifest_syntax_error;
   421    624           break;
   422    625         }
   423    626   
   424    627         /*
   425    628         **    T (+|*|-)<tagname> <uuid> ?<value>?
   426    629         **
................................................................................
   433    636         ** The tag is applied to <uuid>.  If <uuid> is "*" then the tag is
   434    637         ** applied to the current manifest.  If <value> is provided then 
   435    638         ** the tag is really a property with the given value.
   436    639         **
   437    640         ** Tags are not allowed in clusters.  Multiple T lines are allowed.
   438    641         */
   439    642         case 'T': {
   440         -        char *zName, *zUuid, *zValue;
   441         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   442         -        if( blob_token(&line, &a1)==0 ){
   443         -          goto manifest_syntax_error;
   444         -        }
   445         -        if( blob_token(&line, &a2)==0 ){
   446         -          goto manifest_syntax_error;
   447         -        }
   448         -        zName = blob_terminate(&a1);
   449         -        zUuid = blob_terminate(&a2);
   450         -        if( blob_token(&line, &a3)==0 ){
   451         -          zValue = 0;
   452         -        }else{
   453         -          zValue = blob_terminate(&a3);
   454         -          defossilize(zValue);
   455         -        }
   456         -        if( blob_size(&a2)==UUID_SIZE && validate16(zUuid, UUID_SIZE) ){
          643  +        char *zName, *zValue;
          644  +        zName = next_token(&x, 0);
          645  +        if( zName==0 ) goto manifest_syntax_error;
          646  +        zUuid = next_token(&x, &sz);
          647  +        if( zUuid==0 ) goto manifest_syntax_error;
          648  +        zValue = next_token(&x, 0);
          649  +        if( zValue ) defossilize(zValue);
          650  +        if( sz==UUID_SIZE && validate16(zUuid, UUID_SIZE) ){
   457    651             /* A valid uuid */
   458         -        }else if( blob_size(&a2)==1 && zUuid[0]=='*' ){
          652  +        }else if( sz==1 && zUuid[0]=='*' ){
   459    653             zUuid = 0;
   460    654           }else{
   461    655             goto manifest_syntax_error;
   462    656           }
   463    657           defossilize(zName);
   464    658           if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
   465    659             goto manifest_syntax_error;
................................................................................
   466    660           }
   467    661           if( validate16(&zName[1], strlen(&zName[1])) ){
   468    662             /* Do not allow tags whose names look like UUIDs */
   469    663             goto manifest_syntax_error;
   470    664           }
   471    665           if( p->nTag>=p->nTagAlloc ){
   472    666             p->nTagAlloc = p->nTagAlloc*2 + 10;
   473         -          p->aTag = realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) );
   474         -          if( p->aTag==0 ) fossil_panic("out of memory");
          667  +          p->aTag = fossil_realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) );
   475    668           }
   476    669           i = p->nTag++;
   477    670           p->aTag[i].zName = zName;
   478    671           p->aTag[i].zUuid = zUuid;
   479    672           p->aTag[i].zValue = zValue;
   480    673           if( i>0 && strcmp(p->aTag[i-1].zName, zName)>=0 ){
   481    674             goto manifest_syntax_error;
................................................................................
   487    680         **     U ?<login>?
   488    681         **
   489    682         ** Identify the user who created this control file by their
   490    683         ** login.  Only one U line is allowed.  Prohibited in clusters.
   491    684         ** If the user name is omitted, take that to be "anonymous".
   492    685         */
   493    686         case 'U': {
   494         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   495    687           if( p->zUser!=0 ) goto manifest_syntax_error;
   496         -        if( blob_token(&line, &a1)==0 ){
          688  +        p->zUser = next_token(&x, 0);
          689  +        if( p->zUser==0 ){
   497    690             p->zUser = "anonymous";
   498    691           }else{
   499         -          p->zUser = blob_terminate(&a1);
   500    692             defossilize(p->zUser);
   501    693           }
   502         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   503    694           break;
   504    695         }
   505    696   
   506    697         /*
   507    698         **     W <size>
   508    699         **
   509    700         ** The next <size> bytes of the file contain the text of the wiki
   510    701         ** page.  There is always an extra \n before the start of the next
   511    702         ** record.
   512    703         */
   513    704         case 'W': {
   514         -        int size;
          705  +        char *zSize;
          706  +        int size, c;
   515    707           Blob wiki;
   516         -        md5sum_step_text(blob_buffer(&line), blob_size(&line));
   517         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   518         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   519         -        if( !blob_is_int(&a1, &size) ) goto manifest_syntax_error;
          708  +        zSize = next_token(&x, 0);
          709  +        if( zSize==0 ) goto manifest_syntax_error;
          710  +        if( x.atEol==0 ) goto manifest_syntax_error;
          711  +        for(size=0; (c = zSize[0])>='0' && c<='9'; zSize++){
          712  +           size = size*10 + c - '0';
          713  +        }
   520    714           if( size<0 ) goto manifest_syntax_error;
   521    715           if( p->zWiki!=0 ) goto manifest_syntax_error;
   522    716           blob_zero(&wiki);
   523         -        if( blob_extract(pContent, size+1, &wiki)!=size+1 ){
   524         -          goto manifest_syntax_error;
   525         -        }
   526         -        p->zWiki = blob_buffer(&wiki);
   527         -        md5sum_step_text(p->zWiki, size+1);
   528         -        if( p->zWiki[size]!='\n' ) goto manifest_syntax_error;
   529         -        p->zWiki[size] = 0;
          717  +        if( (&x.z[size+1])>=x.zEnd ) goto manifest_syntax_error;
          718  +        p->zWiki = x.z;
          719  +        x.z += size;
          720  +        if( x.z[0]!='\n' ) goto manifest_syntax_error;
          721  +        x.z[0] = 0;
          722  +        x.z++;
   530    723           break;
   531    724         }
   532    725   
   533    726   
   534    727         /*
   535    728         **     Z <md5sum>
   536    729         **
................................................................................
   539    732         ** line.  This must be the last record.
   540    733         **
   541    734         ** This card is required for all control file types except for
   542    735         ** Manifest.  It is not required for manifest only for historical
   543    736         ** compatibility reasons.
   544    737         */
   545    738         case 'Z': {
   546         -        int rc;
   547         -        Blob hash;
   548         -        if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
   549         -        if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
   550         -        if( blob_size(&a1)!=32 ) goto manifest_syntax_error;
   551         -        if( !validate16(blob_buffer(&a1), 32) ) goto manifest_syntax_error;
   552         -        md5sum_finish(&hash);
   553         -        rc = blob_compare(&hash, &a1);
   554         -        blob_reset(&hash);
   555         -        if( rc!=0 ) goto manifest_syntax_error;
          739  +        zUuid = next_token(&x, &sz);
          740  +        if( sz!=32 ) goto manifest_syntax_error;
          741  +        if( !validate16(zUuid, 32) ) goto manifest_syntax_error;
   556    742           seenZ = 1;
   557    743           break;
   558    744         }
   559    745         default: {
   560    746           goto manifest_syntax_error;
   561    747         }
   562    748       }
   563    749     }
   564         -  if( !seenHeader ) goto manifest_syntax_error;
          750  +  if( x.z<x.zEnd ) goto manifest_syntax_error;
   565    751   
   566         -  if( p->nFile>0 || p->zRepoCksum!=0 ){
          752  +  if( p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline ){
   567    753       if( p->nCChild>0 ) goto manifest_syntax_error;
   568         -    if( p->rDate==0.0 ) goto manifest_syntax_error;
          754  +    if( p->rDate<=0.0 ) goto manifest_syntax_error;
   569    755       if( p->nField>0 ) goto manifest_syntax_error;
   570    756       if( p->zTicketUuid ) goto manifest_syntax_error;
   571    757       if( p->zWiki ) goto manifest_syntax_error;
   572    758       if( p->zWikiTitle ) goto manifest_syntax_error;
          759  +    if( p->zEventId ) goto manifest_syntax_error;
   573    760       if( p->zTicketUuid ) goto manifest_syntax_error;
   574    761       if( p->zAttachName ) goto manifest_syntax_error;
   575    762       p->type = CFTYPE_MANIFEST;
   576    763     }else if( p->nCChild>0 ){
   577    764       if( p->rDate>0.0 ) goto manifest_syntax_error;
   578    765       if( p->zComment!=0 ) goto manifest_syntax_error;
   579    766       if( p->zUser!=0 ) goto manifest_syntax_error;
   580    767       if( p->nTag>0 ) goto manifest_syntax_error;
   581    768       if( p->nParent>0 ) goto manifest_syntax_error;
   582    769       if( p->nField>0 ) goto manifest_syntax_error;
   583    770       if( p->zTicketUuid ) goto manifest_syntax_error;
   584    771       if( p->zWiki ) goto manifest_syntax_error;
   585    772       if( p->zWikiTitle ) goto manifest_syntax_error;
          773  +    if( p->zEventId ) goto manifest_syntax_error;
   586    774       if( p->zAttachName ) goto manifest_syntax_error;
   587    775       if( !seenZ ) goto manifest_syntax_error;
   588    776       p->type = CFTYPE_CLUSTER;
   589    777     }else if( p->nField>0 ){
   590         -    if( p->rDate==0.0 ) goto manifest_syntax_error;
          778  +    if( p->rDate<=0.0 ) goto manifest_syntax_error;
   591    779       if( p->zWiki ) goto manifest_syntax_error;
   592    780       if( p->zWikiTitle ) goto manifest_syntax_error;
          781  +    if( p->zEventId ) goto manifest_syntax_error;
   593    782       if( p->nCChild>0 ) goto manifest_syntax_error;
   594    783       if( p->nTag>0 ) goto manifest_syntax_error;
   595    784       if( p->zTicketUuid==0 ) goto manifest_syntax_error;
   596    785       if( p->zUser==0 ) goto manifest_syntax_error;
   597    786       if( p->zAttachName ) goto manifest_syntax_error;
   598    787       if( !seenZ ) goto manifest_syntax_error;
   599    788       p->type = CFTYPE_TICKET;
          789  +  }else if( p->zEventId ){
          790  +    if( p->rDate<=0.0 ) goto manifest_syntax_error;
          791  +    if( p->nCChild>0 ) goto manifest_syntax_error;
          792  +    if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
          793  +    if( p->zWikiTitle!=0 ) goto manifest_syntax_error;
          794  +    if( p->zWiki==0 ) goto manifest_syntax_error;
          795  +    if( p->zAttachName ) goto manifest_syntax_error;
          796  +    for(i=0; i<p->nTag; i++){
          797  +      if( p->aTag[i].zName[0]!='+' ) goto manifest_syntax_error;
          798  +      if( p->aTag[i].zUuid!=0 ) goto manifest_syntax_error;
          799  +    }
          800  +    if( !seenZ ) goto manifest_syntax_error;
          801  +    p->type = CFTYPE_EVENT;
   600    802     }else if( p->zWiki!=0 ){
   601         -    if( p->rDate==0.0 ) goto manifest_syntax_error;
          803  +    if( p->rDate<=0.0 ) goto manifest_syntax_error;
   602    804       if( p->nCChild>0 ) goto manifest_syntax_error;
   603    805       if( p->nTag>0 ) goto manifest_syntax_error;
   604    806       if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
   605    807       if( p->zWikiTitle==0 ) goto manifest_syntax_error;
   606    808       if( p->zAttachName ) goto manifest_syntax_error;
   607    809       if( !seenZ ) goto manifest_syntax_error;
   608    810       p->type = CFTYPE_WIKI;
................................................................................
   612    814       if( p->zWikiTitle ) goto manifest_syntax_error;
   613    815       if( p->zTicketUuid ) goto manifest_syntax_error;
   614    816       if( p->zAttachName ) goto manifest_syntax_error;
   615    817       if( !seenZ ) goto manifest_syntax_error;
   616    818       p->type = CFTYPE_CONTROL;
   617    819     }else if( p->zAttachName ){
   618    820       if( p->nCChild>0 ) goto manifest_syntax_error;
   619         -    if( p->rDate==0.0 ) goto manifest_syntax_error;
          821  +    if( p->rDate<=0.0 ) goto manifest_syntax_error;
   620    822       if( p->zTicketUuid ) goto manifest_syntax_error;
   621    823       if( p->zWikiTitle ) goto manifest_syntax_error;
   622    824       if( !seenZ ) goto manifest_syntax_error;
   623    825       p->type = CFTYPE_ATTACHMENT;
   624    826     }else{
   625    827       if( p->nCChild>0 ) goto manifest_syntax_error;
   626    828       if( p->rDate<=0.0 ) goto manifest_syntax_error;
   627    829       if( p->nParent>0 ) goto manifest_syntax_error;
   628    830       if( p->nField>0 ) goto manifest_syntax_error;
   629    831       if( p->zTicketUuid ) goto manifest_syntax_error;
   630         -    if( p->zWiki ) goto manifest_syntax_error;
   631    832       if( p->zWikiTitle ) goto manifest_syntax_error;
   632    833       if( p->zTicketUuid ) goto manifest_syntax_error;
   633         -    if( p->zAttachName ) goto manifest_syntax_error;
   634    834       p->type = CFTYPE_MANIFEST;
   635    835     }
   636    836     md5sum_init();
   637         -  return 1;
          837  +  return p;
   638    838   
   639    839   manifest_syntax_error:
   640    840     /*fprintf(stderr, "Manifest error on line %i\n", lineNo);fflush(stderr);*/
   641    841     md5sum_init();
   642         -  manifest_clear(p);
          842  +  manifest_destroy(p);
   643    843     return 0;
   644    844   }
          845  +
          846  +/*
          847  +** Get a manifest given the rid for the control artifact.  Return
          848  +** a pointer to the manifest on success or NULL if there is a failure.
          849  +*/
          850  +Manifest *manifest_get(int rid, int cfType){
          851  +  Blob content;
          852  +  Manifest *p;
          853  +  p = manifest_cache_find(rid);
          854  +  if( p ){
          855  +    if( cfType!=CFTYPE_ANY && cfType!=p->type ){
          856  +      manifest_cache_insert(p);
          857  +      p = 0;
          858  +    }
          859  +    return p;
          860  +  }
          861  +  content_get(rid, &content);
          862  +  p = manifest_parse(&content, rid);
          863  +  if( p && cfType!=CFTYPE_ANY && cfType!=p->type ){
          864  +    manifest_destroy(p);
          865  +    p = 0;
          866  +  }
          867  +  return p;
          868  +}
          869  +
          870  +/*
          871  +** Given a checkin name, load and parse the manifest for that checkin.
          872  +** Throw a fatal error if anything goes wrong.
          873  +*/
          874  +Manifest *manifest_get_by_name(const char *zName, int *pRid){
          875  +  int rid;
          876  +  Manifest *p;
          877  +
          878  +  rid = name_to_rid(zName);
          879  +  if( !is_a_version(rid) ){
          880  +    fossil_fatal("no such checkin: %s", zName);
          881  +  }
          882  +  if( pRid ) *pRid = rid;
          883  +  p = manifest_get(rid, CFTYPE_MANIFEST);
          884  +  if( p==0 ){
          885  +    fossil_fatal("cannot parse manifest for checkin: %s", zName);
          886  +  }
          887  +  return p;
          888  +}
   645    889   
   646    890   /*
   647    891   ** COMMAND: test-parse-manifest
   648    892   **
   649         -** Usage: %fossil test-parse-manifest FILENAME
          893  +** Usage: %fossil test-parse-manifest FILENAME ?N?
   650    894   **
   651    895   ** Parse the manifest and discarded.  Use for testing only.
   652    896   */
   653    897   void manifest_test_parse_cmd(void){
   654         -  Manifest m;
          898  +  Manifest *p;
   655    899     Blob b;
   656         -  if( g.argc!=3 ){
          900  +  int i;
          901  +  int n = 1;
          902  +  sqlite3_open(":memory:", &g.db);
          903  +  if( g.argc!=3 && g.argc!=4 ){
   657    904       usage("FILENAME");
   658    905     }
   659         -  db_must_be_within_tree();
   660    906     blob_read_from_file(&b, g.argv[2]);
   661         -  manifest_parse(&m, &b);
   662         -  manifest_clear(&m);
          907  +  if( g.argc>3 ) n = atoi(g.argv[3]);
          908  +  for(i=0; i<n; i++){
          909  +    Blob b2;
          910  +    blob_copy(&b2, &b);
          911  +    p = manifest_parse(&b2, 0);
          912  +    manifest_destroy(p);
          913  +  }
          914  +}
          915  +
          916  +/*
          917  +** Fetch the baseline associated with the delta-manifest p.
          918  +** Return 0 on success.  If unable to parse the baseline,
          919  +** throw an error.  If the baseline is a manifest, throw an
          920  +** error if throwError is true, or record that p is an orphan
          921  +** and return 1 throwError is false.
          922  +*/
          923  +static int fetch_baseline(Manifest *p, int throwError){
          924  +  if( p->zBaseline!=0 && p->pBaseline==0 ){
          925  +    int rid = uuid_to_rid(p->zBaseline, 0);
          926  +    if( rid==0 && !throwError ){
          927  +      rid = content_new(p->zBaseline);
          928  +      db_multi_exec(
          929  +         "INSERT OR IGNORE INTO orphan(rid, baseline) VALUES(%d,%d)",
          930  +         rid, p->rid
          931  +      );
          932  +      return 1;
          933  +    }
          934  +    p->pBaseline = manifest_get(rid, CFTYPE_MANIFEST);
          935  +    if( p->pBaseline==0 ){
          936  +      if( !throwError && db_exists("SELECT 1 FROM phantom WHERE rid=%d",rid) ){
          937  +        db_multi_exec(
          938  +           "INSERT OR IGNORE INTO orphan(rid, baseline) VALUES(%d,%d)",
          939  +           rid, p->rid
          940  +        );
          941  +        return 1;
          942  +      }    
          943  +      fossil_fatal("cannot access baseline manifest %S", p->zBaseline);
          944  +    }
          945  +  }
          946  +  return 0;
          947  +}
          948  +
          949  +/*
          950  +** Rewind a manifest-file iterator back to the beginning of the manifest.
          951  +*/
          952  +void manifest_file_rewind(Manifest *p){
          953  +  p->iFile = 0;
          954  +  fetch_baseline(p, 1);
          955  +  if( p->pBaseline ){
          956  +    p->pBaseline->iFile = 0;
          957  +  }
          958  +}
          959  +
          960  +/*
          961  +** Advance to the next manifest-file.
          962  +**
          963  +** Return NULL for end-of-records or if there is an error.  If an error
          964  +** occurs and pErr!=0 then store 1 in *pErr.
          965  +*/
          966  +ManifestFile *manifest_file_next(
          967  +  Manifest *p,   
          968  +  int *pErr
          969  +){
          970  +  ManifestFile *pOut = 0;
          971  +  if( pErr ) *pErr = 0;
          972  +  if( p->pBaseline==0 ){
          973  +    /* Manifest p is a baseline-manifest.  Just scan down the list
          974  +    ** of files. */
          975  +    if( p->iFile<p->nFile ) pOut = &p->aFile[p->iFile++];
          976  +  }else{
          977  +    /* Manifest p is a delta-manifest.  Scan the baseline but amend the
          978  +    ** file list in the baseline with changes described by p.
          979  +    */
          980  +    Manifest *pB = p->pBaseline;
          981  +    int cmp;
          982  +    while(1){
          983  +      if( pB->iFile>=pB->nFile ){
          984  +        /* We have used all entries out of the baseline.  Return the next
          985  +        ** entry from the delta. */
          986  +        if( p->iFile<p->nFile ) pOut = &p->aFile[p->iFile++];
          987  +        break;
          988  +      }else if( p->iFile>=p->nFile ){
          989  +        /* We have used all entries from the delta.  Return the next
          990  +        ** entry from the baseline. */
          991  +        if( pB->iFile<pB->nFile ) pOut = &pB->aFile[pB->iFile++];
          992  +        break;
          993  +      }else if( (cmp = strcmp(pB->aFile[pB->iFile].zName,
          994  +                              p->aFile[p->iFile].zName)) < 0 ){
          995  +        /* The next baseline entry comes before the next delta entry.
          996  +        ** So return the baseline entry. */
          997  +        pOut = &pB->aFile[pB->iFile++];
          998  +        break;
          999  +      }else if( cmp>0 ){
         1000  +        /* The next delta entry comes before the next baseline
         1001  +        ** entry so return the delta entry */
         1002  +        pOut = &p->aFile[p->iFile++];
         1003  +        break;
         1004  +      }else if( p->aFile[p->iFile].zUuid ){
         1005  +        /* The next delta entry is a replacement for the next baseline
         1006  +        ** entry.  Skip the baseline entry and return the delta entry */
         1007  +        pB->iFile++;
         1008  +        pOut = &p->aFile[p->iFile++];
         1009  +        break;
         1010  +      }else{
         1011  +        /* The next delta entry is a delete of the next baseline
         1012  +        ** entry.  Skip them both.  Repeat the loop to find the next
         1013  +        ** non-delete entry. */
         1014  +        pB->iFile++;
         1015  +        p->iFile++;
         1016  +        continue;
         1017  +      }
         1018  +    }
         1019  +  }
         1020  +  return pOut;
   663   1021   }
   664   1022   
   665   1023   /*
   666   1024   ** Translate a filename into a filename-id (fnid).  Create a new fnid
   667   1025   ** if no previously exists.
   668   1026   */
   669   1027   static int filename_to_fnid(const char *zFilename){
................................................................................
   687   1045   
   688   1046   /*
   689   1047   ** Add a single entry to the mlink table.  Also add the filename to
   690   1048   ** the filename table if it is not there already.
   691   1049   */
   692   1050   static void add_one_mlink(
   693   1051     int mid,                  /* The record ID of the manifest */
   694         -  const char *zFromUuid,    /* UUID for the mlink.pid field */
   695         -  const char *zToUuid,      /* UUID for the mlink.fid field */
         1052  +  const char *zFromUuid,    /* UUID for the mlink.pid. "" to add file */
         1053  +  const char *zToUuid,      /* UUID for the mlink.fid. "" to delele */
   696   1054     const char *zFilename,    /* Filename */
   697         -  const char *zPrior        /* Previous filename.  NULL if unchanged */
         1055  +  const char *zPrior        /* Previous filename. NULL if unchanged */
   698   1056   ){
   699   1057     int fnid, pfnid, pid, fid;
   700   1058     static Stmt s1;
   701   1059   
   702   1060     fnid = filename_to_fnid(zFilename);
   703   1061     if( zPrior==0 ){
   704   1062       pfnid = 0;
   705   1063     }else{
   706   1064       pfnid = filename_to_fnid(zPrior);
   707   1065     }
   708         -  if( zFromUuid==0 ){
         1066  +  if( zFromUuid==0 || zFromUuid[0]==0 ){
   709   1067       pid = 0;
   710   1068     }else{
   711   1069       pid = uuid_to_rid(zFromUuid, 1);
   712   1070     }
   713         -  if( zToUuid==0 ){
         1071  +  if( zToUuid==0 || zToUuid[0]==0 ){
   714   1072       fid = 0;
   715   1073     }else{
   716   1074       fid = uuid_to_rid(zToUuid, 1);
   717   1075     }
   718   1076     db_static_prepare(&s1,
   719   1077       "INSERT INTO mlink(mid,pid,fid,fnid,pfnid)"
   720   1078       "VALUES(:m,:p,:f,:n,:pfn)"
................................................................................
   727   1085     db_exec(&s1);
   728   1086     if( pid && fid ){
   729   1087       content_deltify(pid, fid, 0);
   730   1088     }
   731   1089   }
   732   1090   
   733   1091   /*
   734         -** Locate a file named zName in the aFile[] array of the given
   735         -** manifest.  We assume that filenames are in sorted order.
   736         -** Use a binary search.  Return turn the index of the matching
   737         -** entry.  Or return -1 if not found.
         1092  +** Do a binary search to find a file in the p->aFile[] array.  
         1093  +**
         1094  +** As an optimization, guess that the file we seek is at index p->iFile.
         1095  +** That will usually be the case.  If it is not found there, then do the
         1096  +** actual binary search.
         1097  +**
         1098  +** Update p->iFile to be the index of the file that is found.
   738   1099   */
   739         -static int find_file_in_manifest(Manifest *p, const char *zName){
         1100  +static ManifestFile *manifest_file_seek_base(Manifest *p, const char *zName){
   740   1101     int lwr, upr;
   741   1102     int c;
   742   1103     int i;
   743   1104     lwr = 0;
   744   1105     upr = p->nFile - 1;
         1106  +  if( p->iFile>=lwr && p->iFile<upr ){
         1107  +    c = strcmp(p->aFile[p->iFile+1].zName, zName);
         1108  +    if( c==0 ){
         1109  +      return &p->aFile[++p->iFile];
         1110  +    }else if( c>0 ){
         1111  +      upr = p->iFile;
         1112  +    }else{
         1113  +      lwr = p->iFile+1;
         1114  +    }
         1115  +  }
   745   1116     while( lwr<=upr ){
   746   1117       i = (lwr+upr)/2;
   747   1118       c = strcmp(p->aFile[i].zName, zName);
   748   1119       if( c<0 ){
   749   1120         lwr = i+1;
   750   1121       }else if( c>0 ){
   751   1122         upr = i-1;
   752   1123       }else{
   753         -      return i;
         1124  +      p->iFile = i;
         1125  +      return &p->aFile[i];
   754   1126       }
   755   1127     }
   756         -  return -1;
         1128  +  return 0;
         1129  +}
         1130  +
         1131  +/*
         1132  +** Locate a file named zName in the aFile[] array of the given manifest.
         1133  +** Return a pointer to the appropriate ManifestFile object.  Return NULL
         1134  +** if not found.
         1135  +**
         1136  +** This routine works even if p is a delta-manifest.  The pointer 
         1137  +** returned might be to the baseline.
         1138  +**
         1139  +** We assume that filenames are in sorted order and use a binary search.
         1140  +*/
         1141  +ManifestFile *manifest_file_seek(Manifest *p, const char *zName){
         1142  +  ManifestFile *pFile;
         1143  +  
         1144  +  pFile = manifest_file_seek_base(p, zName);
         1145  +  if( pFile && pFile->zUuid==0 ) return 0;
         1146  +  if( pFile==0 && p->zBaseline ){
         1147  +    fetch_baseline(p, 1);
         1148  +    pFile = manifest_file_seek_base(p->pBaseline, zName);
         1149  +  }
         1150  +  return pFile;
         1151  +}
         1152  +
         1153  +/*
         1154  +** This strcmp() function handles NULL arguments.  NULLs sort first.
         1155  +*/
         1156  +static int strcmp_null(const char *zOne, const char *zTwo){
         1157  +  if( zOne==0 ){
         1158  +    if( zTwo==0 ) return 0;
         1159  +    return -1;
         1160  +  }else if( zTwo==0 ){
         1161  +    return +1;
         1162  +  }else{
         1163  +    return strcmp(zOne, zTwo);
         1164  +  }
   757   1165   }
   758   1166   
   759   1167   /*
   760   1168   ** Add mlink table entries associated with manifest cid.  The
   761   1169   ** parent manifest is pid.
   762   1170   **
   763   1171   ** A single mlink entry is added for every file that changed content
................................................................................
   764   1172   ** and/or name going from pid to cid.
   765   1173   **
   766   1174   ** Deleted files have mlink.fid=0.
   767   1175   ** Added files have mlink.pid=0.
   768   1176   ** Edited files have both mlink.pid!=0 and mlink.fid!=0
   769   1177   */
   770   1178   static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){
   771         -  Manifest other;
   772   1179     Blob otherContent;
   773         -  int i, j;
         1180  +  int otherRid;
         1181  +  int i, rc;
         1182  +  ManifestFile *pChildFile, *pParentFile;
         1183  +  Manifest **ppOther;
         1184  +  static Stmt eq;
   774   1185   
   775         -  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", cid) ){
   776         -    return;
   777         -  }
         1186  +  db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
         1187  +  db_bind_int(&eq, ":mid", cid);
         1188  +  rc = db_step(&eq);
         1189  +  db_reset(&eq);
         1190  +  if( rc==SQLITE_ROW ) return;
         1191  +
   778   1192     assert( pParent==0 || pChild==0 );
   779   1193     if( pParent==0 ){
   780         -    pParent = &other;
   781         -    content_get(pid, &otherContent);
         1194  +    ppOther = &pParent;
         1195  +    otherRid = pid;
   782   1196     }else{
   783         -    pChild = &other;
   784         -    content_get(cid, &otherContent);
   785         -  }
   786         -  if( blob_size(&otherContent)==0 ) return;
   787         -  if( manifest_parse(&other, &otherContent)==0 ) return;
   788         -  content_deltify(pid, cid, 0);
   789         -
   790         -  /* Use the iRename fields to find the cross-linkage between
   791         -  ** renamed files.  */
   792         -  for(j=0; j<pChild->nFile; j++){
   793         -    const char *zPrior = pChild->aFile[j].zPrior;
   794         -    if( zPrior && zPrior[0] ){
   795         -      i = find_file_in_manifest(pParent, zPrior);
   796         -      if( i>=0 ){
   797         -        pChild->aFile[j].iRename = i;
   798         -        pParent->aFile[i].iRename = j;
         1197  +    ppOther = &pChild;
         1198  +    otherRid = cid;
         1199  +  }
         1200  +  if( (*ppOther = manifest_cache_find(otherRid))==0 ){
         1201  +    content_get(otherRid, &otherContent);
         1202  +    if( blob_size(&otherContent)==0 ) return;
         1203  +    *ppOther = manifest_parse(&otherContent, otherRid);
         1204  +    if( *ppOther==0 ) return;
         1205  +  }
         1206  +  if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
         1207  +    manifest_destroy(*ppOther);
         1208  +    return;
         1209  +  }
         1210  +  if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
         1211  +    content_deltify(pid, cid, 0); 
         1212  +  }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
         1213  +    content_deltify(pParent->pBaseline->rid, cid, 0);
         1214  +  }
         1215  +  
         1216  +  for(i=0, pChildFile=pChild->aFile; i<pChild->nFile; i++, pChildFile++){
         1217  +    if( pChildFile->zPrior ){
         1218  +       pParentFile = manifest_file_seek(pParent, pChildFile->zPrior);
         1219  +       if( pParentFile ){
         1220  +         add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
         1221  +                       pChildFile->zName, pChildFile->zPrior);
         1222  +       }
         1223  +    }else{
         1224  +       pParentFile = manifest_file_seek(pParent, pChildFile->zName);
         1225  +       if( pParentFile==0 ){
         1226  +         if( pChildFile->zUuid ){
         1227  +           add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
         1228  +         }
         1229  +       }else if( strcmp_null(pChildFile->zUuid, pParentFile->zUuid)!=0 ){
         1230  +         add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
         1231  +                       pChildFile->zName, 0);
         1232  +       }
         1233  +    }
         1234  +  }
         1235  +  if( pParent->zBaseline && pChild->zBaseline ){
         1236  +    for(i=0, pParentFile=pParent->aFile; i<pParent->nFile; i++, pParentFile++){
         1237  +      if( pParentFile->zUuid ) continue;
         1238  +      pChildFile = manifest_file_seek(pChild, pParentFile->zName);
         1239  +      if( pChildFile ){
         1240  +        add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
   799   1241         }
   800   1242       }
   801   1243     }
   802         -
   803         -  /* Construct the mlink entries */
   804         -  for(i=j=0; i<pParent->nFile && j<pChild->nFile; ){
   805         -    int c;
   806         -    if( pParent->aFile[i].iRename>=0 ){
   807         -      i++;
   808         -    }else if( (c = strcmp(pParent->aFile[i].zName, pChild->aFile[j].zName))<0 ){
   809         -      add_one_mlink(cid, pParent->aFile[i].zUuid,0,pParent->aFile[i].zName,0);
   810         -      i++;
   811         -    }else if( c>0 ){
   812         -      int rn = pChild->aFile[j].iRename;
   813         -      if( rn>=0 ){
   814         -        add_one_mlink(cid, pParent->aFile[rn].zUuid, pChild->aFile[j].zUuid, 
   815         -                      pChild->aFile[j].zName, pParent->aFile[rn].zName);
   816         -      }else{
   817         -        add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName,0);
   818         -      }
   819         -      j++;
   820         -    }else{
   821         -      if( strcmp(pParent->aFile[i].zUuid, pChild->aFile[j].zUuid)!=0 ){
   822         -        add_one_mlink(cid, pParent->aFile[i].zUuid, pChild->aFile[j].zUuid, 
   823         -                      pChild->aFile[j].zName, 0);
   824         -      }
   825         -      i++;
   826         -      j++;
   827         -    }
   828         -  }
   829         -  while( i<pParent->nFile ){
   830         -    if( pParent->aFile[i].iRename<0 ){
   831         -      add_one_mlink(cid, pParent->aFile[i].zUuid, 0, pParent->aFile[i].zName,0);
   832         -    }
   833         -    i++;
   834         -  }
   835         -  while( j<pChild->nFile ){
   836         -    int rn = pChild->aFile[j].iRename;
   837         -    if( rn>=0 ){
   838         -      add_one_mlink(cid, pParent->aFile[rn].zUuid, pChild->aFile[j].zUuid, 
   839         -                    pChild->aFile[j].zName, pParent->aFile[rn].zName);
   840         -    }else{
   841         -      add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName,0);
   842         -    }
   843         -    j++;
   844         -  }
   845         -  manifest_clear(&other);
         1244  +  manifest_cache_insert(*ppOther);
   846   1245   }
   847   1246   
   848   1247   /*
   849   1248   ** True if manifest_crosslink_begin() has been called but
   850   1249   ** manifest_crosslink_end() is still pending.
   851   1250   */
   852   1251   static int manifest_crosslink_busy = 0;
................................................................................
   962   1361   ** any key:
   963   1362   **
   964   1363   **      *  Manifest
   965   1364   **      *  Control
   966   1365   **      *  Wiki Page
   967   1366   **      *  Ticket Change
   968   1367   **      *  Cluster
         1368  +**      *  Attachment
         1369  +**      *  Event
   969   1370   **
   970   1371   ** If the input is a control artifact, then make appropriate entries
   971   1372   ** in the auxiliary tables of the database in order to crosslink the
   972   1373   ** artifact.
   973   1374   **
   974   1375   ** If global variable g.xlinkClusterOnly is true, then ignore all 
   975   1376   ** control artifacts other than clusters.
................................................................................
   977   1378   ** Historical note:  This routine original processed manifests only.
   978   1379   ** Processing for other control artifacts was added later.  The name
   979   1380   ** of the routine, "manifest_crosslink", and the name of this source
   980   1381   ** file, is a legacy of its original use.
   981   1382   */
   982   1383   int manifest_crosslink(int rid, Blob *pContent){
   983   1384     int i;
   984         -  Manifest m;
         1385  +  Manifest *p;
   985   1386     Stmt q;
   986   1387     int parentid = 0;
   987   1388   
   988         -  if( manifest_parse(&m, pContent)==0 ){
         1389  +  if( (p = manifest_cache_find(rid))!=0 ){
         1390  +    blob_reset(pContent);
         1391  +  }else if( (p = manifest_parse(pContent, rid))==0 ){
         1392  +    return 0;
         1393  +  }
         1394  +  if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
         1395  +    manifest_destroy(p);
   989   1396       return 0;
   990   1397     }
   991         -  if( g.xlinkClusterOnly && m.type!=CFTYPE_CLUSTER ){
   992         -    manifest_clear(&m);
         1398  +  if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
         1399  +    manifest_destroy(p);
   993   1400       return 0;
   994   1401     }
   995   1402     db_begin_transaction();
   996         -  if( m.type==CFTYPE_MANIFEST ){
         1403  +  if( p->type==CFTYPE_MANIFEST ){
   997   1404       if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
   998   1405         char *zCom;
   999         -      for(i=0; i<m.nParent; i++){
  1000         -        int pid = uuid_to_rid(m.azParent[i], 1);
         1406  +      for(i=0; i<p->nParent; i++){
         1407  +        int pid = uuid_to_rid(p->azParent[i], 1);
  1001   1408           db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
  1002         -                      "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate);
         1409  +                      "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, p->rDate);
  1003   1410           if( i==0 ){
  1004         -          add_mlink(pid, 0, rid, &m);
         1411  +          add_mlink(pid, 0, rid, p);
  1005   1412             parentid = pid;
  1006   1413           }
  1007   1414         }
  1008   1415         db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid);
  1009   1416         while( db_step(&q)==SQLITE_ROW ){
  1010   1417           int cid = db_column_int(&q, 0);
  1011         -        add_mlink(rid, &m, cid, 0);
         1418  +        add_mlink(rid, p, cid, 0);
  1012   1419         }
  1013   1420         db_finalize(&q);
  1014   1421         db_multi_exec(
  1015   1422           "REPLACE INTO event(type,mtime,objid,user,comment,"
  1016   1423                              "bgcolor,euser,ecomment)"
  1017   1424           "VALUES('ci',"
  1018   1425           "  coalesce("
................................................................................
  1019   1426           "    (SELECT julianday(value) FROM tagxref WHERE tagid=%d AND rid=%d),"
  1020   1427           "    %.17g"
  1021   1428           "  ),"
  1022   1429           "  %d,%Q,%Q,"
  1023   1430           "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>0),"
  1024   1431           "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
  1025   1432           "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
  1026         -        TAG_DATE, rid, m.rDate,
  1027         -        rid, m.zUser, m.zComment, 
         1433  +        TAG_DATE, rid, p->rDate,
         1434  +        rid, p->zUser, p->zComment, 
  1028   1435           TAG_BGCOLOR, rid,
  1029   1436           TAG_USER, rid,
  1030   1437           TAG_COMMENT, rid
  1031   1438         );
  1032   1439         zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event"
  1033   1440                           " WHERE rowid=last_insert_rowid()");
  1034         -      wiki_extract_links(zCom, rid, 0, m.rDate, 1, WIKI_INLINE);
         1441  +      wiki_extract_links(zCom, rid, 0, p->rDate, 1, WIKI_INLINE);
  1035   1442         free(zCom);
         1443  +
         1444  +      /* If this is a delta-manifest, record the fact that this repository
         1445  +      ** contains delta manifests, to free the "commit" logic to generate
         1446  +      ** new delta manifests.
         1447  +      */
         1448  +      if( p->zBaseline!=0 ){
         1449  +        static int once = 0;
         1450  +        if( !once ){
         1451  +          db_set_int("seen-delta-manifest", 1, 0);
         1452  +          once = 0;
         1453  +        }
         1454  +      }
  1036   1455       }
  1037   1456     }
  1038         -  if( m.type==CFTYPE_CLUSTER ){
  1039         -    tag_insert("cluster", 1, 0, rid, m.rDate, rid);
  1040         -    for(i=0; i<m.nCChild; i++){
         1457  +  if( p->type==CFTYPE_CLUSTER ){
         1458  +    static Stmt del1;
         1459  +    tag_insert("cluster", 1, 0, rid, p->rDate, rid);
         1460  +    db_static_prepare(&del1, "DELETE FROM unclustered WHERE rid=:rid");
         1461  +    for(i=0; i<p->nCChild; i++){
  1041   1462         int mid;
  1042         -      mid = uuid_to_rid(m.azCChild[i], 1);
         1463  +      mid = uuid_to_rid(p->azCChild[i], 1);
  1043   1464         if( mid>0 ){
  1044         -        db_multi_exec("DELETE FROM unclustered WHERE rid=%d", mid);
         1465  +        db_bind_int(&del1, ":rid", mid);
         1466  +        db_step(&del1);
         1467  +        db_reset(&del1);
  1045   1468         }
  1046   1469       }
  1047   1470     }
  1048         -  if( m.type==CFTYPE_CONTROL || m.type==CFTYPE_MANIFEST ){
  1049         -    for(i=0; i<m.nTag; i++){
         1471  +  if( p->type==CFTYPE_CONTROL
         1472  +   || p->type==CFTYPE_MANIFEST
         1473  +   || p->type==CFTYPE_EVENT
         1474  +  ){
         1475  +    for(i=0; i<p->nTag; i++){
  1050   1476         int tid;
  1051   1477         int type;
  1052         -      if( m.aTag[i].zUuid ){
  1053         -        tid = uuid_to_rid(m.aTag[i].zUuid, 1);
         1478  +      if( p->aTag[i].zUuid ){
         1479  +        tid = uuid_to_rid(p->aTag[i].zUuid, 1);
  1054   1480         }else{
  1055   1481           tid = rid;
  1056   1482         }
  1057   1483         if( tid ){
  1058         -        switch( m.aTag[i].zName[0] ){
         1484  +        switch( p->aTag[i].zName[0] ){
  1059   1485             case '-':  type = 0;  break;  /* Cancel prior occurances */
  1060   1486             case '+':  type = 1;  break;  /* Apply to target only */
  1061   1487             case '*':  type = 2;  break;  /* Propagate to descendants */
  1062   1488             default:
  1063         -            fossil_fatal("unknown tag type in manifest: %s", m.aTag);
         1489  +            fossil_fatal("unknown tag type in manifest: %s", p->aTag);
  1064   1490               return 0;
  1065   1491           }
  1066         -        tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue, 
  1067         -                   rid, m.rDate, tid);
         1492  +        tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue, 
         1493  +                   rid, p->rDate, tid);
  1068   1494         }
  1069   1495       }
  1070   1496       if( parentid ){
  1071   1497         tag_propagate_all(parentid);
  1072   1498       }
  1073   1499     }
  1074         -  if( m.type==CFTYPE_WIKI ){
  1075         -    char *zTag = mprintf("wiki-%s", m.zWikiTitle);
         1500  +  if( p->type==CFTYPE_WIKI ){
         1501  +    char *zTag = mprintf("wiki-%s", p->zWikiTitle);
  1076   1502       int tagid = tag_findid(zTag, 1);
  1077   1503       int prior;
  1078   1504       char *zComment;
  1079   1505       int nWiki;
  1080   1506       char zLength[40];
  1081         -    while( isspace(m.zWiki[0]) ) m.zWiki++;
  1082         -    nWiki = strlen(m.zWiki);
         1507  +    while( fossil_isspace(p->zWiki[0]) ) p->zWiki++;
         1508  +    nWiki = strlen(p->zWiki);
  1083   1509       sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki);
  1084         -    tag_insert(zTag, 1, zLength, rid, m.rDate, rid);
         1510  +    tag_insert(zTag, 1, zLength, rid, p->rDate, rid);
  1085   1511       free(zTag);
  1086   1512       prior = db_int(0,
  1087   1513         "SELECT rid FROM tagxref"
  1088   1514         " WHERE tagid=%d AND mtime<%.17g"
  1089   1515         " ORDER BY mtime DESC",
  1090         -      tagid, m.rDate
         1516  +      tagid, p->rDate
  1091   1517       );
  1092   1518       if( prior ){
  1093   1519         content_deltify(prior, rid, 0);
  1094   1520       }
  1095   1521       if( nWiki>0 ){
  1096         -      zComment = mprintf("Changes to wiki page [%h]", m.zWikiTitle);
         1522  +      zComment = mprintf("Changes to wiki page [%h]", p->zWikiTitle);
  1097   1523       }else{
  1098         -      zComment = mprintf("Deleted wiki page [%h]", m.zWikiTitle);
         1524  +      zComment = mprintf("Deleted wiki page [%h]", p->zWikiTitle);
  1099   1525       }
  1100   1526       db_multi_exec(
  1101   1527         "REPLACE INTO event(type,mtime,objid,user,comment,"
  1102   1528         "                  bgcolor,euser,ecomment)"
  1103   1529         "VALUES('w',%.17g,%d,%Q,%Q,"
  1104   1530         "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
  1105   1531         "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
  1106   1532         "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
  1107         -      m.rDate, rid, m.zUser, zComment, 
         1533  +      p->rDate, rid, p->zUser, zComment, 
  1108   1534         TAG_BGCOLOR, rid,
  1109   1535         TAG_BGCOLOR, rid,
  1110   1536         TAG_USER, rid,
  1111   1537         TAG_COMMENT, rid
  1112   1538       );
  1113   1539       free(zComment);
  1114   1540     }
  1115         -  if( m.type==CFTYPE_TICKET ){
         1541  +  if( p->type==CFTYPE_EVENT ){
         1542  +    char *zTag = mprintf("event-%s", p->zEventId);
         1543  +    int tagid = tag_findid(zTag, 1);
         1544  +    int prior, subsequent;
         1545  +    int nWiki;
         1546  +    char zLength[40];
         1547  +    while( fossil_isspace(p->zWiki[0]) ) p->zWiki++;
         1548  +    nWiki = strlen(p->zWiki);
         1549  +    sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki);
         1550  +    tag_insert(zTag, 1, zLength, rid, p->rDate, rid);
         1551  +    free(zTag);
         1552  +    prior = db_int(0,
         1553  +      "SELECT rid FROM tagxref"
         1554  +      " WHERE tagid=%d AND mtime<%.17g"
         1555  +      " ORDER BY mtime DESC",
         1556  +      tagid, p->rDate
         1557  +    );
         1558  +    if( prior ){
         1559  +      content_deltify(prior, rid, 0);
         1560  +      db_multi_exec(
         1561  +        "DELETE FROM event"
         1562  +        " WHERE type='e'"
         1563  +        "   AND tagid=%d"
         1564  +        "   AND objid IN (SELECT rid FROM tagxref WHERE tagid=%d)",
         1565  +        tagid, tagid
         1566  +      );
         1567  +    }
         1568  +    subsequent = db_int(0,
         1569  +      "SELECT rid FROM tagxref"
         1570  +      " WHERE tagid=%d AND mtime>%.17g"
         1571  +      " ORDER BY mtime",
         1572  +      tagid, p->rDate
         1573  +    );
         1574  +    if( subsequent ){
         1575  +      content_deltify(rid, subsequent, 0);
         1576  +    }else{
         1577  +      db_multi_exec(
         1578  +        "REPLACE INTO event(type,mtime,objid,tagid,user,comment,bgcolor)"
         1579  +        "VALUES('e',%.17g,%d,%d,%Q,%Q,"
         1580  +        "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
         1581  +        p->rEventDate, rid, tagid, p->zUser, p->zComment, 
         1582  +        TAG_BGCOLOR, rid
         1583  +      );
         1584  +    }
         1585  +  }
         1586  +  if( p->type==CFTYPE_TICKET ){
  1116   1587       char *zTag;
  1117   1588   
  1118   1589       assert( manifest_crosslink_busy==1 );
  1119         -    zTag = mprintf("tkt-%s", m.zTicketUuid);
  1120         -    tag_insert(zTag, 1, 0, rid, m.rDate, rid);
         1590  +    zTag = mprintf("tkt-%s", p->zTicketUuid);
         1591  +    tag_insert(zTag, 1, 0, rid, p->rDate, rid);
  1121   1592       free(zTag);
  1122   1593       db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
  1123         -                  m.zTicketUuid);
         1594  +                  p->zTicketUuid);
  1124   1595     }
  1125         -  if( m.type==CFTYPE_ATTACHMENT ){
         1596  +  if( p->type==CFTYPE_ATTACHMENT ){
  1126   1597       db_multi_exec(
  1127   1598          "INSERT INTO attachment(attachid, mtime, src, target,"
  1128   1599                                           "filename, comment, user)"
  1129   1600          "VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);",
  1130         -       rid, m.rDate, m.zAttachSrc, m.zAttachTarget, m.zAttachName,
  1131         -       (m.zComment ? m.zComment : ""), m.zUser
         1601  +       rid, p->rDate, p->zAttachSrc, p->zAttachTarget, p->zAttachName,
         1602  +       (p->zComment ? p->zComment : ""), p->zUser
  1132   1603       );
  1133   1604       db_multi_exec(
  1134   1605          "UPDATE attachment SET isLatest = (mtime=="
  1135   1606             "(SELECT max(mtime) FROM attachment"
  1136   1607             "  WHERE target=%Q AND filename=%Q))"
  1137   1608          " WHERE target=%Q AND filename=%Q",
  1138         -       m.zAttachTarget, m.zAttachName,
  1139         -       m.zAttachTarget, m.zAttachName
         1609  +       p->zAttachTarget, p->zAttachName,
         1610  +       p->zAttachTarget, p->zAttachName
  1140   1611       );
  1141         -    if( strlen(m.zAttachTarget)!=UUID_SIZE
  1142         -     || !validate16(m.zAttachTarget, UUID_SIZE) 
         1612  +    if( strlen(p->zAttachTarget)!=UUID_SIZE
         1613  +     || !validate16(p->zAttachTarget, UUID_SIZE) 
  1143   1614       ){
  1144   1615         char *zComment;
  1145         -      if( m.zAttachSrc && m.zAttachSrc[0] ){
         1616  +      if( p->zAttachSrc && p->zAttachSrc[0] ){
  1146   1617           zComment = mprintf("Add attachment \"%h\" to wiki page [%h]",
  1147         -             m.zAttachName, m.zAttachTarget);
         1618  +             p->zAttachName, p->zAttachTarget);
  1148   1619         }else{
  1149   1620           zComment = mprintf("Delete attachment \"%h\" from wiki page [%h]",
  1150         -             m.zAttachName, m.zAttachTarget);
         1621  +             p->zAttachName, p->zAttachTarget);
  1151   1622         }
  1152   1623         db_multi_exec(
  1153   1624           "REPLACE INTO event(type,mtime,objid,user,comment)"
  1154   1625           "VALUES('w',%.17g,%d,%Q,%Q)",
  1155         -        m.rDate, rid, m.zUser, zComment
         1626  +        p->rDate, rid, p->zUser, zComment
  1156   1627         );
  1157   1628         free(zComment);
  1158   1629       }else{
  1159   1630         char *zComment;
  1160         -      if( m.zAttachSrc && m.zAttachSrc[0] ){
         1631  +      if( p->zAttachSrc && p->zAttachSrc[0] ){
  1161   1632           zComment = mprintf("Add attachment \"%h\" to ticket [%.10s]",
  1162         -             m.zAttachName, m.zAttachTarget);
         1633  +             p->zAttachName, p->zAttachTarget);
  1163   1634         }else{
  1164   1635           zComment = mprintf("Delete attachment \"%h\" from ticket [%.10s]",
  1165         -             m.zAttachName, m.zAttachTarget);
         1636  +             p->zAttachName, p->zAttachTarget);
  1166   1637         }
  1167   1638         db_multi_exec(
  1168   1639           "REPLACE INTO event(type,mtime,objid,user,comment)"
  1169   1640           "VALUES('t',%.17g,%d,%Q,%Q)",
  1170         -        m.rDate, rid, m.zUser, zComment
         1641  +        p->rDate, rid, p->zUser, zComment
  1171   1642         );
  1172   1643         free(zComment);
  1173   1644       }
  1174   1645     }
  1175   1646     db_end_transaction(0);
  1176         -  manifest_clear(&m);
  1177         -  return 1;
  1178         -}
  1179         -
  1180         -/*
  1181         -** Given a checkin name, load and parse the manifest for that checkin.
  1182         -** Throw a fatal error if anything goes wrong.
  1183         -*/
  1184         -void manifest_from_name(
  1185         -  const char *zName,
  1186         -  Manifest *pM
  1187         -){
  1188         -  int rid;
  1189         -  Blob content;
  1190         -
  1191         -  rid = name_to_rid(zName);
  1192         -  if( !is_a_version(rid) ){
  1193         -    fossil_fatal("no such checkin: %s", zName);
         1647  +  if( p->type==CFTYPE_MANIFEST ){
         1648  +    manifest_cache_insert(p);
         1649  +  }else{
         1650  +    manifest_destroy(p);
  1194   1651     }
  1195         -  content_get(rid, &content);
  1196         -  if( !manifest_parse(pM, &content) ){
  1197         -    fossil_fatal("cannot parse manifest for checkin: %s", zName);
  1198         -  }
         1652  +  return 1;
  1199   1653   }

Changes to src/md5.c.

    39     39     int isInit;
    40     40     uint32 buf[4];
    41     41     uint32 bits[2];
    42     42     unsigned char in[64];
    43     43   };
    44     44   typedef struct Context MD5Context;
    45     45   
           46  +#if defined(__i386__) || defined(__x86_64__) || defined(_WIN32)
           47  +# define byteReverse(A,B)
           48  +#else
    46     49   /*
    47         - * Note: this code is harmless on little-endian machines.
           50  + * Convert an array of integers to little-endian.
           51  + * Note: this code is a no-op on little-endian machines.
    48     52    */
    49     53   static void byteReverse (unsigned char *buf, unsigned longs){
    50     54           uint32 t;
    51     55           do {
    52     56                   t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
    53     57                               ((unsigned)buf[1]<<8 | buf[0]);
    54     58                   *(uint32 *)buf = t;
    55     59                   buf += 4;
    56     60           } while (--longs);
    57     61   }
           62  +#endif
           63  +
    58     64   /* The four core functions - F1 is optimized somewhat */
    59     65   
    60     66   /* #define F1(x, y, z) (x & y | ~x & z) */
    61     67   #define F1(x, y, z) (z ^ (x & (y ^ z)))
    62     68   #define F2(x, y, z) F1(z, x, y)
    63     69   #define F3(x, y, z) (x ^ y ^ z)
    64     70   #define F4(x, y, z) (y ^ (x | ~z))
................................................................................
   312    318   
   313    319   /*
   314    320   ** Add the content of a blob to the incremental MD5 checksum.
   315    321   */
   316    322   void md5sum_step_blob(Blob *p){
   317    323     md5sum_step_text(blob_buffer(p), blob_size(p));
   318    324   }
          325  +
          326  +/*
          327  +** For trouble-shooting only:
          328  +**
          329  +** Report the current state of the incremental checksum.
          330  +*/
          331  +const char *md5sum_current_state(void){
          332  +  unsigned int cksum = 0;
          333  +  unsigned int *pFirst, *pLast;
          334  +  static char zResult[12];
          335  +
          336  +  pFirst = (unsigned int*)&incrCtx;
          337  +  pLast = (unsigned int*)((&incrCtx)+1);
          338  +  while( pFirst<pLast ){
          339  +    cksum += *pFirst;
          340  +    pFirst++;
          341  +  }
          342  +  sqlite3_snprintf(sizeof(zResult), zResult, "%08x", cksum);
          343  +  return zResult;
          344  +}
   319    345   
   320    346   /*
   321    347   ** Finish the incremental MD5 checksum.  Store the result in blob pOut
   322    348   ** if pOut!=0.  Also return a pointer to the result.  
   323    349   **
   324    350   ** This resets the incremental checksum preparing for the next round
   325    351   ** of computation.  The return pointer points to a static buffer that

Changes to src/merge3.c.

   149    149   int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
   150    150     int *aC1;              /* Changes from pPivot to pV1 */
   151    151     int *aC2;              /* Changes from pPivot to pV2 */
   152    152     int i1, i2;            /* Index into aC1[] and aC2[] */
   153    153     int nCpy, nDel, nIns;  /* Number of lines to copy, delete, or insert */
   154    154     int limit1, limit2;    /* Sizes of aC1[] and aC2[] */
   155    155     int nConflict = 0;     /* Number of merge conflicts seen so far */
   156         -  static const char zBegin[] = ">>>>>>> BEGIN MERGE CONFLICT\n";
          156  +  static const char zBegin[] = "<<<<<<< BEGIN MERGE CONFLICT\n";
   157    157     static const char zMid[]   = "============================\n";
   158         -  static const char zEnd[]   = "<<<<<<< END MERGE CONFLICT\n";
          158  +  static const char zEnd[]   = ">>>>>>> END MERGE CONFLICT\n";
   159    159   
   160    160     blob_zero(pOut);         /* Merge results stored in pOut */
   161    161   
   162    162     /* Compute the edits that occur from pPivot => pV1 (into aC1)
   163    163     ** and pPivot => pV2 (into aC2).  Each of the aC1 and aC2 arrays is
   164    164     ** an array of integer triples.  Within each triple, the first integer
   165    165     ** is the number of lines of text to copy directly from the pivot,
   166    166     ** the second integer is the number of lines of text to omit from the
   167    167     ** pivot, and the third integer is the number of lines of text that are
   168    168     ** inserted.  The edit array ends with a triple of 0,0,0.
   169    169     */
   170         -  aC1 = text_diff(pPivot, pV1, 0, 0);
   171         -  aC2 = text_diff(pPivot, pV2, 0, 0);
          170  +  aC1 = text_diff(pPivot, pV1, 0, 0, 1);
          171  +  aC2 = text_diff(pPivot, pV2, 0, 0, 1);
   172    172     if( aC1==0 || aC2==0 ){
   173    173       free(aC1);
   174    174       free(aC2);
   175    175       return -1;
   176    176     }
   177    177   
   178    178     blob_rewind(pV1);        /* Rewind inputs:  Needed to reconstruct output */

Changes to src/name.c.

   109    109     return rc;
   110    110   }
   111    111   
   112    112   /*
   113    113   ** Return TRUE if the string begins with an ISO8601 date: YYYY-MM-DD.
   114    114   */
   115    115   static int is_date(const char *z){
   116         -  if( !isdigit(z[0]) ) return 0;
   117         -  if( !isdigit(z[1]) ) return 0;
   118         -  if( !isdigit(z[2]) ) return 0;
   119         -  if( !isdigit(z[3]) ) return 0;
          116  +  if( !fossil_isdigit(z[0]) ) return 0;
          117  +  if( !fossil_isdigit(z[1]) ) return 0;
          118  +  if( !fossil_isdigit(z[2]) ) return 0;
          119  +  if( !fossil_isdigit(z[3]) ) return 0;
   120    120     if( z[4]!='-') return 0;
   121         -  if( !isdigit(z[5]) ) return 0;
   122         -  if( !isdigit(z[6]) ) return 0;
          121  +  if( !fossil_isdigit(z[5]) ) return 0;
          122  +  if( !fossil_isdigit(z[6]) ) return 0;
   123    123     if( z[7]!='-') return 0;
   124         -  if( !isdigit(z[8]) ) return 0;
   125         -  if( !isdigit(z[9]) ) return 0;
          124  +  if( !fossil_isdigit(z[8]) ) return 0;
          125  +  if( !fossil_isdigit(z[9]) ) return 0;
   126    126     return 1;
   127    127   }
   128    128   
   129    129   /*
   130    130   ** Convert a symbolic tag name into the UUID of a check-in that contains
   131    131   ** that tag.  If the tag appears on multiple check-ins, return the UUID
   132    132   ** of the most recent check-in with the tag.
................................................................................
   278    278     int rid;
   279    279     Blob name;
   280    280   
   281    281     if( zName==0 || zName[0]==0 ) return 0;
   282    282     blob_init(&name, zName, -1);
   283    283     if( name_to_uuid(&name, -1) ){
   284    284       blob_reset(&name);
   285         -    for(i=0; zName[i] && isdigit(zName[i]); i++){}
          285  +    for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){}
   286    286       if( zName[i]==0 ){
   287    287         rid = atoi(zName);
   288    288         if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){
   289    289           return rid;
   290    290         }
   291    291       }
   292    292       fossil_error(1, "no such artifact: %s", zName);
................................................................................
   346    346     Blob name;
   347    347   
   348    348     if( zName==0 || zName[0]==0 ) return 0;
   349    349     blob_init(&name, zName, -1);
   350    350     rc = name_to_uuid(&name, -1);
   351    351     if( rc==1 ){
   352    352       blob_reset(&name);
   353         -    for(i=0; zName[i] && isdigit(zName[i]); i++){}
          353  +    for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){}
   354    354       if( zName[i]==0 ){
   355    355         rid = atoi(zName);
   356    356         if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){
   357    357           return rid;
   358    358         }
   359    359       }
   360    360       return 0;

Added src/popen.c.

            1  +/*
            2  +** Copyright (c) 2010 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the Simplified BSD License (also
            6  +** known as the "2-Clause License" or "FreeBSD License".)
            7  +
            8  +** This program is distributed in the hope that it will be useful,
            9  +** but without any warranty; without even the implied warranty of
           10  +** merchantability or fitness for a particular purpose.
           11  +**
           12  +** Author contact information:
           13  +**   drh@hwaci.com
           14  +**   http://www.hwaci.com/drh/
           15  +**
           16  +*******************************************************************************
           17  +**
           18  +** This file contains an implementation of a bi-directional popen().
           19  +*/
           20  +#include "config.h"
           21  +#include "popen.h"
           22  +
           23  +#ifdef _WIN32
           24  +#include <windows.h>
           25  +#include <fcntl.h>
           26  +/*
           27  +** Print a fatal error and quit.
           28  +*/
           29  +static void win32_fatal_error(const char *zMsg){
           30  +  fossil_fatal("%s");
           31  +}
           32  +#endif
           33  +
           34  +
           35  +
           36  +#ifdef _WIN32
           37  +/*
           38  +** On windows, create a child process and specify the stdin, stdout,
           39  +** and stderr channels for that process to use.
           40  +**
           41  +** Return the number of errors.
           42  +*/
           43  +static int win32_create_child_process(
           44  +  char *zCmd,          /* The command that the child process will run */
           45  +  HANDLE hIn,          /* Standard input */
           46  +  HANDLE hOut,         /* Standard output */
           47  +  HANDLE hErr,         /* Standard error */
           48  +  DWORD *pChildPid     /* OUT: Child process handle */
           49  +){
           50  +  STARTUPINFO si;
           51  +  PROCESS_INFORMATION pi;
           52  +  BOOL rc;
           53  +
           54  +  memset(&si, 0, sizeof(si));
           55  +  si.cb = sizeof(si);
           56  +  si.dwFlags = STARTF_USESTDHANDLES;
           57  +  SetHandleInformation(hIn, HANDLE_FLAG_INHERIT, TRUE);
           58  +  si.hStdInput  = hIn;
           59  +  SetHandleInformation(hOut, HANDLE_FLAG_INHERIT, TRUE);
           60  +  si.hStdOutput = hOut;
           61  +  SetHandleInformation(hErr, HANDLE_FLAG_INHERIT, TRUE);
           62  +  si.hStdError  = hErr;
           63  +  rc = CreateProcess(
           64  +     NULL,  /* Application Name */
           65  +     zCmd,  /* Command-line */
           66  +     NULL,  /* Process attributes */
           67  +     NULL,  /* Thread attributes */
           68  +     TRUE,  /* Inherit Handles */
           69  +     0,     /* Create flags  */
           70  +     NULL,  /* Environment */
           71  +     NULL,  /* Current directory */
           72  +     &si,   /* Startup Info */
           73  +     &pi    /* Process Info */
           74  +  );
           75  +  if( rc ){
           76  +    CloseHandle( pi.hProcess );
           77  +    CloseHandle( pi.hThread );
           78  +    *pChildPid = pi.dwProcessId;
           79  +  }else{
           80  +    win32_fatal_error("cannot create child process");
           81  +  }
           82  +  return rc!=0;
           83  +}
           84  +#endif
           85  +
           86  +/*
           87  +** Create a child process running shell command "zCmd".  *ppOut is
           88  +** a FILE that becomes the standard input of the child process.  
           89  +** (The caller writes to *ppOut in order to send text to the child.)
           90  +** *ppIn is stdout from the child process.  (The caller
           91  +** reads from *ppIn in order to receive input from the child.)
           92  +** Note that *ppIn is an unbuffered file descriptor, not a FILE.
           93  +** The process ID of the child is written into *pChildPid.
           94  +**
           95  +** Return the number of errors.
           96  +*/
           97  +int popen2(const char *zCmd, int *pfdIn, FILE **ppOut, int *pChildPid){
           98  +#ifdef _WIN32
           99  +  HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
          100  +  SECURITY_ATTRIBUTES saAttr;    
          101  +  DWORD childPid = 0;
          102  +  int fd;
          103  +
          104  +  saAttr.nLength = sizeof(saAttr);
          105  +  saAttr.bInheritHandle = TRUE;
          106  +  saAttr.lpSecurityDescriptor = NULL; 
          107  +  hStderr = GetStdHandle(STD_ERROR_HANDLE);
          108  +  if( !CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 4096) ){
          109  +    win32_fatal_error("cannot create pipe for stdout");
          110  +  }
          111  +  SetHandleInformation( hStdoutRd, HANDLE_FLAG_INHERIT, FALSE);
          112  +
          113  +  if( !CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 4096) ){
          114  +    win32_fatal_error("cannot create pipe for stdin");
          115  +  }
          116  +  SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
          117  +  
          118  +  win32_create_child_process((char*)zCmd, 
          119  +                             hStdinRd, hStdoutWr, hStderr,&childPid);
          120  +  *pChildPid = childPid;
          121  +  *pfdIn = _open_osfhandle((long)hStdoutRd, 0);
          122  +  fd = _open_osfhandle((long)hStdinWr, 0);
          123  +  *ppOut = _fdopen(fd, "w");
          124  +  CloseHandle(hStdinRd); 
          125  +  CloseHandle(hStdoutWr);
          126  +  return 0;
          127  +#else
          128  +  int pin[2], pout[2];
          129  +  *pfdIn = 0;
          130  +  *ppOut = 0;
          131  +  *pChildPid = 0;
          132  +
          133  +  if( pipe(pin)<0 ){
          134  +    return 1;
          135  +  }
          136  +  if( pipe(pout)<0 ){
          137  +    close(pin[0]);
          138  +    close(pin[1]);
          139  +    return 1;
          140  +  }
          141  +  *pChildPid = fork();
          142  +  if( *pChildPid<0 ){
          143  +    close(pin[0]);
          144  +    close(pin[1]);
          145  +    close(pout[0]);
          146  +    close(pout[1]);
          147  +    *pChildPid = 0;
          148  +    return 1;
          149  +  }
          150  +  if( *pChildPid==0 ){
          151  +    /* This is the child process */
          152  +    close(0);
          153  +    dup(pout[0]);
          154  +    close(pout[0]);
          155  +    close(pout[1]);
          156  +    close(1);
          157  +    dup(pin[1]);
          158  +    close(pin[0]);
          159  +    close(pin[1]);
          160  +    execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
          161  +    return 1;
          162  +  }else{
          163  +    /* This is the parent process */
          164  +    close(pin[1]);
          165  +    *pfdIn = pin[0];
          166  +    close(pout[0]);
          167  +    *ppOut = fdopen(pout[1], "w");
          168  +    return 0;
          169  +  }
          170  +#endif
          171  +}
          172  +
          173  +/*
          174  +** Close the connection to a child process previously created using
          175  +** popen2().  Kill off the child process, then close the pipes.
          176  +*/
          177  +void pclose2(int fdIn, FILE *pOut, int childPid){
          178  +#ifdef _WIN32
          179  +  /* Not implemented, yet */
          180  +  close(fdIn);
          181  +  fclose(pOut);
          182  +#else
          183  +  close(fdIn);
          184  +  fclose(pOut);
          185  +  kill(childPid, SIGINT);
          186  +#endif
          187  +}

Changes to src/pqueue.c.

    60     60     pqueue_init(p);
    61     61   }
    62     62   
    63     63   /*
    64     64   ** Change the size of the queue so that it contains N slots
    65     65   */
    66     66   static void pqueue_resize(PQueue *p, int N){
    67         -  p->a = realloc(p->a, sizeof(p->a[0])*N);
           67  +  p->a = fossil_realloc(p->a, sizeof(p->a[0])*N);
    68     68     p->sz = N;
    69     69   }
    70     70   
    71     71   /*
    72     72   ** Insert element e into the queue.
    73     73   */
    74     74   void pqueue_insert(PQueue *p, int e, double v){

Changes to src/printf.c.

    42     42                             NULL pointers replaced by SQL NULL.  %Q */
    43     43   #define etPOINTER    15 /* The %p conversion */
    44     44   #define etHTMLIZE    16 /* Make text safe for HTML */
    45     45   #define etHTTPIZE    17 /* Make text safe for HTTP.  "/" encoded as %2f */
    46     46   #define etURLIZE     18 /* Make text safe for HTTP.  "/" not encoded */
    47     47   #define etFOSSILIZE  19 /* The fossil header encoding format. */
    48     48   #define etPATH       20 /* Path type */
    49         -#define etWIKISTR    21 /* Wiki text rendered from a char* */
    50         -#define etWIKIBLOB   22 /* Wiki text rendered from a Blob* */
    51         -#define etSTRINGID   23 /* String with length limit for a UUID prefix */
           49  +#define etWIKISTR    21 /* Wiki text rendered from a char*: %w */
           50  +#define etWIKIBLOB   22 /* Wiki text rendered from a Blob*: %W */
           51  +#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
    52     52   
    53     53   
    54     54   /*
    55     55   ** An "etByte" is an 8-bit unsigned value.
    56     56   */
    57     57   typedef unsigned char etByte;
    58     58   
................................................................................
   558    558           break;
   559    559         case etPATH: {
   560    560           int i;
   561    561           int limit = flag_alternateform ? va_arg(ap,int) : -1;
   562    562           char *e = va_arg(ap,char*);
   563    563           if( e==0 ){e="";}
   564    564           length = StrNLen32(e, limit);
   565         -        zExtra = bufpt = malloc(length+1);
          565  +        zExtra = bufpt = fossil_malloc(length+1);
   566    566           for( i=0; i<length; i++ ){
   567    567             if( e[i]=='\\' ){
   568    568               bufpt[i]='/';
   569    569             }else{
   570    570               bufpt[i]=e[i];
   571    571             }
   572    572           }
................................................................................
   603    603           Blob *pBlob = va_arg(ap, Blob*);
   604    604           char *zOrig = blob_buffer(pBlob);
   605    605           int i, j, n, cnt;
   606    606           n = blob_size(pBlob);
   607    607           if( limit>=0 && limit<n ) n = limit;
   608    608           for(cnt=i=0; i<n; i++){ if( zOrig[i]=='\'' ) cnt++; }
   609    609           if( n+cnt+2 > etBUFSIZE ){
   610         -          bufpt = zExtra = malloc( n + cnt + 2 );
          610  +          bufpt = zExtra = fossil_malloc( n + cnt + 2 );
   611    611           }else{
   612    612             bufpt = buf;
   613    613           }
   614    614           bufpt[0] = '\'';
   615    615           for(i=0, j=1; i<n; i++, j++){
   616    616             if( zOrig[i]=='\'' ){ bufpt[j++] = '\''; }
   617    617             bufpt[j] = zOrig[i];
................................................................................
   632    632           if( limit<0 ) limit = strlen(escarg);
   633    633           for(i=n=0; i<limit; i++){
   634    634             if( escarg[i]=='\'' )  n++;
   635    635           }
   636    636           needQuote = !isnull && xtype==etSQLESCAPE2;
   637    637           n += i + 1 + needQuote*2;
   638    638           if( n>etBUFSIZE ){
   639         -          bufpt = zExtra = malloc( n );
   640         -          if( bufpt==0 ) return -1;
          639  +          bufpt = zExtra = fossil_malloc( n );
   641    640           }else{
   642    641             bufpt = buf;
   643    642           }
   644    643           j = 0;
   645    644           if( needQuote ) bufpt[j++] = '\'';
   646    645           for(i=0; i<limit; i++){
   647    646             bufpt[j++] = ch = escarg[i];

Changes to src/rebuild.c.

    70     70   @ CREATE TABLE IF NOT EXISTS concealed(
    71     71   @   hash TEXT PRIMARY KEY,
    72     72   @   content TEXT
    73     73   @ );
    74     74   ;
    75     75   
    76     76   /*
    77         -** Variables used for progress information
           77  +** Variables used to store state information about an on-going "rebuild"
           78  +** or "deconstruct".
    78     79   */
    79     80   static int totalSize;       /* Total number of artifacts to process */
    80     81   static int processCnt;      /* Number processed so far */
    81     82   static int ttyOutput;       /* Do progress output */
    82     83   static Bag bagDone;         /* Bag of records rebuilt */
           84  +
           85  +static char *zFNameFormat;  /* Format string for filenames on deconstruct */
           86  +static int prefixLength;    /* Length of directory prefix for deconstruct */
           87  +
           88  +
           89  +/*
           90  +** Draw the percent-complete message.
           91  +** The input is actually the permill complete.
           92  +*/
           93  +static void percent_complete(int permill){
           94  +  static int lastOutput = -1;
           95  +  if( permill>lastOutput ){
           96  +    printf("  %d.%d%% complete...\r", permill/10, permill%10);
           97  +    fflush(stdout);
           98  +    lastOutput = permill;
           99  +  }
          100  +}
          101  +
    83    102   
    84    103   /*
    85    104   ** Called after each artifact is processed
    86    105   */
    87    106   static void rebuild_step_done(rid){
    88    107     /* assert( bag_find(&bagDone, rid)==0 ); */
    89    108     bag_insert(&bagDone, rid);
    90    109     if( ttyOutput ){
    91    110       processCnt++;
    92         -    if (!g.fQuiet) {
    93         -      printf("%d (%d%%)...\r", processCnt, (processCnt*100/totalSize));
    94         -      fflush(stdout);
          111  +    if (!g.fQuiet && totalSize>0) {
          112  +      percent_complete((processCnt*1000)/totalSize);
    95    113       }
    96    114     }
    97    115   }
    98    116   
    99    117   /*
   100    118   ** Rebuild cross-referencing information for the artifact
   101    119   ** rid with content pBase and all of its descendants.  This
   102    120   ** routine clears the content buffer before returning.
          121  +**
          122  +** If the zFNameFormat variable is set, then this routine is
          123  +** called to run "fossil deconstruct" instead of the usual
          124  +** "fossil rebuild".  In that case, instead of rebuilding the
          125  +** cross-referencing information, write the file content out
          126  +** to the approriate directory.
          127  +**
          128  +** In both cases, this routine automatically recurses to process
          129  +** other artifacts that are deltas off of the current artifact.
          130  +** This is the most efficient way to extract all of the original
          131  +** artifact content from the Fossil repository.
   103    132   */
   104    133   static void rebuild_step(int rid, int size, Blob *pBase){
   105    134     static Stmt q1;
   106    135     Bag children;
   107    136     Blob copy;
   108    137     Blob *pUse;
   109    138     int nChild, i, cid;
   110    139   
   111         -  /* Fix up the "blob.size" field if needed. */
   112         -  if( size!=blob_size(pBase) ){
   113         -    db_multi_exec(
   114         -       "UPDATE blob SET size=%d WHERE rid=%d", blob_size(pBase), rid
   115         -    );
   116         -  }
   117         -
   118         -  /* Find all children of artifact rid */
   119         -  db_static_prepare(&q1, "SELECT rid FROM delta WHERE srcid=:rid");
   120         -  db_bind_int(&q1, ":rid", rid);
   121         -  bag_init(&children);
   122         -  while( db_step(&q1)==SQLITE_ROW ){
   123         -    int cid = db_column_int(&q1, 0);
   124         -    if( !bag_find(&bagDone, cid) ){
   125         -      bag_insert(&children, cid);
   126         -    }
   127         -  }
   128         -  nChild = bag_count(&children);
   129         -  db_reset(&q1);
   130         -
   131         -  /* Crosslink the artifact */
   132         -  if( nChild==0 ){
   133         -    pUse = pBase;
   134         -  }else{
   135         -    blob_copy(&copy, pBase);
   136         -    pUse = &copy;
   137         -  }
   138         -  manifest_crosslink(rid, pUse);
   139         -  blob_reset(pUse);
   140         -
   141         -  /* Call all children recursively */
   142         -  for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
   143         -    Stmt q2;
   144         -    int sz;
   145         -    if( nChild==i ){
          140  +  while( rid>0 ){
          141  +
          142  +    /* Fix up the "blob.size" field if needed. */
          143  +    if( size!=blob_size(pBase) ){
          144  +      db_multi_exec(
          145  +         "UPDATE blob SET size=%d WHERE rid=%d", blob_size(pBase), rid
          146  +      );
          147  +    }
          148  +  
          149  +    /* Find all children of artifact rid */
          150  +    db_static_prepare(&q1, "SELECT rid FROM delta WHERE srcid=:rid");
          151  +    db_bind_int(&q1, ":rid", rid);
          152  +    bag_init(&children);
          153  +    while( db_step(&q1)==SQLITE_ROW ){
          154  +      int cid = db_column_int(&q1, 0);
          155  +      if( !bag_find(&bagDone, cid) ){
          156  +        bag_insert(&children, cid);
          157  +      }
          158  +    }
          159  +    nChild = bag_count(&children);
          160  +    db_reset(&q1);
          161  +  
          162  +    /* Crosslink the artifact */
          163  +    if( nChild==0 ){
   146    164         pUse = pBase;
   147    165       }else{
   148    166         blob_copy(&copy, pBase);
   149    167         pUse = &copy;
   150    168       }
   151         -    db_prepare(&q2, "SELECT content, size FROM blob WHERE rid=%d", cid);
   152         -    if( db_step(&q2)==SQLITE_ROW && (sz = db_column_int(&q2,1))>=0 ){
   153         -      Blob delta;
   154         -      db_ephemeral_blob(&q2, 0, &delta);
   155         -      blob_uncompress(&delta, &delta);
   156         -      blob_delta_apply(pUse, &delta, pUse);
   157         -      blob_reset(&delta);
   158         -      db_finalize(&q2);
   159         -      rebuild_step(cid, sz, pUse);
          169  +    if( zFNameFormat==0 ){
          170  +      /* We are doing "fossil rebuild" */
          171  +      manifest_crosslink(rid, pUse);
   160    172       }else{
   161         -      db_finalize(&q2);
   162         -      blob_reset(pUse);
          173  +      /* We are doing "fossil deconstruct" */
          174  +      char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
          175  +      char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
          176  +      blob_write_to_file(pUse,zFile);
          177  +      free(zFile);
          178  +      free(zUuid);
          179  +    }
          180  +    blob_reset(pUse);
          181  +    rebuild_step_done(rid);
          182  +  
          183  +    /* Call all children recursively */
          184  +    rid = 0;
          185  +    for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
          186  +      static Stmt q2;
          187  +      int sz;
          188  +      db_static_prepare(&q2, "SELECT content, size FROM blob WHERE rid=:rid");
          189  +      db_bind_int(&q2, ":rid", cid);
          190  +      if( db_step(&q2)==SQLITE_ROW && (sz = db_column_int(&q2,1))>=0 ){
          191  +        Blob delta, next;
          192  +        db_ephemeral_blob(&q2, 0, &delta);
          193  +        blob_uncompress(&delta, &delta);
          194  +        blob_delta_apply(pBase, &delta, &next);
          195  +        blob_reset(&delta);
          196  +        db_reset(&q2);
          197  +        if( i<nChild ){
          198  +          rebuild_step(cid, sz, &next);
          199  +        }else{
          200  +          /* Tail recursion */
          201  +          rid = cid;
          202  +          size = sz;
          203  +          blob_reset(pBase);
          204  +          *pBase = next;
          205  +        }
          206  +      }else{
          207  +        db_reset(&q2);
          208  +        blob_reset(pBase);
          209  +      }
   163    210       }
          211  +    bag_clear(&children);
   164    212     }
   165         -  bag_clear(&children);
   166         -  rebuild_step_done(rid);
   167    213   }
   168    214   
   169    215   /*
   170    216   ** Check to see if the "sym-trunk" tag exists.  If not, create it
   171    217   ** and attach it to the very first check-in.
   172    218   */
   173    219   static void rebuild_tag_trunk(void){
................................................................................
   179    225     rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS("
   180    226                     "  SELECT 1 FROM plink WHERE cid=x.pid)");
   181    227     if( rid==0 ) return;
   182    228   
   183    229     /* Add the trunk tag to the root of the whole tree */
   184    230     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
   185    231     if( zUuid==0 ) return;
   186         -  tag_add_artifact("sym-", "trunk", zUuid, 0, 2);
   187         -  tag_add_artifact("", "branch", zUuid, "trunk", 2);
          232  +  tag_add_artifact("sym-", "trunk", zUuid, 0, 2, 0, 0);
          233  +  tag_add_artifact("", "branch", zUuid, "trunk", 2, 0, 0);
   188    234   }
   189    235   
   190    236   /*
   191    237   ** Core function to rebuild the infomration in the derived tables of a
   192    238   ** fossil repository from the blobs. This function is shared between
   193    239   ** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
   194    240   ** ('reconstruct'), both of which have to regenerate this information
................................................................................
   199    245   ** ability of fossil to accept records in any order and still
   200    246   ** construct a sane repository.
   201    247   */
   202    248   int rebuild_db(int randomize, int doOut){
   203    249     Stmt s;
   204    250     int errCnt = 0;
   205    251     char *zTable;
          252  +  int incrSize;
   206    253   
   207    254     bag_init(&bagDone);
   208    255     ttyOutput = doOut;
   209    256     processCnt = 0;
   210    257     if (!g.fQuiet) {
   211         -    printf("0 (0%%)...\r");
   212         -    fflush(stdout);
          258  +    percent_complete(0);
   213    259     }
   214    260     db_multi_exec(zSchemaUpdates);
   215    261     for(;;){
   216    262       zTable = db_text(0,
   217    263          "SELECT name FROM sqlite_master /*scan*/"
   218    264          " WHERE type='table'"
   219    265          " AND name NOT IN ('blob','delta','rcvfrom','user',"
................................................................................
   237    283        "DELETE FROM unclustered"
   238    284        " WHERE rid IN (SELECT rid FROM shun JOIN blob USING(uuid))"
   239    285     );
   240    286     db_multi_exec(
   241    287       "DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')"
   242    288     );
   243    289     totalSize = db_int(0, "SELECT count(*) FROM blob");
          290  +  incrSize = totalSize/100;
          291  +  totalSize += incrSize*2;
   244    292     db_prepare(&s,
   245    293        "SELECT rid, size FROM blob /*scan*/"
   246    294        " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
   247    295        "   AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
   248    296     );
   249    297     manifest_crosslink_begin();
   250    298     while( db_step(&s)==SQLITE_ROW ){
................................................................................
   274    322         db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
   275    323         rebuild_step_done(rid);
   276    324       }
   277    325     }
   278    326     db_finalize(&s);
   279    327     manifest_crosslink_end();
   280    328     rebuild_tag_trunk();
          329  +  if( !g.fQuiet && totalSize>0 ){
          330  +    processCnt += incrSize;
          331  +    percent_complete((processCnt*1000)/totalSize);
          332  +  }
          333  +  create_cluster();
          334  +  if( !g.fQuiet && totalSize>0 ){
          335  +    processCnt += incrSize;
          336  +    percent_complete((processCnt*1000)/totalSize);
          337  +  }
   281    338     if(!g.fQuiet && ttyOutput ){
   282    339       printf("\n");
   283    340     }
   284    341     return errCnt;
   285    342   }
   286    343   
   287    344   /*
................................................................................
   293    350   ** records.  Run this command after updating the fossil
   294    351   ** executable in a way that changes the database schema.
   295    352   */
   296    353   void rebuild_database(void){
   297    354     int forceFlag;
   298    355     int randomizeFlag;
   299    356     int errCnt;
          357  +  int omitVerify;
   300    358   
          359  +  omitVerify = find_option("noverify",0,0)!=0;
   301    360     forceFlag = find_option("force","f",0)!=0;
   302    361     randomizeFlag = find_option("randomize", 0, 0)!=0;
   303    362     if( g.argc==3 ){
   304    363       db_open_repository(g.argv[2]);
   305    364     }else{
   306    365       db_find_and_open_repository(1);
   307    366       if( g.argc!=2 ){
................................................................................
   314    373     ttyOutput = 1;
   315    374     errCnt = rebuild_db(randomizeFlag, 1);
   316    375     if( errCnt && !forceFlag ){
   317    376       printf("%d errors. Rolling back changes. Use --force to force a commit.\n",
   318    377               errCnt);
   319    378       db_end_transaction(1);
   320    379     }else{
          380  +    if( omitVerify ) verify_cancel();
   321    381       db_end_transaction(0);
   322    382     }
   323    383   }
   324    384   
   325    385   /*
   326    386   ** COMMAND:  test-detach
   327    387   **
................................................................................
   338    398       "UPDATE config SET value=lower(hex(randomblob(20)))"
   339    399       " WHERE name='project-code';"
   340    400       "UPDATE config SET value='detached-' || value"
   341    401       " WHERE name='project-name' AND value NOT GLOB 'detached-*';"
   342    402     );
   343    403     db_end_transaction(0);
   344    404   }
          405  +
          406  +/*
          407  +** COMMAND:  test-create-clusters
          408  +**
          409  +** Create clusters for all unclustered artifacts if the number of unclustered
          410  +** artifacts exceeds the current clustering threshold.
          411  +*/
          412  +void test_createcluster_cmd(void){
          413  +  if( g.argc==3 ){
          414  +    db_open_repository(g.argv[2]);
          415  +  }else{
          416  +    db_find_and_open_repository(1);
          417  +    if( g.argc!=2 ){
          418  +      usage("?REPOSITORY-FILENAME?");
          419  +    }
          420  +    db_close();
          421  +    db_open_repository(g.zRepositoryName);
          422  +  }
          423  +  db_begin_transaction();
          424  +  create_cluster();
          425  +  db_end_transaction(0);  
          426  +}
   345    427   
   346    428   /*
   347    429   ** COMMAND: scrub
   348    430   ** %fossil scrub [--verily] [--force] [REPOSITORY]
   349    431   **
   350    432   ** The command removes sensitive information (such as passwords) from a
   351    433   ** repository so that the respository can be sent to an untrusted reader.
................................................................................
   399    481       db_end_transaction(0);
   400    482       db_multi_exec("VACUUM;");
   401    483     }else{
   402    484       rebuild_db(0, 1);
   403    485       db_end_transaction(0);
   404    486     }
   405    487   }
          488  +
          489  +/*
          490  +** Recursively read all files from the directory zPath and install
          491  +** every file read as a new artifact in the repository.
          492  +*/
          493  +void recon_read_dir(char *zPath){
          494  +  DIR *d;
          495  +  struct dirent *pEntry;
          496  +  Blob aContent; /* content of the just read artifact */
          497  +  static int nFileRead = 0;
          498  +
          499  +  d = opendir(zPath);
          500  +  if( d ){
          501  +    while( (pEntry=readdir(d))!=0 ){
          502  +      Blob path;
          503  +      char *zSubpath;
          504  +
          505  +      if( pEntry->d_name[0]=='.' ){
          506  +        continue;
          507  +      }
          508  +      zSubpath = mprintf("%s/%s",zPath,pEntry->d_name);
          509  +      if( file_isdir(zSubpath)==1 ){
          510  +        recon_read_dir(zSubpath);
          511  +      }
          512  +      blob_init(&path, 0, 0);
          513  +      blob_appendf(&path, "%s", zSubpath);
          514  +      if( blob_read_from_file(&aContent, blob_str(&path))==-1 ){
          515  +        fossil_panic("some unknown error occurred while reading \"%s\"", 
          516  +                     blob_str(&path));
          517  +      }
          518  +      content_put(&aContent, 0, 0);
          519  +      blob_reset(&path);
          520  +      blob_reset(&aContent);
          521  +      free(zSubpath);
          522  +      printf("\r%d", ++nFileRead);
          523  +      fflush(stdout);
          524  +    }
          525  +  }else {
          526  +    fossil_panic("encountered error %d while trying to open \"%s\".",
          527  +                  errno, g.argv[3]);
          528  +  }
          529  +}
   406    530   
   407    531   /*
   408    532   ** COMMAND: reconstruct
   409    533   **
   410    534   ** Usage: %fossil reconstruct FILENAME DIRECTORY
   411    535   **
   412    536   ** This command studies the artifacts (files) in DIRECTORY and
   413    537   ** reconstructs the fossil record from them. It places the new
   414         -** fossil repository in FILENAME
          538  +** fossil repository in FILENAME. Subdirectories are read, files
          539  +** with leading '.' in the filename are ignored.
   415    540   **
   416    541   */
   417    542   void reconstruct_cmd(void) {
   418    543     char *zPassword;
   419         -  DIR *d;
   420         -  struct dirent *pEntry;
   421         -  Blob aContent; /* content of the just read artifact */
   422    544     if( g.argc!=4 ){
   423    545       usage("FILENAME DIRECTORY");
   424    546     }
   425    547     if( file_isdir(g.argv[3])!=1 ){
   426    548       printf("\"%s\" is not a directory\n\n", g.argv[3]);
   427    549       usage("FILENAME DIRECTORY");
   428    550     }
   429    551     db_create_repository(g.argv[2]);
   430    552     db_open_repository(g.argv[2]);
   431    553     db_open_config(0);
   432    554     db_begin_transaction();
   433    555     db_initial_setup(0, 0, 1);
   434    556   
   435         -  d = opendir(g.argv[3]);
   436         -  if( d ){
   437         -    while( (pEntry=readdir(d))!=0 ){
   438         -      Blob path;
   439         -      blob_init(&path, 0, 0);
   440         -      if( pEntry->d_name[0]=='.' ){
   441         -        continue;
   442         -      }
   443         -      if( file_isdir(pEntry->d_name)==1 ){
   444         -        continue;
   445         -      }
   446         -      blob_appendf(&path, "%s/%s", g.argv[3], pEntry->d_name);
   447         -      if( blob_read_from_file(&aContent, blob_str(&path))==-1 ){
   448         -        fossil_panic("Some unknown error occurred while reading \"%s\"", blob_str(&path));
   449         -      }
   450         -      content_put(&aContent, 0, 0);
   451         -    }
   452         -  }
   453         -  else {
   454         -    fossil_panic("Encountered error %d while trying to open \"%s\".", errno, g.argv[3]);
   455         -  }
          557  +  printf("Reading files from directory \"%s\"...\n", g.argv[3]);
          558  +  recon_read_dir(g.argv[3]);
          559  +  printf("\nBuilding the Fossil repository...\n");
   456    560   
   457    561     rebuild_db(0, 1);
   458    562   
          563  +  /* Skip the verify_before_commit() step on a reconstruct.  Most artifacts
          564  +  ** will have been changed and verification therefore takes a really, really
          565  +  ** long time.
          566  +  */
          567  +  verify_cancel();
          568  +  
   459    569     db_end_transaction(0);
   460    570     printf("project-id: %s\n", db_get("project-code", 0));
   461    571     printf("server-id: %s\n", db_get("server-code", 0));
   462    572     zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
   463    573     printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
   464    574   }
          575  +
          576  +/*
          577  +** COMMAND: deconstruct
          578  +**
          579  +** Usage %fossil deconstruct ?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION
          580  +**
          581  +** This command exports all artifacts of o given repository and
          582  +** writes all artifacts to the file system. The DESTINATION directory
          583  +** will be populated with subdirectories AA and files AA/BBBBBBBBB.., where
          584  +** AABBBBBBBBB.. is the 40 character artifact ID, AA the first 2 characters.
          585  +** If -L|--prefixlength is given, the length (default 2) of the directory
          586  +** prefix can be set to 0,1,..,9 characters.
          587  +*/
          588  +void deconstruct_cmd(void){
          589  +  const char *zDestDir;
          590  +  const char *zPrefixOpt;
          591  +  Stmt        s;
          592  +
          593  +  /* check number of arguments */
          594  +  if( (g.argc != 3) && (g.argc != 5)  && (g.argc != 7)){
          595  +    usage ("?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION");
          596  +  }
          597  +  /* get and check argument destination directory */
          598  +  zDestDir = g.argv[g.argc-1];
          599  +  if( !*zDestDir  || !file_isdir(zDestDir)) {
          600  +    fossil_panic("DESTINATION(%s) is not a directory!",zDestDir);
          601  +  }
          602  +  /* get and check prefix length argument and build format string */
          603  +  zPrefixOpt=find_option("prefixlength","L",1);
          604  +  if( !zPrefixOpt ){
          605  +    prefixLength = 2;
          606  +  }else{
          607  +    if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
          608  +      prefixLength = (int)(*zPrefixOpt-'0');
          609  +    }else{
          610  +      fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt);
          611  +    }
          612  +  }
          613  +#ifndef _WIN32
          614  +  if( access(zDestDir, W_OK) ){
          615  +    fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
          616  +  }
          617  +#else
          618  +  /* write access on windows is not checked, errors will be
          619  +  ** dected on blob_write_to_file
          620  +  */
          621  +#endif
          622  +  if( prefixLength ){
          623  +    zFNameFormat = mprintf("%s/%%.%ds/%%s",zDestDir,prefixLength);
          624  +  }else{
          625  +    zFNameFormat = mprintf("%s/%%s",zDestDir);
          626  +  }
          627  +  /* open repository and open query for all artifacts */
          628  +  db_find_and_open_repository(1);
          629  +  bag_init(&bagDone);
          630  +  ttyOutput = 1;
          631  +  processCnt = 0;
          632  +  if (!g.fQuiet) {
          633  +    printf("0 (0%%)...\r");
          634  +    fflush(stdout);
          635  +  }
          636  +  totalSize = db_int(0, "SELECT count(*) FROM blob");
          637  +  db_prepare(&s,
          638  +     "SELECT rid, size FROM blob /*scan*/"
          639  +     " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
          640  +     "   AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
          641  +  );
          642  +  while( db_step(&s)==SQLITE_ROW ){
          643  +    int rid = db_column_int(&s, 0);
          644  +    int size = db_column_int(&s, 1);
          645  +    if( size>=0 ){
          646  +      Blob content;
          647  +      content_get(rid, &content);
          648  +      rebuild_step(rid, size, &content);
          649  +    }
          650  +  }
          651  +  db_finalize(&s);
          652  +  db_prepare(&s,
          653  +     "SELECT rid, size FROM blob"
          654  +     " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
          655  +  );
          656  +  while( db_step(&s)==SQLITE_ROW ){
          657  +    int rid = db_column_int(&s, 0);
          658  +    int size = db_column_int(&s, 1);
          659  +    if( size>=0 ){
          660  +      if( !bag_find(&bagDone, rid) ){
          661  +        Blob content;
          662  +        content_get(rid, &content);
          663  +        rebuild_step(rid, size, &content);
          664  +      }
          665  +    }
          666  +  }
          667  +  db_finalize(&s);
          668  +  if(!g.fQuiet && ttyOutput ){
          669  +    printf("\n");
          670  +  }
          671  +
          672  +  /* free filename format string */
          673  +  free(zFNameFormat);
          674  +  zFNameFormat = 0;
          675  +}

Changes to src/report.c.

    86     86   }
    87     87   
    88     88   /*
    89     89   ** Remove whitespace from both ends of a string.
    90     90   */
    91     91   char *trim_string(const char *zOrig){
    92     92     int i;
    93         -  while( isspace(*zOrig) ){ zOrig++; }
           93  +  while( fossil_isspace(*zOrig) ){ zOrig++; }
    94     94     i = strlen(zOrig);
    95         -  while( i>0 && isspace(zOrig[i-1]) ){ i--; }
           95  +  while( i>0 && fossil_isspace(zOrig[i-1]) ){ i--; }
    96     96     return mprintf("%.*s", i, zOrig);
    97     97   }
    98     98   
    99     99   /*
   100    100   ** Extract a numeric (integer) value from a string.
   101    101   */
   102    102   char *extract_integer(const char *zOrig){
   103    103     if( zOrig == NULL || zOrig[0] == 0 ) return "";
   104         -  while( *zOrig && !isdigit(*zOrig) ){ zOrig++; }
          104  +  while( *zOrig && !fossil_isdigit(*zOrig) ){ zOrig++; }
   105    105     if( *zOrig ){
   106    106       /* we have a digit. atoi() will get as much of the number as it
   107    107       ** can. We'll run it through mprintf() to get a string. Not
   108    108       ** an efficient way to do it, but effective.
   109    109       */
   110    110       return mprintf("%d", atoi(zOrig));
   111    111     }
................................................................................
   116    116   ** Remove blank lines from the beginning of a string and
   117    117   ** all whitespace from the end. Removes whitespace preceeding a NL,
   118    118   ** which also converts any CRNL sequence into a single NL.
   119    119   */
   120    120   char *remove_blank_lines(const char *zOrig){
   121    121     int i, j, n;
   122    122     char *z;
   123         -  for(i=j=0; isspace(zOrig[i]); i++){ if( zOrig[i]=='\n' ) j = i+1; }
          123  +  for(i=j=0; fossil_isspace(zOrig[i]); i++){ if( zOrig[i]=='\n' ) j = i+1; }
   124    124     n = strlen(&zOrig[j]);
   125         -  while( n>0 && isspace(zOrig[j+n-1]) ){ n--; }
          125  +  while( n>0 && fossil_isspace(zOrig[j+n-1]) ){ n--; }
   126    126     z = mprintf("%.*s", n, &zOrig[j]);
   127    127     for(i=j=0; z[i]; i++){
   128         -    if( z[i+1]=='\n' && z[i]!='\n' && isspace(z[i]) ){
          128  +    if( z[i+1]=='\n' && z[i]!='\n' && fossil_isspace(z[i]) ){
   129    129         z[j] = z[i];
   130         -      while(isspace(z[j]) && z[j] != '\n' ){ j--; }
          130  +      while(fossil_isspace(z[j]) && z[j] != '\n' ){ j--; }
   131    131         j++;
   132    132         continue;
   133    133       }
   134    134   
   135    135       z[j++] = z[i];
   136    136     }
   137    137     z[j] = 0;
................................................................................
   143    143   
   144    144   /*
   145    145   ** This is the SQLite authorizer callback used to make sure that the
   146    146   ** SQL statements entered by users do not try to do anything untoward.
   147    147   ** If anything suspicious is tried, set *(char**)pError to an error
   148    148   ** message obtained from malloc.
   149    149   */
   150         -static int report_query_authorizer(
          150  +int report_query_authorizer(
   151    151     void *pError,
   152    152     int code,
   153    153     const char *zArg1,
   154    154     const char *zArg2,
   155    155     const char *zArg3,
   156    156     const char *zArg4
   157    157   ){
................................................................................
   210    210     const char *zTail;
   211    211     sqlite3_stmt *pStmt;
   212    212     int rc;
   213    213   
   214    214     /* First make sure the SQL is a single query command by verifying that
   215    215     ** the first token is "SELECT" and that there are no unquoted semicolons.
   216    216     */
   217         -  for(i=0; isspace(zSql[i]); i++){}
          217  +  for(i=0; fossil_isspace(zSql[i]); i++){}
   218    218     if( strncasecmp(&zSql[i],"select",6)!=0 ){
   219    219       return mprintf("The SQL must be a SELECT statement");
   220    220     }
   221    221     for(i=0; zSql[i]; i++){
   222    222       if( zSql[i]==';' ){
   223    223         int bad;
   224    224         int c = zSql[i+1];
................................................................................
   275    275     }
   276    276     zTitle = db_column_text(&q, 0);
   277    277     zSQL = db_column_text(&q, 1);
   278    278     zOwner = db_column_text(&q, 2);
   279    279     zClrKey = db_column_text(&q, 3);
   280    280     @ <table cellpadding=0 cellspacing=0 border=0>
   281    281     @ <tr><td valign="top" align="right">Title:</td><td width=15></td>
   282         -  @ <td colspan=3>%h(zTitle)</td></tr>
          282  +  @ <td colspan="3">%h(zTitle)</td></tr>
   283    283     @ <tr><td valign="top" align="right">Owner:</td><td></td>
   284         -  @ <td colspan=3>%h(zOwner)</td></tr>
          284  +  @ <td colspan="3">%h(zOwner)</td></tr>
   285    285     @ <tr><td valign="top" align="right">SQL:</td><td></td>
   286    286     @ <td valign="top"><pre>
   287    287     @ %h(zSQL)
   288    288     @ </pre></td>
   289    289     @ <td width=15></td><td valign="top">
   290    290     output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3");
   291    291     @ </td>
................................................................................
   326    326       return;
   327    327     }else if( rn>0 && P("del1") ){
   328    328       zTitle = db_text(0, "SELECT title FROM reportfmt "
   329    329                            "WHERE rn=%d", rn);
   330    330       if( zTitle==0 ) cgi_redirect("reportlist");
   331    331   
   332    332       style_header("Are You Sure?");
   333         -    @ <form action="rptedit" method="POST">
          333  +    @ <form action="rptedit" method="post">
   334    334       @ <p>You are about to delete all traces of the report
   335    335       @ <strong>%h(zTitle)</strong> from
   336    336       @ the database.  This is an irreversible operation.  All records
   337    337       @ related to this report will be removed and cannot be recovered.</p>
   338    338       @
   339    339       @ <input type="hidden" name="rn" value="%d(rn)">
   340    340       login_insert_csrf_secret();
................................................................................
   391    391         zTitle = mprintf("Copy Of %s", zTitle);
   392    392         zOwner = g.zLogin;
   393    393       }
   394    394     }
   395    395     if( zOwner==0 ) zOwner = g.zLogin;
   396    396     style_submenu_element("Cancel", "Cancel", "reportlist");
   397    397     if( rn>0 ){
   398         -    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
          398  +    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&amp;del1=1", rn);
   399    399     }
   400    400     style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
   401    401     if( zErr ){
   402         -    @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote>
          402  +    @ <blockquote class="reportError">%h(zErr)</blockquote>
   403    403     }
   404         -  @ <form action="rptedit" method="POST">
   405         -  @ <input type="hidden" name="rn" value="%d(rn)">
   406         -  @ <p>Report Title:<br>
   407         -  @ <input type="text" name="t" value="%h(zTitle)" size="60"></p>
   408         -  @ <p>Enter a complete SQL query statement against the "TICKET" table:<br>
          404  +  @ <form action="rptedit" method="post"><div>
          405  +  @ <input type="hidden" name="rn" value="%d(rn)" />
          406  +  @ <p>Report Title:<br />
          407  +  @ <input type="text" name="t" value="%h(zTitle)" size="60" /></p>
          408  +  @ <p>Enter a complete SQL query statement against the "TICKET" table:<br />
   409    409     @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea>
   410    410     @ </p>
   411    411     login_insert_csrf_secret();
   412    412     if( g.okAdmin ){
   413    413       @ <p>Report owner:
   414         -    @ <input type="text" name="w" size="20" value="%h(zOwner)">
          414  +    @ <input type="text" name="w" size="20" value="%h(zOwner)" />
   415    415       @ </p>
   416    416     } else {
   417         -    @ <input type="hidden" name="w" value="%h(zOwner)">
          417  +    @ <input type="hidden" name="w" value="%h(zOwner)" />
   418    418     }
   419    419     @ <p>Enter an optional color key in the following box.  (If blank, no
   420    420     @ color key is displayed.)  Each line contains the text for a single
   421    421     @ entry in the key.  The first token of each line is the background
   422         -  @ color for that line.<br>
          422  +  @ color for that line.<br />
   423    423     @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea>
   424    424     @ </p>
   425    425     if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){
   426    426       @ <p>This report format is owned by %h(zOwner).  You are not allowed
   427    427       @ to change it.</p>
   428    428       @ </form>
   429    429       report_format_hints();
   430    430       style_footer();
   431    431       return;
   432    432     }
   433         -  @ <input type="submit" value="Apply Changes">
          433  +  @ <input type="submit" value="Apply Changes" />
   434    434     if( rn>0 ){
   435         -    @ <input type="submit" value="Delete This Report" name="del1">
          435  +    @ <input type="submit" value="Delete This Report" name="del1" />
   436    436     }
   437         -  @ </form>
          437  +  @ </div></form>
   438    438     report_format_hints();
   439    439     style_footer();
   440    440   }
   441    441   
   442    442   /*
   443    443   ** Output a bunch of text that provides information about report
   444    444   ** formats
................................................................................
   446    446   static void report_format_hints(void){
   447    447     char *zSchema;
   448    448     zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'");
   449    449     if( zSchema==0 ){
   450    450       zSchema = db_text(0,"SELECT sql FROM repository.sqlite_master"
   451    451                           " WHERE name='ticket'");
   452    452     }
   453         -  @ <hr><h3>TICKET Schema</h3>
          453  +  @ <hr /><h3>TICKET Schema</h3>
   454    454     @ <blockquote><pre>
   455    455     @ %h(zSchema)
   456    456     @ </pre></blockquote>
   457    457     @ <h3>Notes</h3>
   458    458     @ <ul>
   459    459     @ <li><p>The SQL must consist of a single SELECT statement</p></li>
   460    460     @
................................................................................
   476    476     @
   477    477     @ <h3>Examples</h3>
   478    478     @ <p>In this example, the first column in the result set is named
   479    479     @ "bgcolor".  The value of this column is not displayed.  Instead, it
   480    480     @ selects the background color of each row based on the TICKET.STATUS
   481    481     @ field of the database.  The color key at the right shows the various
   482    482     @ color codes.</p>
   483         -  @ <table align="right" style="margin: 0 5px;" border=1 cellspacing=0 width=125>
   484         -  @ <tr bgcolor="#f2dcdc"><td align="center">new or active</td></tr>
   485         -  @ <tr bgcolor="#e8e8bd"><td align="center">review</td></tr>
   486         -  @ <tr bgcolor="#cfe8bd"><td align="center">fixed</td></tr>
   487         -  @ <tr bgcolor="#bde5d6"><td align="center">tested</td></tr>
   488         -  @ <tr bgcolor="#cacae5"><td align="center">defer</td></tr>
   489         -  @ <tr bgcolor="#c8c8c8"><td align="center">closed</td></tr>
          483  +  @ <table class="rpteditex">
          484  +  @ <tr style="background-color:#f2dcdc;"><td class="rpteditex">new or active</td></tr>
          485  +  @ <tr style="background-color:#e8e8bd;"><td class="rpteditex">review</td></tr>
          486  +  @ <tr style="background-color:#cfe8bd;"><td class="rpteditex">fixed</td></tr>
          487  +  @ <tr style="background-color:#bde5d6;"><td class="rpteditex">tested</td></tr>
          488  +  @ <tr style="background-color:#cacae5;"><td class="rpteditex">defer</td></tr>
          489  +  @ <tr style="background-color:#c8c8c8;"><td class="rpteditex">closed</td></tr>
   490    490     @ </table>
   491    491     @ <blockquote><pre>
   492    492     @ SELECT
   493    493     @   CASE WHEN status IN ('new','active') THEN '#f2dcdc'
   494    494     @        WHEN status='review' THEN '#e8e8bd'
   495    495     @        WHEN status='fixed' THEN '#cfe8bd'
   496    496     @        WHEN status='tested' THEN '#bde5d6'
................................................................................
   508    508     @   priority AS 'Pri',
   509    509     @   title AS 'Title'
   510    510     @ FROM ticket
   511    511     @ </pre></blockquote>
   512    512     @ <p>To base the background color on the TICKET.PRIORITY or
   513    513     @ TICKET.SEVERITY fields, substitute the following code for the
   514    514     @ first column of the query:</p>
   515         -  @ <table align="right" style="margin: 0 5px;" border=1 cellspacing=0 width=125>
   516         -  @ <tr bgcolor="#f2dcdc"><td align="center">1</td></tr>
   517         -  @ <tr bgcolor="#e8e8bd"><td align="center">2</td></tr>
   518         -  @ <tr bgcolor="#cfe8bd"><td align="center">3</td></tr>
   519         -  @ <tr bgcolor="#cacae5"><td align="center">4</td></tr>
   520         -  @ <tr bgcolor="#c8c8c8"><td align="center">5</td></tr>
          515  +  @ <table class="rpteditex">
          516  +  @ <tr style="background-color:#f2dcdc;"><td class="rpteditex">1</td></tr>
          517  +  @ <tr style="background-color:#e8e8bd;"><td class="rpteditex">2</td></tr>
          518  +  @ <tr style="background-color:#cfe8bd;"><td class="rpteditex">3</td></tr>
          519  +  @ <tr style="background-color:#cacae5;"><td class="rpteditex">4</td></tr>
          520  +  @ <tr style="background-color:#c8c8c8;"><td class="rpteditex">5</td></tr>
   521    521     @ </table>
   522    522     @ <blockquote><pre>
   523    523     @ SELECT
   524    524     @   CASE priority WHEN 1 THEN '#f2dcdc'
   525    525     @        WHEN 2 THEN '#e8e8bd'
   526    526     @        WHEN 3 THEN '#cfe8bd'
   527    527     @        WHEN 4 THEN '#cacae5'
................................................................................
   581    581     @    title AS 'Title',
   582    582     @    wiki(substr(description,0,80)) AS 'Description'
   583    583     @  FROM ticket
   584    584     @ </pre></blockquote>
   585    585     @
   586    586   }
   587    587   
   588         -#if 0 /* NOT USED */
   589         -static void column_header(int rn,const char *zCol, int nCol, int nSorted,
   590         -    const char *zDirection, const char *zExtra
   591         -){
   592         -  int set = (nCol==nSorted);
   593         -  int desc = !strcmp(zDirection,"DESC");
   594         -
   595         -  /*
   596         -  ** Clicking same column header 3 times in a row resets any sorting.
   597         -  ** Note that we link to rptview, which means embedded reports will get
   598         -  ** sent to the actual report view page as soon as a user tries to do
   599         -  ** any sorting. I don't see that as a Bad Thing.
   600         -  */
   601         -  if(set && desc){
   602         -    @ <th bgcolor="%s(BG1)" class="bkgnd1">
   603         -    @   <a href="rptview?rn=%d(rn)%s(zExtra)">%h(zCol)</a></th>
   604         -  }else{
   605         -    if(set){
   606         -      @ <th bgcolor="%s(BG1)" class="bkgnd1"><a
   607         -    }else{
   608         -      @ <th><a
   609         -    }
   610         -    @ href="rptview?rn=%d(rn)&amp;order_by=%d(nCol)&amp;\
   611         -    @ order_dir=%s(desc?"ASC":"DESC")\
   612         -    @ %s(zExtra)">%h(zCol)</a></th>
   613         -  }
   614         -}
   615         -#endif
   616         -
   617    588   /*
   618    589   ** The state of the report generation.
   619    590   */
   620    591   struct GenerateHTML {
   621    592     int rn;          /* Report number */
   622    593     int nCount;      /* Row number */
   623    594     int nCol;        /* Number of columns */
................................................................................
   721    692       @ <tr><td colspan=%d(pState->nCol)><font size=1>&nbsp;</font></td></tr>
   722    693     }
   723    694   
   724    695     /* Output the data for this entry from the database
   725    696     */
   726    697     zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0;
   727    698     if( zBg==0 ) zBg = "white";
   728         -  @ <tr bgcolor="%h(zBg)">
          699  +  @ <tr style="background-color:%h(zBg)">
   729    700     zTid = 0;
   730    701     zPage[0] = 0;
   731    702     for(i=0; i<nArg; i++){
   732    703       char *zData;
   733    704       if( i==pState->iBg ) continue;
   734    705       zData = azArg[i];
   735    706       if( zData==0 ) zData = "";
................................................................................
   736    707       if( pState->iNewRow>=0 && i>=pState->iNewRow ){
   737    708         if( zTid && g.okWrite ){
   738    709           @ <td valign="top"><a href="tktedit/%h(zTid)">edit</a></td>
   739    710           zTid = 0;
   740    711         }
   741    712         if( zData[0] ){
   742    713           Blob content;
   743         -        @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(pState->nCol)>
          714  +        @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
   744    715           blob_init(&content, zData, -1);
   745    716           wiki_convert(&content, 0, 0);
   746    717           blob_reset(&content);
   747    718         }
   748    719       }else if( azName[i][0]=='#' ){
   749    720         zTid = zData;
   750    721         if( g.okHistory ){
................................................................................
   770    741   /*
   771    742   ** Output the text given in the argument.  Convert tabs and newlines into
   772    743   ** spaces.
   773    744   */
   774    745   static void output_no_tabs(const char *z){
   775    746     while( z && z[0] ){
   776    747       int i, j;
   777         -    for(i=0; z[i] && (!isspace(z[i]) || z[i]==' '); i++){}
          748  +    for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){}
   778    749       if( i>0 ){
   779    750         cgi_printf("%.*s", i, z);
   780    751       }
   781         -    for(j=i; isspace(z[j]); j++){}
          752  +    for(j=i; fossil_isspace(z[j]); j++){}
   782    753       if( j>i ){
   783    754         cgi_printf("%*s", j-i, "");
   784    755       }
   785    756       z += j;
   786    757     }
   787    758   }
   788    759   
................................................................................
   814    785   
   815    786   /*
   816    787   ** Generate HTML that describes a color key.
   817    788   */
   818    789   void output_color_key(const char *zClrKey, int horiz, char *zTabArgs){
   819    790     int i, j, k;
   820    791     char *zSafeKey, *zToFree;
   821         -  while( isspace(*zClrKey) ) zClrKey++;
          792  +  while( fossil_isspace(*zClrKey) ) zClrKey++;
   822    793     if( zClrKey[0]==0 ) return;
   823    794     @ <table %s(zTabArgs)>
   824    795     if( horiz ){
   825    796       @ <tr>
   826    797     }
   827    798     zToFree = zSafeKey = mprintf("%h", zClrKey);
   828    799     while( zSafeKey[0] ){
   829         -    while( isspace(*zSafeKey) ) zSafeKey++;
   830         -    for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){}
   831         -    for(j=i; isspace(zSafeKey[j]); j++){}
          800  +    while( fossil_isspace(*zSafeKey) ) zSafeKey++;
          801  +    for(i=0; zSafeKey[i] && !fossil_isspace(zSafeKey[i]); i++){}
          802  +    for(j=i; fossil_isspace(zSafeKey[j]); j++){}
   832    803       for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){}
   833    804       if( !horiz ){
   834         -      cgi_printf("<tr bgcolor=\"%.*s\"><td>%.*s</td></tr>\n",
          805  +      cgi_printf("<tr style=\"background-color: %.*s;\"><td>%.*s</td></tr>\n",
   835    806           i, zSafeKey, k-j, &zSafeKey[j]);
   836    807       }else{
   837         -      cgi_printf("<td bgcolor=\"%.*s\">%.*s</td>\n",
          808  +      cgi_printf("<td style=\"background-color: %.*s;\">%.*s</td>\n",
   838    809           i, zSafeKey, k-j, &zSafeKey[j]);
   839    810       }
   840    811       zSafeKey += k;
   841    812     }
   842    813     free(zToFree);
   843    814     if( horiz ){
   844    815       @ </tr>
................................................................................
   905    876   
   906    877     count = 0;
   907    878     if( !tabs ){
   908    879       struct GenerateHTML sState;
   909    880   
   910    881       db_multi_exec("PRAGMA empty_result_callbacks=ON");
   911    882       style_submenu_element("Raw", "Raw", 
   912         -      "rptview?tablist=1&%s", PD("QUERY_STRING",""));
          883  +      "rptview?tablist=1&amp;%h", PD("QUERY_STRING",""));
   913    884       if( g.okAdmin 
   914    885          || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){
   915    886         style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn);
   916    887       }
   917    888       if( g.okTktFmt ){
   918    889         style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn);
   919    890       }
   920    891       if( g.okNewTkt ){
   921    892         style_submenu_element("New Ticket", "Create a new ticket",
   922    893           "%s/tktnew", g.zTop);
   923    894       }
   924    895       style_header(zTitle);
   925    896       output_color_key(zClrKey, 1, 
   926         -        "border=0 cellpadding=3 cellspacing=0 class=\"report\"");
   927         -    @ <table border=1 cellpadding=2 cellspacing=0 class="report">
          897  +        "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
          898  +    @ <table border="1" cellpadding="2" cellspacing="0" class="report">
   928    899       sState.rn = rn;
   929    900       sState.nCount = 0;
   930    901       sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
   931    902       sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
   932    903       sqlite3_set_authorizer(g.db, 0, 0);
   933    904       @ </table>
   934    905       if( zErr1 ){
   935         -      @ <p><font color="red"><b>Error: %h(zErr1)</b></font></p>
          906  +      @ <p class="reportError">Error: %h(zErr1)</p>
   936    907       }else if( zErr2 ){
   937         -      @ <p><font color="red"><b>Error: %h(zErr2)</b></font></p>
          908  +      @ <p class="reportError">Error: %h(zErr2)</p>
   938    909       }
   939    910       style_footer();
   940    911     }else{
   941    912       sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
   942    913       sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2);
   943    914       sqlite3_set_authorizer(g.db, 0, 0);
   944    915       cgi_set_content_type("text/plain");
   945    916     }
   946    917   }
          918  +
          919  +/*
          920  +** report number for full table ticket export
          921  +*/
          922  +static const char zFullTicketRptRn[] = "0";
          923  +
          924  +/*
          925  +** report title for full table ticket export
          926  +*/
          927  +static const char zFullTicketRptTitle[] = "full ticket export";
          928  +
          929  +/*
          930  +** show all reports, which can be used for ticket show.
          931  +** Output is written to stdout as tab delimited table
          932  +*/
          933  +void rpt_list_reports(void){
          934  +  Stmt q;
          935  +  char const aRptOutFrmt[] = "%s\t%s\n";
          936  +
          937  +  printf("Available reports:\n");
          938  +  printf(aRptOutFrmt,"report number","report title");
          939  +  printf(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
          940  +  db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
          941  +  while( db_step(&q)==SQLITE_ROW ){
          942  +    const char *zRn = db_column_text(&q, 0);
          943  +    const char *zTitle = db_column_text(&q, 1);
          944  +
          945  +    printf(aRptOutFrmt,zRn,zTitle);
          946  +  }
          947  +  db_finalize(&q);
          948  +}
          949  +
          950  +/*
          951  +** user defined separator used by ticket show command
          952  +*/
          953  +static const char *zSep = 0;
          954  +
          955  +/*
          956  +** select the quoting algorithm for "ticket show"
          957  +*/
          958  +#if INTERFACE
          959  +typedef enum eTktShowEnc { tktNoTab=0, tktFossilize=1 } tTktShowEncoding;
          960  +#endif
          961  +static tTktShowEncoding tktEncode = tktNoTab;
          962  +
          963  +/*
          964  +** Output the text given in the argument.  Convert tabs and newlines into
          965  +** spaces.
          966  +*/
          967  +static void output_no_tabs_file(const char *z){
          968  +  switch( tktEncode ){
          969  +    case tktFossilize:
          970  +      { char *zFosZ;
          971  +
          972  +        if( z && *z ){
          973  +          zFosZ = fossilize(z,-1);
          974  +          printf("%s",zFosZ);
          975  +          free(zFosZ);
          976  +        }
          977  +        break;
          978  +      }
          979  +    default:
          980  +      while( z && z[0] ){
          981  +        int i, j;
          982  +        for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){}
          983  +        if( i>0 ){
          984  +          printf("%.*s", i, z);
          985  +        }
          986  +        for(j=i; fossil_isspace(z[j]); j++){}
          987  +        if( j>i ){
          988  +          printf("%*s", j-i, "");
          989  +        }
          990  +        z += j;
          991  +      }
          992  +      break; 
          993  +  }
          994  +}
          995  +
          996  +/*
          997  +** Output a row as a tab-separated line of text.
          998  +*/
          999  +int output_separated_file(
         1000  +  void *pUser,     /* Pointer to row-count integer */
         1001  +  int nArg,        /* Number of columns in this result row */
         1002  +  char **azArg,    /* Text of data in all columns */
         1003  +  char **azName    /* Names of the columns */
         1004  +){
         1005  +  int *pCount = (int*)pUser;
         1006  +  int i;
         1007  +
         1008  +  if( *pCount==0 ){
         1009  +    for(i=0; i<nArg; i++){
         1010  +      output_no_tabs_file(azName[i]);
         1011  +      printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
         1012  +    }
         1013  +  }
         1014  +  ++*pCount;
         1015  +  for(i=0; i<nArg; i++){
         1016  +    output_no_tabs_file(azArg[i]);
         1017  +    printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
         1018  +  }
         1019  +  return 0;
         1020  +}
         1021  +
         1022  +/*
         1023  +** Generate a report.  The rn query parameter is the report number.
         1024  +** The output is written to stdout as flat file. The zFilter paramater
         1025  +** is a full WHERE-condition.
         1026  +*/
         1027  +void rptshow( 
         1028  +    const char *zRep,
         1029  +    const char *zSepIn,
         1030  +    const char *zFilter,
         1031  +    tTktShowEncoding enc
         1032  +){
         1033  +  Stmt q;
         1034  +  char *zSql;
         1035  +  const char *zTitle;
         1036  +  const char *zOwner;
         1037  +  const char *zClrKey;
         1038  +  char *zErr1 = 0;
         1039  +  char *zErr2 = 0;
         1040  +  int count = 0;
         1041  +  int rn;
         1042  +
         1043  +  if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){
         1044  +    zTitle = zFullTicketRptTitle;
         1045  +    zSql = "SELECT * FROM ticket";
         1046  +    zOwner = g.zLogin;
         1047  +    zClrKey = "";
         1048  +  }else{
         1049  +    rn = atoi(zRep);
         1050  +    if( rn ){
         1051  +      db_prepare(&q,
         1052  +       "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn);
         1053  +    }else{
         1054  +      db_prepare(&q,
         1055  +       "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep);
         1056  +    }
         1057  +    if( db_step(&q)!=SQLITE_ROW ){
         1058  +      db_finalize(&q);
         1059  +      rpt_list_reports();
         1060  +      fossil_fatal("unkown report format(%s)!",zRep);
         1061  +    }
         1062  +    zTitle = db_column_malloc(&q, 0);
         1063  +    zSql = db_column_malloc(&q, 1);
         1064  +    zOwner = db_column_malloc(&q, 2);
         1065  +    zClrKey = db_column_malloc(&q, 3);
         1066  +    db_finalize(&q);
         1067  +  }
         1068  +  if( zFilter ){
         1069  +    zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter);
         1070  +  }
         1071  +  count = 0;
         1072  +  tktEncode = enc;
         1073  +  zSep = zSepIn;
         1074  +  sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
         1075  +  sqlite3_exec(g.db, zSql, output_separated_file, &count, &zErr2);
         1076  +  sqlite3_set_authorizer(g.db, 0, 0);
         1077  +  if( zFilter ){
         1078  +    free(zSql);
         1079  +  }
         1080  +}

Changes to src/rss.c.

    14     14   **   http://www.hwaci.com/drh/
    15     15   **
    16     16   *******************************************************************************
    17     17   **
    18     18   ** This file contains code used to create a RSS feed for the CGI interface.
    19     19   */
    20     20   #include "config.h"
           21  +#include <time.h>
    21     22   #include "rss.h"
    22     23   #include <assert.h>
    23         -#include <time.h>
    24     24   
    25     25   /*
    26     26   ** WEBPAGE: timeline.rss
    27     27   */
    28     28   void page_timeline_rss(void){
    29     29     Stmt q;
    30     30     int nLine=0;

Changes to src/schema.c.

   239    239   @
   240    240   @ -- A record of phantoms.  A phantom is a record for which we know the
   241    241   @ -- UUID but we do not (yet) know the file content.
   242    242   @ --
   243    243   @ CREATE TABLE phantom(
   244    244   @   rid INTEGER PRIMARY KEY         -- Record ID of the phantom
   245    245   @ );
          246  +@
          247  +@ -- A record of orphaned delta-manifests.  An orphan is a delta-manifest
          248  +@ -- for which we have content, but its baseline-manifest is a phantom.
          249  +@ -- We have to track all orphan maniftests so that when the baseline arrives,
          250  +@ -- we know to process the orphaned deltas.
          251  +@ CREATE TABLE orphan(
          252  +@   rid INTEGER PRIMARY KEY,        -- Delta manifest with a phantom baseline
          253  +@   baseline INTEGER                -- Phantom baseline of this orphan
          254  +@ );
          255  +@ CREATE INDEX orphan_baseline ON orphan(baseline);
   246    256   @
   247    257   @ -- Unclustered records.  An unclustered record is a record (including
   248    258   @ -- a cluster records themselves) that is not mentioned by some other
   249    259   @ -- cluster.
   250    260   @ --
   251    261   @ -- Phantoms are usually included in the unclustered table.  A new cluster
   252    262   @ -- will never be created that contains a phantom.  But another repository

Changes to src/search.c.

    40     40   */
    41     41   Search *search_init(const char *zPattern){
    42     42     int nPattern = strlen(zPattern);
    43     43     Search *p;
    44     44     char *z;
    45     45     int i;
    46     46   
    47         -  p = malloc( nPattern + sizeof(*p) + 1);
    48         -  if( p==0 ) fossil_panic("out of memory");
           47  +  p = fossil_malloc( nPattern + sizeof(*p) + 1);
    49     48     z = (char*)&p[1];
    50     49     strcpy(z, zPattern);
    51     50     memset(p, 0, sizeof(*p));
    52     51     while( *z && p->nTerm<sizeof(p->a)/sizeof(p->a[0]) ){
    53         -    while( !isalnum(*z) && *z ){ z++; }
           52  +    while( !fossil_isalnum(*z) && *z ){ z++; }
    54     53       if( *z==0 ) break;
    55     54       p->a[p->nTerm].z = z;
    56         -    for(i=1; isalnum(z[i]) || z[i]=='_'; i++){}
           55  +    for(i=1; fossil_isalnum(z[i]) || z[i]=='_'; i++){}
    57     56       p->a[p->nTerm].n = i;
    58     57       z += i;
    59     58       p->nTerm++;
    60     59     }
    61     60     return p;
    62     61   }
    63     62   

Changes to src/setup.c.

    17     17   **
    18     18   ** Implementation of the Setup page
    19     19   */
    20     20   #include <assert.h>
    21     21   #include "config.h"
    22     22   #include "setup.h"
    23     23   
           24  +/*
           25  +** The table of web pages supported by this application is generated
           26  +** automatically by the "mkindex" program and written into a file
           27  +** named "page_index.h".  We include that file here to get access
           28  +** to the table.
           29  +*/
           30  +#include "page_index.h"
    24     31   
    25     32   /*
    26     33   ** Output a single entry for a menu generated using an HTML table.
    27     34   ** If zLink is not NULL or an empty string, then it is the page that
    28     35   ** the menu entry will hyperlink to.  If zLink is NULL or "", then
    29     36   ** the menu entry has no hyperlink - it is disabled.
    30     37   */
................................................................................
    55     62     @ <table border="0" cellspacing="20">
    56     63     setup_menu_entry("Users", "setup_ulist",
    57     64       "Grant privileges to individual users.");
    58     65     setup_menu_entry("Access", "setup_access",
    59     66       "Control access settings.");
    60     67     setup_menu_entry("Configuration", "setup_config",
    61     68       "Configure the WWW components of the repository");
           69  +  setup_menu_entry("Settings", "setup_settings",
           70  +    "Web interface to the \"fossil settings\" command");
    62     71     setup_menu_entry("Timeline", "setup_timeline",
    63     72       "Timeline display preferences");
    64     73     setup_menu_entry("Tickets", "tktsetup",
    65     74       "Configure the trouble-ticketing system for this repository");
    66     75     setup_menu_entry("Skins", "setup_skin",
    67     76       "Select from a menu of prepackaged \"skins\" for the web interface");
    68     77     setup_menu_entry("CSS", "setup_editcss",
................................................................................
    97    106     if( !g.okAdmin ){
    98    107       login_needed();
    99    108       return;
   100    109     }
   101    110   
   102    111     style_submenu_element("Add", "Add User", "setup_uedit");
   103    112     style_header("User List");
   104         -  @ <table border="0" cellpadding="0" cellspacing="25">
   105         -  @ <tr><td valign="top">
   106         -  @ <b>Users:</b>
   107         -  @ <table border="1" cellpadding="10"><tr><td>
   108         -  @ <table cellspacing=0 cellpadding=0 border=0>
          113  +  @ <table class="usetupLayoutTable">
          114  +  @ <tr><td class="usetupColumnLayout">
          115  +  @ <span class="note">Users:</span>
          116  +  @ <table class="usetupUserList">
   109    117     @ <tr>
   110         -  @   <th align="right">User&nbsp;ID</th><td width="20">&nbsp;</td>
   111         -  @   <th>Capabilities</th><td width="15">&nbsp;</td>
   112         -  @   <th>Contact&nbsp;Info</th>
          118  +  @   <th class="usetupListUser" style="text-align: right;padding-right: 20px;">User&nbsp;ID</th>
          119  +  @   <th class="usetupListCap" style="text-align: center;padding-right: 15px;">Capabilities</th>
          120  +  @   <th class="usetupListCon"  style="text-align: left;">Contact&nbsp;Info</th>
   113    121     @ </tr>
   114    122     db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login");
   115    123     while( db_step(&s)==SQLITE_ROW ){
   116    124       const char *zCap = db_column_text(&s, 2);
   117    125       if( strstr(zCap, "s") ) zCap = "s";
   118    126       @ <tr>
   119         -    @ <td align="right">
          127  +    @ <td class="usetupListUser" style="text-align: right;padding-right: 20px;white-space:nowrap;">
   120    128       if( g.okAdmin && (zCap[0]!='s' || g.okSetup) ){
   121    129         @ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
   122    130       }
   123         -    @ <nobr>%h(db_column_text(&s,1))</nobr>
          131  +    @ %h(db_column_text(&s,1))
   124    132       if( g.okAdmin ){
   125    133         @ </a>
   126    134       }
   127         -    @ </td><td>&nbsp;&nbsp;&nbsp;</td>
   128         -    @ <td align="center">%s(zCap)</td>
   129         -    @ <td>&nbsp;&nbsp;&nbsp;</td>
   130         -    @ <td align="left">%s(db_column_text(&s,3))</td>
          135  +    @ </td>
          136  +    @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
          137  +    @ <td  class="usetupListCon"  style="text-align: left;">%s(db_column_text(&s,3))</td>
   131    138       @ </tr>
   132    139     }
   133         -  @ </table></td></tr></table>
   134         -  @ <td valign="top">
   135         -  @ <b>Notes:</b>
          140  +  @ </table>
          141  +  @ </td><td class="usetupColumnLayout">
          142  +  @ <span class="note">Notes:</span>
   136    143     @ <ol>
   137    144     @ <li><p>The permission flags are as follows:</p>
   138    145     @ <table>
   139    146        @ <tr><td valign="top"><b>a</b></td>
   140    147        @   <td><i>Admin:</i> Create and delete users</td></tr>
   141    148        @ <tr><td valign="top"><b>b</b></td>
   142    149        @   <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
................................................................................
   179    186        @ <tr><td valign="top"><b>v</b></td>
   180    187        @   <td><i>Developer:</i> Inherit privileges of
   181    188        @   user <tt>developer</tt></td></tr>
   182    189        @ <tr><td valign="top"><b>w</b></td>
   183    190        @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
   184    191        @ <tr><td valign="top"><b>z</b></td>
   185    192        @   <td><i>Zip download:</i> Download a baseline via the
   186         -     @   <tt>/zip</tt> URL even without check<b>o</b>ut
   187         -     @    and <b>h</b>istory permissions</td></tr>
          193  +     @   <tt>/zip</tt> URL even without 
          194  +     @    check<span class="capability">o</span>ut
          195  +     @    and <span class="capability">h</span>istory permissions</td></tr>
   188    196     @ </table>
   189    197     @ </li>
   190    198     @
   191    199     @ <li><p>
   192         -  @ Every user, logged in or not, inherits the privileges of <b>nobody</b>.
          200  +  @ Every user, logged in or not, inherits the privileges of
          201  +  @ <span class="usertype">nobody</span>.
   193    202     @ </p></li>
   194    203     @
   195    204     @ <li><p>
   196         -  @ Any human can login as <b>anonymous</b> since the password is
   197         -  @ clearly displayed on the login page for them to type.  The purpose
   198         -  @ of requiring anonymous to log in is to prevent access by spiders.
          205  +  @ Any human can login as <span class="usertype">anonymous</span> since the
          206  +  @ password is clearly displayed on the login page for them to type. The
          207  +  @ purpose of requiring anonymous to log in is to prevent access by spiders.
   199    208     @ Every logged-in user inherits the combined privileges of
   200         -  @ <b>anonymous</b> and
   201         -  @ <b>nobody</b>.
          209  +  @ <span class="usertype">anonymous</span> and
          210  +  @ <span class="usertype">nobody</span>.
   202    211     @ </p></li>
   203    212     @
   204    213     @ <li><p>
   205         -  @ Users with privilege <b>v</b> inherit the combined privileges of
   206         -  @ <b>developer</b>, <b>anonymous</b>, and <b>nobody</b>.
          214  +  @ Users with privilege <span class="capability">v</span> inherit the combined
          215  +  @ privileges of <span class="usertype">developer</span>,
          216  +  @ <span class="usertype">anonymous</span>, and
          217  +  @ <span class="usertype">nobody</span>.
   207    218     @ </p></li>
   208    219     @
   209    220     @ </ol>
   210    221     @ </td></tr></table>
   211    222     style_footer();
   212    223   }
   213    224   
................................................................................
   321    332       }else{
   322    333         zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid);
   323    334       }
   324    335       if( uid>0 &&
   325    336           db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid)
   326    337       ){
   327    338         style_header("User Creation Error");
   328         -      @ <font color="red">Login "%h(zLogin)" is already used by a different
   329         -      @ user.</font>
          339  +      @ <span class="loginError">Login "%h(zLogin)" is already used by
          340  +      @ a different user.</span>
   330    341         @
   331    342         @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
   332    343         style_footer();
   333    344         return;
   334    345       }
   335    346       login_verify_csrf_secret();
   336    347       db_multi_exec(
................................................................................
   351    362     oaa = oab = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam =
   352    363           oan = oao = oap = oar = oas = oat = oau = oav = oaw = oaz = "";
   353    364     if( uid ){
   354    365       zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
   355    366       zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
   356    367       zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
   357    368       zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid);
   358         -    if( strchr(zCap, 'a') ) oaa = " checked";
   359         -    if( strchr(zCap, 'b') ) oab = " checked";
   360         -    if( strchr(zCap, 'c') ) oac = " checked";
   361         -    if( strchr(zCap, 'd') ) oad = " checked";
   362         -    if( strchr(zCap, 'e') ) oae = " checked";
   363         -    if( strchr(zCap, 'f') ) oaf = " checked";
   364         -    if( strchr(zCap, 'g') ) oag = " checked";
   365         -    if( strchr(zCap, 'h') ) oah = " checked";
   366         -    if( strchr(zCap, 'i') ) oai = " checked";
   367         -    if( strchr(zCap, 'j') ) oaj = " checked";
   368         -    if( strchr(zCap, 'k') ) oak = " checked";
   369         -    if( strchr(zCap, 'm') ) oam = " checked";
   370         -    if( strchr(zCap, 'n') ) oan = " checked";
   371         -    if( strchr(zCap, 'o') ) oao = " checked";
   372         -    if( strchr(zCap, 'p') ) oap = " checked";
   373         -    if( strchr(zCap, 'r') ) oar = " checked";
   374         -    if( strchr(zCap, 's') ) oas = " checked";
   375         -    if( strchr(zCap, 't') ) oat = " checked";
   376         -    if( strchr(zCap, 'u') ) oau = " checked";
   377         -    if( strchr(zCap, 'v') ) oav = " checked";
   378         -    if( strchr(zCap, 'w') ) oaw = " checked";
   379         -    if( strchr(zCap, 'z') ) oaz = " checked";
          369  +    if( strchr(zCap, 'a') ) oaa = " checked=\"checked\"";
          370  +    if( strchr(zCap, 'b') ) oab = " checked=\"checked\"";
          371  +    if( strchr(zCap, 'c') ) oac = " checked=\"checked\"";
          372  +    if( strchr(zCap, 'd') ) oad = " checked=\"checked\"";
          373  +    if( strchr(zCap, 'e') ) oae = " checked=\"checked\"";
          374  +    if( strchr(zCap, 'f') ) oaf = " checked=\"checked\"";
          375  +    if( strchr(zCap, 'g') ) oag = " checked=\"checked\"";
          376  +    if( strchr(zCap, 'h') ) oah = " checked=\"checked\"";
          377  +    if( strchr(zCap, 'i') ) oai = " checked=\"checked\"";
          378  +    if( strchr(zCap, 'j') ) oaj = " checked=\"checked\"";
          379  +    if( strchr(zCap, 'k') ) oak = " checked=\"checked\"";
          380  +    if( strchr(zCap, 'm') ) oam = " checked=\"checked\"";
          381  +    if( strchr(zCap, 'n') ) oan = " checked=\"checked\"";
          382  +    if( strchr(zCap, 'o') ) oao = " checked=\"checked\"";
          383  +    if( strchr(zCap, 'p') ) oap = " checked=\"checked\"";
          384  +    if( strchr(zCap, 'r') ) oar = " checked=\"checked\"";
          385  +    if( strchr(zCap, 's') ) oas = " checked=\"checked\"";
          386  +    if( strchr(zCap, 't') ) oat = " checked=\"checked\"";
          387  +    if( strchr(zCap, 'u') ) oau = " checked=\"checked\"";
          388  +    if( strchr(zCap, 'v') ) oav = " checked=\"checked\"";
          389  +    if( strchr(zCap, 'w') ) oaw = " checked=\"checked\"";
          390  +    if( strchr(zCap, 'z') ) oaz = " checked=\"checked\"";
   380    391     }
   381    392   
   382    393     /* figure out inherited permissions */
   383    394     memset(inherit, 0, sizeof(inherit));
   384    395     if( strcmp(zLogin, "developer") ){
   385    396       char *z1, *z2;
   386    397       z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
   387    398       while( z1 && *z1 ){
   388         -      inherit[0x7f & *(z1++)] = "<font color=\"red\">&bull;</font>";
          399  +      inherit[0x7f & *(z1++)] =
          400  +         "<span class=\"ueditInheritDeveloper\">&bull;</span>";
   389    401       }
   390    402       free(z2);
   391    403     }
   392    404     if( strcmp(zLogin, "reader") ){
   393    405       char *z1, *z2;
   394    406       z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
   395    407       while( z1 && *z1 ){
   396         -      inherit[0x7f & *(z1++)] = "<font color=\"black\">&bull;</font>";
          408  +      inherit[0x7f & *(z1++)] =
          409  +          "<span class=\"ueditInheritReader\">&bull;</span>";
   397    410       }
   398    411       free(z2);
   399    412     }
   400    413     if( strcmp(zLogin, "anonymous") ){
   401    414       char *z1, *z2;
   402    415       z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
   403    416       while( z1 && *z1 ){
   404         -      inherit[0x7f & *(z1++)] = "<font color=\"blue\">&bull;</font>";
          417  +      inherit[0x7f & *(z1++)] =
          418  +           "<span class=\"ueditInheritAnonymous\">&bull;</span>";
   405    419       }
   406    420       free(z2);
   407    421     }
   408    422     if( strcmp(zLogin, "nobody") ){
   409    423       char *z1, *z2;
   410    424       z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
   411    425       while( z1 && *z1 ){
   412         -      inherit[0x7f & *(z1++)] = "<font color=\"green\">&bull;</font>";
          426  +      inherit[0x7f & *(z1++)] =
          427  +           "<span class=\"ueditInheritNobody\">&bull;</span>";
   413    428       }
   414    429       free(z2);
   415    430     }
   416    431   
   417    432     /* Begin generating the page
   418    433     */
   419    434     style_submenu_element("Cancel", "Cancel", "setup_ulist");
   420    435     if( uid ){
   421    436       style_header(mprintf("Edit User %h", zLogin));
   422    437     }else{
   423    438       style_header("Add A New User");
   424    439     }
   425         -  @ <table align="left" hspace="20" vspace="10"><tr><td>
   426         -  @ <form action="%s(g.zPath)" method="POST">
          440  +  @ <div class="ueditCapBox">
          441  +  @ <form action="%s(g.zPath)" method="post"><div>
   427    442     login_insert_csrf_secret();
   428    443     @ <table>
   429    444     @ <tr>
   430         -  @   <td align="right"><nobr>User ID:</nobr></td>
          445  +  @   <td class="usetupEditLabel">User ID:</td>
   431    446     if( uid ){
   432         -    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td>
          447  +    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
   433    448     }else{
   434         -    @   <td>(new user)<input type="hidden" name="id" value=0></td>
          449  +    @   <td>(new user)<input type="hidden" name="id" value="0" /></td>
   435    450     }
   436    451     @ </tr>
          452  +  @ <tr>
          453  +  @   <td class="usetupEditLabel">Login:</td>
          454  +  @   <td><input type="text" name="login" value="%h(zLogin)" /></td>
          455  +  @ </tr>
   437    456     @ <tr>
   438         -  @   <td align="right"><nobr>Login:</nobr></td>
   439         -  @   <td><input type="text" name="login" value="%h(zLogin)"></td>
          457  +  @   <td class="usetupEditLabel">Contact&nbsp;Info:</td>
          458  +  @   <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td>
   440    459     @ </tr>
   441    460     @ <tr>
   442         -  @   <td align="right"><nobr>Contact&nbsp;Info:</nobr></td>
   443         -  @   <td><input type="text" name="info" size=40 value="%h(zInfo)"></td>
   444         -  @ </tr>
   445         -  @ <tr>
   446         -  @   <td align="right" valign="top">Capabilities:</td>
          461  +  @   <td class="usetupEditLabel">Capabilities:</td>
   447    462     @   <td>
   448    463   #define B(x) inherit[x]
   449    464     if( g.okSetup ){
   450         -    @    <input type="checkbox" name="as"%s(oas)/>%s(B('s'))Setup<br>
   451         -  }
   452         -  @    <input type="checkbox" name="aa"%s(oaa)/>%s(B('a'))Admin<br>
   453         -  @    <input type="checkbox" name="ad"%s(oad)/>%s(B('d'))Delete<br>
   454         -  @    <input type="checkbox" name="ae"%s(oae)/>%s(B('e'))Email<br>
   455         -  @    <input type="checkbox" name="ap"%s(oap)/>%s(B('p'))Password<br>
   456         -  @    <input type="checkbox" name="ai"%s(oai)/>%s(B('i'))Check-In<br>
   457         -  @    <input type="checkbox" name="ao"%s(oao)/>%s(B('o'))Check-Out<br>
   458         -  @    <input type="checkbox" name="ah"%s(oah)/>%s(B('h'))History<br>
   459         -  @    <input type="checkbox" name="au"%s(oau)/>%s(B('u'))Reader<br>
   460         -  @    <input type="checkbox" name="av"%s(oav)/>%s(B('v'))Developer<br>
   461         -  @    <input type="checkbox" name="ag"%s(oag)/>%s(B('g'))Clone<br>
   462         -  @    <input type="checkbox" name="aj"%s(oaj)/>%s(B('j'))Read Wiki<br>
   463         -  @    <input type="checkbox" name="af"%s(oaf)/>%s(B('f'))New Wiki<br>
   464         -  @    <input type="checkbox" name="am"%s(oam)/>%s(B('m'))Append Wiki<br>
   465         -  @    <input type="checkbox" name="ak"%s(oak)/>%s(B('k'))Write Wiki<br>
   466         -  @    <input type="checkbox" name="ab"%s(oab)/>%s(B('b'))Attachments<br>
   467         -  @    <input type="checkbox" name="ar"%s(oar)/>%s(B('r'))Read Ticket<br>
   468         -  @    <input type="checkbox" name="an"%s(oan)/>%s(B('n'))New Ticket<br>
   469         -  @    <input type="checkbox" name="ac"%s(oac)/>%s(B('c'))Append Ticket<br>
   470         -  @    <input type="checkbox" name="aw"%s(oaw)/>%s(B('w'))Write Ticket<br>
   471         -  @    <input type="checkbox" name="at"%s(oat)/>%s(B('t'))Ticket Report<br>
   472         -  @    <input type="checkbox" name="az"%s(oaz)/>%s(B('z'))Download Zip
          465  +    @    <input type="checkbox" name="as"%s(oas) />%s(B('s'))Setup<br />
          466  +  }
          467  +  @    <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br />
          468  +  @    <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br />
          469  +  @    <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br />
          470  +  @    <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br />
          471  +  @    <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br />
          472  +  @    <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br />
          473  +  @    <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br />
          474  +  @    <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br />
          475  +  @    <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br />
          476  +  @    <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br />
          477  +  @    <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br />
          478  +  @    <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br />
          479  +  @    <input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki<br />
          480  +  @    <input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki<br />
          481  +  @    <input type="checkbox" name="ab"%s(oab) />%s(B('b'))Attachments<br />
          482  +  @    <input type="checkbox" name="ar"%s(oar) />%s(B('r'))Read Ticket<br />
          483  +  @    <input type="checkbox" name="an"%s(oan) />%s(B('n'))New Ticket<br />
          484  +  @    <input type="checkbox" name="ac"%s(oac) />%s(B('c'))Append Ticket<br />
          485  +  @    <input type="checkbox" name="aw"%s(oaw) />%s(B('w'))Write Ticket<br />
          486  +  @    <input type="checkbox" name="at"%s(oat) />%s(B('t'))Ticket Report<br />
          487  +  @    <input type="checkbox" name="az"%s(oaz) />%s(B('z'))Download Zip
   473    488     @   </td>
   474    489     @ </tr>
   475    490     @ <tr>
   476    491     @   <td align="right">Password:</td>
   477    492     if( zPw[0] ){
   478    493       /* Obscure the password for all users */
   479         -    @   <td><input type="password" name="pw" value="**********"></td>
          494  +    @   <td><input type="password" name="pw" value="**********" /></td>
   480    495     }else{
   481    496       /* Show an empty password as an empty input field */
   482         -    @   <td><input type="password" name="pw" value=""></td>
          497  +    @   <td><input type="password" name="pw" value="" /></td>
   483    498     }
   484    499     @ </tr>
   485    500     if( !higherUser ){
   486    501       @ <tr>
   487         -    @   <td>&nbsp</td>
   488         -    @   <td><input type="submit" name="submit" value="Apply Changes">
          502  +    @   <td>&nbsp;</td>
          503  +    @   <td><input type="submit" name="submit" value="Apply Changes" /></td>
   489    504       @ </tr>
   490    505     }
   491         -  @ </table></td></tr></table>
          506  +  @ </table>
          507  +  @ </div></form>
          508  +  @ </div>
   492    509     @ <h2>Privileges And Capabilities:</h2>
   493    510     @ <ul>
   494    511     if( higherUser ){
   495         -    @ <li><p><font color="blue"><b>
          512  +    @ <li><p class=missingPriv">
   496    513       @ User %h(zLogin) has Setup privileges and you only have Admin privileges
   497    514       @ so you are not permitted to make changes to %h(zLogin).
   498         -    @ </b></font></p></li>
          515  +    @ </p></li>
   499    516       @
   500    517     }
   501    518     @ <li><p>
   502         -  @ The <b>Setup</b> user can make arbitrary configuration changes.
   503         -  @ An <b>Admin</b> user can add other users and change user privileges
          519  +  @ The <span class="capability">Setup</span> user can make arbitrary
          520  +  @ configuration changes. An <span class="usertype">Admin</span> user
          521  +  @ can add other users and change user privileges
   504    522     @ and reset user passwords.  Both automatically get all other privileges
   505    523     @ listed below.  Use these two settings with discretion.
   506    524     @ </p></li>
   507    525     @
   508    526     @ <li><p>
   509         -  @ The "<font color="green"><big>&bull;</big></font>" mark indicates
   510         -  @ the privileges of "nobody" that are available to all users
   511         -  @ regardless of whether or not they are logged in.
          527  +  @ The "<span class="ueditInheritNobody"><big>&bull;</big></span>" mark
          528  +  @ indicates the privileges of <span class="usertype">nobody</span> that
          529  +  @ are available to all users regardless of whether or not they are logged in.
          530  +  @ </p></li>
          531  +  @
          532  +  @ <li><p>
          533  +  @ The "<span class="ueditInheritAnonymous"><big>&bull;</big></span>" mark
          534  +  @ indicates the privileges of <span class="usertype">anonymous</span> that
          535  +  @ are inherited by all logged-in users.
          536  +  @ </p></li>
          537  +  @
          538  +  @ <li><p>
          539  +  @ The "<span class="ueditInheritDeveloper"><big>&bull;</big></span>" mark
          540  +  @ indicates the privileges of <span class="usertype">developer</span> that
          541  +  @ are inherited by all users with the
          542  +  @ <span class="capability">Developer</span> privilege.
          543  +  @ </p></li>
          544  +  @
          545  +  @ <li><p>
          546  +  @ The "<span class="ueditInheritReader"><big>&bull;</big></span>" mark
          547  +  @ indicates the privileges of <span class="usertype">reader</span> that
          548  +  @ are inherited by all users with the <span class="capability">Reader</span>
          549  +  @ privilege.
          550  +  @ </p></li>
          551  +  @
          552  +  @ <li><p>
          553  +  @ The <span class="capability">Delete</span> privilege give the user the
          554  +  @ ability to erase wiki, tickets, and attachments that have been added
          555  +  @ by anonymous users.  This capability is intended for deletion of spam. 
          556  +  @ The delete capability is only in effect for 24 hours after the item
          557  +  @ is first posted.  The <span class="usertype">Setup</span> user can
          558  +  @ delete anything at any time.
          559  +  @ </p></li>
          560  +  @
          561  +  @ <li><p>
          562  +  @ The <span class="capability">History</span> privilege allows a user
          563  +  @ to see most hyperlinks. This is recommended ON for most logged-in users
          564  +  @ but OFF for user "nobody" to avoid problems with spiders trying to walk
          565  +  @ every historical version of every baseline and file.
          566  +  @ </p></li>
          567  +  @
          568  +  @ <li><p>
          569  +  @ The <span class="capability">Zip</span> privilege allows a user to
          570  +  @ see the "download as ZIP"
          571  +  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
          572  +  @ users to download ZIP archives without granting other rights like
          573  +  @ <span class="capability">Read</span> or
          574  +  @ <span class="capability">History</span>.  This privilege is recommended for
          575  +  @ user <span class="usertype">nobody</span> so that automatic package
          576  +  @ downloaders can obtain the sources without going through the login
          577  +  @ procedure.
   512    578     @ </p></li>
   513    579     @
   514    580     @ <li><p>
   515         -  @ The "<font color="blue"><big>&bull;</big></font>" mark indicates
   516         -  @ the privileges of "anonymous" that are inherited by all logged-in users.
          581  +  @ The <span class="capability">Check-in</span> privilege allows remote
          582  +  @ users to "push". The <span class="capability">Check-out</span> privilege
          583  +  @ allows remote users to "pull". The <span class="capability">Clone</span>
          584  +  @ privilege allows remote users to "clone".
   517    585     @ </p></li>
   518    586     @
   519    587     @ <li><p>
   520         -  @ The "<font color="red"><big>&bull;</big></font>" mark indicates
   521         -  @ the privileges of "developer" that are inherited by all users with
   522         -  @ the <b>Developer</b> privilege.
          588  +  @ The <span class="capability">Read Wiki</span>,
          589  +  @ <span class="capability">New Wiki</span>,
          590  +  @ <span class="capability">Append Wiki</span>, and
          591  +  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
          592  +  @ <span class="capability">Read Ticket</span>,
          593  +  @ <span class="capability">New Ticket</span>,
          594  +  @ <span class="capability">Append Ticket</span>, and
          595  +  @ <span class="capability">Write Ticket</span> privileges control access
          596  +  @ to trouble tickets.
          597  +  @ The <span class="capability">Ticket Report</span> privilege allows
          598  +  @ the user to create or edit ticket report formats.
   523    599     @ </p></li>
   524    600     @
   525    601     @ <li><p>
   526         -  @ The "<font color="black"><big>&bull;</big></font>" mark indicates
   527         -  @ the privileges of "reader" that are inherited by all users with
   528         -  @ the <b>Reader</b> privilege.
   529         -  @ </p></li>
   530         -  @
   531         -  @ <li><p>
   532         -  @ The <b>Delete</b> privilege give the user the ability to erase
   533         -  @ wiki, tickets, and attachments that have been added by anonymous
   534         -  @ users.  This capability is intended for deletion of spam.  The
   535         -  @ delete capability is only in effect for 24 hours after the item
   536         -  @ is first posted.  The Setup user can delete anything at any time.
          602  +  @ Users with the <span class="capability">Password</span> privilege
          603  +  @ are allowed to change their own password.  Recommended ON for most
          604  +  @ users but OFF for special users <span class="usertype">developer</span>,
          605  +  @ <span class="usertype">anonymous</span>,
          606  +  @ and <span class="usertype">nobody</span>.
   537    607     @ </p></li>
   538    608     @
   539    609     @ <li><p>
   540         -  @ The <b>History</b> privilege allows a user to see most hyperlinks.
   541         -  @ This is recommended ON for most logged-in users but OFF for
   542         -  @ user "nobody" to avoid problems with spiders trying to walk every
   543         -  @ historical version of every baseline and file.
   544         -  @ </p></li>
   545         -  @
   546         -  @ <li><p>
   547         -  @ The <b>Zip</b> privilege allows a user to see the "download as ZIP"
   548         -  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
   549         -  @ users to download ZIP archives without granting other rights like
   550         -  @ <b>Read</b> or <b>History</b>.  This privilege is recommended for
   551         -  @ user <b>nobody</b> so that automatic package downloaders can obtain
   552         -  @ the sources without going through the login procedure.
          610  +  @ The <span class="capability">EMail</span> privilege allows the display of
          611  +  @ sensitive information such as the email address of users and contact
          612  +  @ information on tickets. Recommended OFF for 
          613  +  @ <span class="usertype">anonymousy</span> and for
          614  +  @ <span class="usertype">nobody</span> but ON for
          615  +  @ <span class="usertype">developer</span>.
   553    616     @ </p></li>
   554    617     @
   555    618     @ <li><p>
   556         -  @ The <b>Check-in</b> privilege allows remote users to "push".
   557         -  @ The <b>Check-out</b> privilege allows remote users to "pull".
   558         -  @ The <b>Clone</b> privilege allows remote users to "clone".
   559         -  @ </li><p>
   560         -  @
   561         -  @ <li><p>
   562         -  @ The <b>Read Wiki</b>, <b>New Wiki</b>, <b>Append Wiki</b>, and
   563         -  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
   564         -  @ <b>Read Ticket</b>, <b>New Ticket</b>, <b>Append Ticket</b>, and
   565         -  @ <b>Write Ticket</b> privileges control access to trouble tickets.
   566         -  @ The <b>Ticket Report</b> privilege allows the user to create or edit
   567         -  @ ticket report formats.
          619  +  @ The <span class="capability">Attachment</span> privilege is needed in
          620  +  @ order to add attachments to tickets or wiki.  Write privilege on the
          621  +  @ ticket or wiki is also required.
   568    622     @ </p></li>
   569    623     @
   570         -  @ <li><p>
   571         -  @ Users with the <b>Password</b> privilege are allowed to change their
   572         -  @ own password.  Recommended ON for most users but OFF for special
   573         -  @ users "developer", "anonymous", and "nobody".
   574         -  @ </p></li>
   575         -  @
   576         -  @ <li><p>
   577         -  @ The <b>EMail</b> privilege allows the display of sensitive information
   578         -  @ such as the email address of users and contact information on tickets.
   579         -  @ Recommended OFF for "anonymous" and for "nobody" but ON for
   580         -  @ "developer".
   581         -  @ </p></li>
   582         -  @
   583         -  @ <li><p>
   584         -  @ The <b>Attachment</b> privilege is needed in order to add attachments
   585         -  @ to tickets or wiki.  Write privilege on the ticket or wiki is also
   586         -  @ required.</p></li>
   587         -  @
   588    624     @ <li><p>
   589    625     @ Login is prohibited if the password is an empty string.
   590    626     @ </p></li>
   591    627     @ </ul>
   592    628     @
   593    629     @ <h2>Special Logins</h2>
   594    630     @
   595    631     @ <ul>
   596    632     @ <li><p>
   597         -  @ No login is required for user "<b>nobody</b>".  The capabilities
   598         -  @ of the <b>nobody</b> user are inherited by all users, regardless of
   599         -  @ whether or not they are logged in.  To disable universal access
   600         -  @ to the repository, make sure no user named "<b>nobody</b>" exists or
   601         -  @ that the <b>nobody</b> user has no capabilities enabled.
   602         -  @ The password for <b>nobody</b> is ignore.  To avoid problems with
   603         -  @ spiders overloading the server, it is recommended
   604         -  @ that the 'h' (History) capability be turned off for the <b>nobody</b>
   605         -  @ user.
          633  +  @ No login is required for user <span class="usertype">nobody</span>. The
          634  +  @ capabilities of the <span class="usertype">nobody</span> user are
          635  +  @ inherited by all users, regardless of whether or not they are logged in.
          636  +  @ To disable universal access to the repository, make sure no user named 
          637  +  @ <span class="usertype">nobody</span> exists or that the
          638  +  @ <span class="usertype">nobody</span> user has no capabilities
          639  +  @ enabled. The password for <span class="usertype">nobody</span> is ignore.
          640  +  @ To avoid problems with spiders overloading the server, it is recommended
          641  +  @ that the <span class="capability">h</span> (History) capability be turned 
          642  +  @ off for the <span class="usertype">nobody</span> user.
   606    643     @ </p></li>
   607    644     @
   608    645     @ <li><p>
   609         -  @ Login is required for user "<b>anonymous</b>" but the password
   610         -  @ is displayed on the login screen beside the password entry box
          646  +  @ Login is required for user <span class="usertype">anonymous</span> but the
          647  +  @ password is displayed on the login screen beside the password entry box
   611    648     @ so anybody who can read should be able to login as anonymous.
   612    649     @ On the other hand, spiders and web-crawlers will typically not
   613         -  @ be able to login.  Set the capabilities of the anonymous user
   614         -  @ to things that you want any human to be able to do, but not any
          650  +  @ be able to login.  Set the capabilities of the
          651  +  @ <span class="usertype">anonymous</span>
          652  +  @ user to things that you want any human to be able to do, but not any
   615    653     @ spider.  Every other logged-in user inherits the privileges of
   616         -  @ <b>anonymous</b>.
          654  +  @ <span class="usertype">anonymous</span>.
   617    655     @ </p></li>
   618    656     @
   619    657     @ <li><p>
   620         -  @ The "<b>developer</b>" user is intended as a template for trusted users
   621         -  @ with check-in privileges.  When adding new trusted users, simply
   622         -  @ select the <b>Developer</b> privilege to cause the new user to inherit
   623         -  @ all privileges of the "developer" user.  Similarly, the "<b>reader</b>"
   624         -  @ user is a template for users who are allowed more access than anonymous,
   625         -  @ but less than a developer.
          658  +  @ The <span class="usertype">developer</span> user is intended as a template
          659  +  @ for trusted users with check-in privileges. When adding new trusted users,
          660  +  @ simply select the <span class="capability">developer</span> privilege to
          661  +  @ cause the new user to inherit all privileges of the 
          662  +  @ <span class="usertype">developer</span>
          663  +  @ user.  Similarly, the <span class="usertype">reader</span> user is a 
          664  +  @ template for users who are allowed more access than
          665  +  @ <span class="usertype">anonymous</span>,
          666  +  @ but less than a <span class="usertype">developer</span>.
   626    667     @ </p></li>
   627    668     @ </ul>
   628         -  @ </form>
   629    669     style_footer();
   630    670   }
   631    671   
   632    672   
   633    673   /*
   634    674   ** Generate a checkbox for an attribute.
   635    675   */
................................................................................
   649    689       if( iQ!=iVal ){
   650    690         login_verify_csrf_secret();
   651    691         db_set(zVar, iQ ? "1" : "0", 0);
   652    692         iVal = iQ;
   653    693       }
   654    694     }
   655    695     if( iVal ){
   656         -    @ <input type="checkbox" name="%s(zQParm)" checked><b>%s(zLabel)</b></input>
          696  +    @ <input type="checkbox" name="%s(zQParm)" checked="checked" />
          697  +    @ <b>%s(zLabel)</b>
   657    698     }else{
   658         -    @ <input type="checkbox" name="%s(zQParm)"><b>%s(zLabel)</b></input>
          699  +    @ <input type="checkbox" name="%s(zQParm)" /> <b>%s(zLabel)</b>
   659    700     }
   660    701   }
   661    702   
   662    703   /*
   663    704   ** Generate an entry box for an attribute.
   664    705   */
   665    706   void entry_attribute(
................................................................................
   672    713     const char *zVal = db_get(zVar, zDflt);
   673    714     const char *zQ = P(zQParm);
   674    715     if( zQ && strcmp(zQ,zVal)!=0 ){
   675    716       login_verify_csrf_secret();
   676    717       db_set(zVar, zQ, 0);
   677    718       zVal = zQ;
   678    719     }
   679         -  @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)">
          720  +  @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" />
   680    721     @ <b>%s(zLabel)</b>
   681    722   }
   682    723   
   683    724   /*
   684    725   ** Generate a text box for an attribute.
   685    726   */
   686    727   static void textarea_attribute(
................................................................................
   696    737     if( zQ && strcmp(zQ,z)!=0 ){
   697    738       login_verify_csrf_secret();
   698    739       db_set(zVar, zQ, 0);
   699    740       z = zQ;
   700    741     }
   701    742     if( rows>0 && cols>0 ){
   702    743       @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea>
   703         -    @ <b>%s(zLabel)</b>
          744  +    if (zLabel && *zLabel)
          745  +      @ <span class="textareaLabel">%s(zLabel)</span>
   704    746     }
   705    747   }
   706    748   
   707    749   
   708    750   /*
   709    751   ** WEBPAGE: setup_access
   710    752   */
................................................................................
   712    754     login_check_credentials();
   713    755     if( !g.okSetup ){
   714    756       login_needed();
   715    757     }
   716    758   
   717    759     style_header("Access Control Settings");
   718    760     db_begin_transaction();
   719         -  @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
          761  +  @ <form action="%s(g.zBaseURL)/setup_access" method="post"><div>
   720    762     login_insert_csrf_secret();
   721         -  @ <hr>
          763  +  @ <hr />
   722    764     onoff_attribute("Require password for local access",
   723    765        "localauth", "localauth", 0);
   724    766     @ <p>When enabled, the password sign-in is required for
   725    767     @ web access coming from 127.0.0.1.  When disabled, web access
   726    768     @ from 127.0.0.1 is allows without any login - the user id is selected
   727    769     @ from the ~/.fossil database. Password login is always required
   728    770     @ for incoming web connections on internet addresses other than
   729         -  @ 127.0.0.1.</p></li>
          771  +  @ 127.0.0.1.</p>
   730    772   
   731         -  @ <hr>
          773  +  @ <hr />
   732    774     onoff_attribute("Allow REMOTE_USER authentication",
   733    775        "remote_user_ok", "remote_user_ok", 0);
   734    776     @ <p>When enabled, if the REMOTE_USER environment variable is set to the
   735    777     @ login name of a valid user and no other login credentials are available,
   736    778     @ then the REMOTE_USER is accepted as an authenticated user.
   737         -  @ </p></li>
          779  +  @ </p>
   738    780   
   739         -  @ <hr>
          781  +  @ <hr />
   740    782     entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
   741    783     @ <p>The number of hours for which a login is valid.  This must be a
   742    784     @ positive number.  The default is 8760 hours which is approximately equal
   743    785     @ to a year.</p>
   744    786   
   745         -  @ <hr>
          787  +  @ <hr />
   746    788     entry_attribute("Download packet limit", 10, "max-download", "mxdwn",
   747    789                     "5000000");
   748    790     @ <p>Fossil tries to limit out-bound sync, clone, and pull packets
   749    791     @ to this many bytes, uncompressed.  If the client requires more data
   750    792     @ than this, then the client will issue multiple HTTP requests.
   751    793     @ Values below 1 million are not recommended.  5 million is a
   752    794     @ reasonable number.</p>
   753    795   
   754         -  @ <hr>
          796  +  @ <hr />
   755    797     onoff_attribute("Show javascript button to fill in CAPTCHA",
   756    798                     "auto-captcha", "autocaptcha", 0);
   757    799     @ <p>When enabled, a button appears on the login screen for user
   758    800     @ "anonymous" that will automatically fill in the CAPTCHA password.
   759    801     @ This is less secure that forcing the user to do it manually, but is
   760    802     @ probably secure enough and it is certainly more convenient for
   761    803     @ anonymous users.</p>
   762    804   
   763         -  @ <hr>
   764         -  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
   765         -  @ </form>
          805  +  @ <hr />
          806  +  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
          807  +  @ </div></form>
   766    808     db_end_transaction(0);
   767    809     style_footer();
   768    810   }
   769    811   
   770    812   /*
   771    813   ** WEBPAGE: setup_timeline
   772    814   */
................................................................................
   774    816     login_check_credentials();
   775    817     if( !g.okSetup ){
   776    818       login_needed();
   777    819     }
   778    820   
   779    821     style_header("Timeline Display Preferences");
   780    822     db_begin_transaction();
   781         -  @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST">
          823  +  @ <form action="%s(g.zBaseURL)/setup_timeline" method="post"><div>
   782    824     login_insert_csrf_secret();
   783    825   
   784         -  @ <hr>
          826  +  @ <hr />
   785    827     onoff_attribute("Allow block-markup in timeline",
   786    828                     "timeline-block-markup", "tbm", 0);
   787    829     @ <p>In timeline displays, check-in comments can be displayed with or
   788    830     @ without block markup (paragraphs, tables, etc.)</p>
   789    831   
   790         -  @ <hr>
          832  +  @ <hr />
   791    833     onoff_attribute("Use Universal Coordinated Time (UTC)",
   792    834                     "timeline-utc", "utc", 1);
   793    835     @ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or
   794    836     @ Zulu) instead of in local time.</p>
   795    837   
   796         -  @ <hr>
          838  +  @ <hr />
   797    839     onoff_attribute("Show version differences by default",
   798    840                     "show-version-diffs", "vdiff", 0);
   799    841     @ <p>On the version-information pages linked from the timeline can either
   800    842     @ show complete diffs of all file changes, or can just list the names of
   801    843     @ the files that have changed.  Users can get to either page by
   802    844     @ clicking.  This setting selects the default.</p>
   803    845   
   804         -  @ <hr>
          846  +  @ <hr />
   805    847     entry_attribute("Max timeline comment length", 6,
   806    848                     "timeline-max-comment", "tmc", "0");
   807    849     @ <p>The maximum length of a comment to be displayed in a timeline.
   808    850     @ "0" there is no length limit.</p>
   809    851   
   810         -  @ <hr>
   811         -  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
   812         -  @ </form>
          852  +  @ <hr />
          853  +  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
          854  +  @ </div></form>
          855  +  db_end_transaction(0);
          856  +  style_footer();
          857  +}
          858  +
          859  +/*
          860  +** WEBPAGE: setup_settings
          861  +*/
          862  +void setup_settings(void){
          863  +  struct stControlSettings const *pSet;
          864  +
          865  +  login_check_credentials();
          866  +  if( !g.okSetup ){
          867  +    login_needed();
          868  +  }
          869  +
          870  +  style_header("Settings");
          871  +  db_begin_transaction();
          872  +  @ <p>This page provides a simple interface to the "fossil setting" command.
          873  +  @ See the "fossil help setting" output below for further information on
          874  +  @ the meaning of each setting.</p><hr />
          875  +  @ <form action="%s(g.zBaseURL)/setup_settings" method="post"><div>
          876  +  @ <table border="0"><tr><td valign="top">
          877  +  login_insert_csrf_secret();
          878  +  for(pSet=ctrlSettings; pSet->name!=0; pSet++){
          879  +    if( pSet->width==0 ){
          880  +      onoff_attribute(pSet->name, pSet->name,
          881  +                      pSet->var!=0 ? pSet->var : pSet->name,
          882  +                      is_truth(pSet->def));
          883  +      @ <br />
          884  +    }
          885  +  }
          886  +  @ </td><td style="width: 30;"></td><td valign="top">
          887  +  for(pSet=ctrlSettings; pSet->name!=0; pSet++){
          888  +    if( pSet->width!=0 ){
          889  +      entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name,
          890  +                      pSet->var!=0 ? pSet->var : pSet->name,
          891  +                      (char*)pSet->def);
          892  +      @ <br />
          893  +    }
          894  +  }
          895  +  @ </td></tr></table>
          896  +  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
          897  +  @ </div></form>
          898  +  @ <hr /><p>
          899  +  @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br />
          900  +  @ </p><pre>%s(zHelp_setting_cmd)</pre>
   813    901     db_end_transaction(0);
   814    902     style_footer();
   815    903   }
   816    904   
   817    905   /*
   818    906   ** WEBPAGE: setup_config
   819    907   */
................................................................................
   821    909     login_check_credentials();
   822    910     if( !g.okSetup ){
   823    911       login_needed();
   824    912     }
   825    913   
   826    914     style_header("WWW Configuration");
   827    915     db_begin_transaction();
   828         -  @ <form action="%s(g.zBaseURL)/setup_config" method="POST">
          916  +  @ <form action="%s(g.zBaseURL)/setup_config" method="post"><div>
   829    917     login_insert_csrf_secret();
   830    918     @ <hr />
   831    919     entry_attribute("Project Name", 60, "project-name", "pn", "");
   832    920     @ <p>Give your project a name so visitors know what this site is about.
   833    921     @ The project name will also be used as the RSS feed title.</p>
   834    922     @ <hr />
   835    923     textarea_attribute("Project Description", 5, 60,
................................................................................
   838    926     @ engines as well as a short RSS description.</p>
   839    927     @ <hr />
   840    928     entry_attribute("Index Page", 60, "index-page", "idxpg", "/home");
   841    929     @ <p>Enter the pathname of the page to display when the "Home" menu
   842    930     @ option is selected and when no pathname is
   843    931     @ specified in the URL.  For example, if you visit the url:</p>
   844    932     @
   845         -  @ <blockquote>%h(g.zBaseURL)</blockquote>
          933  +  @ <blockquote><p>%h(g.zBaseURL)</p></blockquote>
   846    934     @
   847    935     @ <p>And you have specified an index page of "/home" the above will
   848    936     @ automatically redirect to:</p>
   849    937     @
   850         -  @ <blockquote>%h(g.zBaseURL)/home</blockquote>
          938  +  @ <blockquote><p>%h(g.zBaseURL)/home</p></blockquote>
   851    939     @
   852    940     @ <p>The default "/home" page displays a Wiki page with the same name
   853    941     @ as the Project Name specified above.  Some sites prefer to redirect
   854    942     @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p>
          943  +  @
          944  +  @ <p>Note:  To avoid a redirect loop or other problems, this entry must
          945  +  @ begin with "/" and it must specify a valid page.  For example,
          946  +  @ "<b>/home</b>" will work but "<b>home</b>" will not, since it omits the
          947  +  @ leading "/".</p>
   855    948     @ <hr />
   856    949     onoff_attribute("Use HTML as wiki markup language",
   857    950       "wiki-use-html", "wiki-use-html", 0);
   858         -  @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed but
   859         -  @ all other wiki formatting will be ignored. This option is helpful if you have
   860         -  @ chosen to use a rich HTML editor for wiki markup such as TinyMCE.</p>
          951  +  @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed
          952  +  @ but all other wiki formatting will be ignored. This option is helpful
          953  +  @ if you have chosen to use a rich HTML editor for wiki markup such as
          954  +  @ TinyMCE.</p>
   861    955     @ <p><strong>CAUTION:</strong> when
   862    956     @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
   863    957     @ No sanitization is done. This means that it is very possible for malicious
   864    958     @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
   865    959     @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
   866    960     @ to trusted users. It should <strong>not</strong> be used on a publically
   867    961     @ editable wiki.</p>
   868    962     @ <hr />
   869         -  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
   870         -  @ </form>
          963  +  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
          964  +  @ </div></form>
   871    965     db_end_transaction(0);
   872    966     style_footer();
   873    967   }
   874    968   
   875    969   /*
   876    970   ** WEBPAGE: setup_editcss
   877    971   */
................................................................................
   890    984       textarea_attribute(0, 0, 0, "css", "css", zDefaultCSS);
   891    985     }
   892    986     if( P("submit")!=0 ){
   893    987       db_end_transaction(0);
   894    988       cgi_redirect("setup_editcss");
   895    989     }
   896    990     style_header("Edit CSS");
   897         -  @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST">
          991  +  @ <form action="%s(g.zBaseURL)/setup_editcss" method="post"><div>
   898    992     login_insert_csrf_secret();
   899    993     @ Edit the CSS below:<br />
   900    994     textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
   901    995     @ <br />
   902         -  @ <input type="submit" name="submit" value="Apply Changes">
   903         -  @ <input type="submit" name="clear" value="Revert To Default">
   904         -  @ </form>
   905         -  @ <p><b>Note:</b> Press your browser Reload button after modifying the
   906         -  @ CSS in order to pull in the modified CSS file.</p>
   907         -  @ <hr>
          996  +  @ <input type="submit" name="submit" value="Apply Changes" />
          997  +  @ <input type="submit" name="clear" value="Revert To Default" />
          998  +  @ </div></form>
          999  +  @ <p><span class="note">Note:</span> Press your browser Reload button after
         1000  +  @ modifying the CSS in order to pull in the modified CSS file.</p>
         1001  +  @ <hr />
   908   1002     @ The default CSS is shown below for reference.  Other examples
   909   1003     @ of CSS files can be seen on the <a href="setup_skin">skins page</a>.
   910   1004     @ See also the <a href="setup_header">header</a> and
   911   1005     @ <a href="setup_footer">footer</a> editing screens.
   912   1006     @ <blockquote><pre>
   913         -  @ %h(zDefaultCSS)
         1007  +  cgi_append_default_css();
   914   1008     @ </pre></blockquote>
   915   1009     style_footer();
   916   1010     db_end_transaction(0);
   917   1011   }
   918   1012   
   919   1013   /*
   920   1014   ** WEBPAGE: setup_header
................................................................................
   928   1022     if( P("clear")!=0 ){
   929   1023       db_multi_exec("DELETE FROM config WHERE name='header'");
   930   1024       cgi_replace_parameter("header", zDefaultHeader);
   931   1025     }else{
   932   1026       textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
   933   1027     }
   934   1028     style_header("Edit Page Header");
   935         -  @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
         1029  +  @ <form action="%s(g.zBaseURL)/setup_header" method="post"><div>
   936   1030     login_insert_csrf_secret();
   937   1031     @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   938   1032     @ generate the beginning of every page through start of the main
   939   1033     @ menu.</p>
   940   1034     textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
   941   1035     @ <br />
   942         -  @ <input type="submit" name="submit" value="Apply Changes">
   943         -  @ <input type="submit" name="clear" value="Revert To Default">
   944         -  @ </form>
   945         -  @ <hr>
         1036  +  @ <input type="submit" name="submit" value="Apply Changes" />
         1037  +  @ <input type="submit" name="clear" value="Revert To Default" />
         1038  +  @ </div></form>
         1039  +  @ <hr />
   946   1040     @ The default header is shown below for reference.  Other examples
   947   1041     @ of headers can be seen on the <a href="setup_skin">skins page</a>.
   948   1042     @ See also the <a href="setup_editcss">CSS</a> and
   949   1043     @ <a href="setup_footer">footer</a> editing screeens.
   950   1044     @ <blockquote><pre>
   951   1045     @ %h(zDefaultHeader)
   952   1046     @ </pre></blockquote>
................................................................................
   966   1060     if( P("clear")!=0 ){
   967   1061       db_multi_exec("DELETE FROM config WHERE name='footer'");
   968   1062       cgi_replace_parameter("footer", zDefaultFooter);
   969   1063     }else{
   970   1064       textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
   971   1065     }
   972   1066     style_header("Edit Page Footer");
   973         -  @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
         1067  +  @ <form action="%s(g.zBaseURL)/setup_footer" method="post"><div>
   974   1068     login_insert_csrf_secret();
   975   1069     @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   976   1070     @ generate the end of every page.</p>
   977   1071     textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
   978   1072     @ <br />
   979         -  @ <input type="submit" name="submit" value="Apply Changes">
   980         -  @ <input type="submit" name="clear" value="Revert To Default">
   981         -  @ </form>
   982         -  @ <hr>
         1073  +  @ <input type="submit" name="submit" value="Apply Changes" />
         1074  +  @ <input type="submit" name="clear" value="Revert To Default" />
         1075  +  @ </div></form>
         1076  +  @ <hr />
   983   1077     @ The default footer is shown below for reference.  Other examples
   984   1078     @ of footers can be seen on the <a href="setup_skin">skins page</a>.
   985   1079     @ See also the <a href="setup_editcss">CSS</a> and
   986   1080     @ <a href="setup_header">header</a> editing screens.
   987   1081     @ <blockquote><pre>
   988   1082     @ %h(zDefaultFooter)
   989   1083     @ </pre></blockquote>
................................................................................
  1029   1123       );
  1030   1124       db_end_transaction(0);
  1031   1125       cgi_redirect("setup_logo");
  1032   1126     }
  1033   1127     style_header("Edit Project Logo");
  1034   1128     @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks
  1035   1129     @ like this:</p>
  1036         -  @ <blockquote><img src="%s(g.zTop)/logo" alt="logo"></blockquote>
         1130  +  @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" /></p></blockquote>
  1037   1131     @
  1038   1132     @ <p>The logo is accessible to all users at this URL:
  1039   1133     @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>.
  1040   1134     @ The logo may or may not appear on each
  1041   1135     @ page depending on the <a href="setup_editcss">CSS</a> and
  1042   1136     @ <a href="setup_header">header setup</a>.</p>
  1043   1137     @
  1044         -  @ <form action="%s(g.zBaseURL)/setup_logo" method="POST"
  1045         -  @  enctype="multipart/form-data">
         1138  +  @ <form action="%s(g.zBaseURL)/setup_logo" method="post"
         1139  +  @  enctype="multipart/form-data"><div>
  1046   1140     @ <p>To set a new logo image, select a file to use as the logo using
  1047   1141     @ the entry box below and then press the "Change Logo" button.</p>
  1048   1142     login_insert_csrf_secret();
  1049   1143     @ Logo Image file:
  1050         -  @ <input type="file" name="im" size="60" accepts="image/*"><br>
  1051         -  @ <input type="submit" name="set" value="Change Logo">
  1052         -  @ <input type="submit" name="clr" value="Revert To Default">
  1053         -  @ </form>
         1144  +  @ <input type="file" name="im" size="60" accept="image/*" /><br />
         1145  +  @ <input type="submit" name="set" value="Change Logo" />
         1146  +  @ <input type="submit" name="clr" value="Revert To Default" />
         1147  +  @ </div></form>
  1054   1148     @
  1055         -  @ <p><b>Note:</b>  Your browser has probably cached the logo image, so
  1056         -  @ you will probably need to press the Reload button on your browser after
  1057         -  @ changing the logo to provoke your browser to reload the new logo image.
  1058         -  @ </p>
         1149  +  @ <p><span class="note">Note:</span>  Your browser has probably cached the
         1150  +  @ logo image, so you will probably need to press the Reload button on your
         1151  +  @ browser after changing the logo to provoke your browser to reload the new
         1152  +  @ logo image. </p>
  1059   1153     style_footer();
  1060   1154     db_end_transaction(0);
  1061   1155   }

Changes to src/sha1.c.

     1      1   /*
     2         -** This implementation of SHA1 is adapted from the example implementation
     3         -** contained in RFC-3174.
            2  +** This implementation of SHA1.
     4      3   */
     5         -#include <stdint.h>
     6      4   #include <sys/types.h>
     7      5   #include "config.h"
     8      6   #include "sha1.h"
     9      7   
    10         -/*
    11         - * If you do not have the ISO standard stdint.h header file, then you
    12         - * must typdef the following:
    13         - *    name              meaning
    14         - *  uint32_t         unsigned 32 bit integer
    15         - *  uint8_t          unsigned 8 bit integer (i.e., unsigned char)
    16         - *
    17         - */
    18         -#define SHA1HashSize 20
    19         -#define shaSuccess 0
    20         -#define shaInputTooLong 1
    21         -#define shaStateError 2
    22      8   
    23      9   /*
    24         - *  This structure will hold context information for the SHA-1
    25         - *  hashing operation
    26         - */
           10  +** The SHA1 implementation below is adapted from:
           11  +**
           12  +**  $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $
           13  +**  $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $
           14  +**
           15  +** SHA-1 in C
           16  +** By Steve Reid <steve@edmweb.com>
           17  +** 100% Public Domain
           18  +*/
    27     19   typedef struct SHA1Context SHA1Context;
    28     20   struct SHA1Context {
    29         -    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */
    30         -
    31         -    uint32_t Length_Low;            /* Message length in bits      */
    32         -    uint32_t Length_High;           /* Message length in bits      */
    33         -
    34         -    int Message_Block_Index;   /* Index into message block array   */
    35         -    uint8_t Message_Block[64];      /* 512-bit message blocks      */
    36         -
    37         -    int Computed;               /* Is the digest computed?         */
    38         -    int Corrupted;             /* Is the message digest corrupted? */
           21  +  unsigned int state[5];
           22  +  unsigned int count[2];
           23  +  unsigned char buffer[64];
    39     24   };
    40     25   
    41     26   /*
    42         - *  sha1.c
    43         - *
    44         - *  Description:
    45         - *      This file implements the Secure Hashing Algorithm 1 as
    46         - *      defined in FIPS PUB 180-1 published April 17, 1995.
           27  + * blk0() and blk() perform the initial expand.
           28  + * I got the idea of expanding during the round function from SSLeay
    47     29    *
    48         - *      The SHA-1, produces a 160-bit message digest for a given
    49         - *      data stream.  It should take about 2**n steps to find a
    50         - *      message with the same digest as a given message and
    51         - *      2**(n/2) to find any two messages with the same digest,
    52         - *      when n is the digest size in bits.  Therefore, this
    53         - *      algorithm can serve as a means of providing a
    54         - *      "fingerprint" for a message.
           30  + * blk0le() for little-endian and blk0be() for big-endian.
           31  + */
           32  +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
           33  +#define blk0le(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
           34  +    |(rol(block->l[i],8)&0x00FF00FF))
           35  +#define blk0be(i) block->l[i]
           36  +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
           37  +    ^block->l[(i+2)&15]^block->l[i&15],1))
           38  +
           39  +/*
           40  + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
    55     41    *
    56         - *  Portability Issues:
    57         - *      SHA-1 is defined in terms of 32-bit "words".  This code
    58         - *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
    59         - *      bit unsigned integer types.  If your C compiler does not
    60         - *      support 32 bit unsigned integers, this code is not
    61         - *      appropriate.
    62         - *
    63         - *  Caveats:
    64         - *      SHA-1 is designed to work with messages less than 2^64 bits
    65         - *      long.  Although SHA-1 allows a message digest to be generated
    66         - *      for messages of any number of bits less than 2^64, this
    67         - *      implementation only works with messages with a length that is
    68         - *      a multiple of the size of an 8-bit character.
    69         - *
           42  + * Rl0() for little-endian and Rb0() for big-endian.  Endianness is 
           43  + * determined at run-time.
           44  + */
           45  +#define Rl0(v,w,x,y,z,i) \
           46  +    z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=rol(w,30);
           47  +#define Rb0(v,w,x,y,z,i) \
           48  +    z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=rol(w,30);
           49  +#define R1(v,w,x,y,z,i) \
           50  +    z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
           51  +#define R2(v,w,x,y,z,i) \
           52  +    z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
           53  +#define R3(v,w,x,y,z,i) \
           54  +    z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
           55  +#define R4(v,w,x,y,z,i) \
           56  +    z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
           57  +
           58  +typedef union {
           59  +    unsigned char c[64];
           60  +    unsigned int l[16];
           61  +} CHAR64LONG16;
           62  +
           63  +/*
           64  + * Hash a single 512-bit block. This is the core of the algorithm.
    70     65    */
    71         -
    72         -/*
    73         - *  Define the SHA1 circular left shift macro
    74         - */
    75         -#define SHA1CircularShift(bits,word) \
    76         -                (((word) << (bits)) | ((word) >> (32-(bits))))
    77         -
    78         -/* Local Function Prototyptes */
    79         -static void SHA1PadMessage(SHA1Context *);
    80         -static void SHA1ProcessMessageBlock(SHA1Context *);
    81         -
    82         -/*
    83         - *  SHA1Reset
    84         - *
    85         - *  Description:
    86         - *      This function will initialize the SHA1Context in preparation
    87         - *      for computing a new SHA1 message digest.
    88         - *
    89         - *  Parameters:
    90         - *      context: [in/out]
    91         - *          The context to reset.
    92         - *
    93         - *  Returns:
    94         - *      sha Error Code.
    95         - *
    96         - */
    97         -static int SHA1Reset(SHA1Context *context)
           66  +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
    98     67   {
    99         -    context->Length_Low             = 0;
   100         -    context->Length_High            = 0;
   101         -    context->Message_Block_Index    = 0;
   102         -
   103         -    context->Intermediate_Hash[0]   = 0x67452301;
   104         -    context->Intermediate_Hash[1]   = 0xEFCDAB89;
   105         -    context->Intermediate_Hash[2]   = 0x98BADCFE;
   106         -    context->Intermediate_Hash[3]   = 0x10325476;
   107         -    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
   108         -
   109         -    context->Computed   = 0;
   110         -    context->Corrupted  = 0;
   111         -
   112         -    return shaSuccess;
   113         -}
   114         -
   115         -/*
   116         - *  SHA1Result
   117         - *
   118         - *  Description:
   119         - *      This function will return the 160-bit message digest into the
   120         - *      Message_Digest array  provided by the caller.
   121         - *      NOTE: The first octet of hash is stored in the 0th element,
   122         - *            the last octet of hash in the 19th element.
   123         - *
   124         - *  Parameters:
   125         - *      context: [in/out]
   126         - *          The context to use to calculate the SHA-1 hash.
   127         - *      Message_Digest: [out]
   128         - *          Where the digest is returned.
   129         - *
   130         - *  Returns:
   131         - *      sha Error Code.
   132         - *
           68  +  unsigned int a, b, c, d, e;
           69  +  CHAR64LONG16 *block;
           70  +  static int one = 1;
           71  +  CHAR64LONG16 workspace;
           72  +
           73  +  block = &workspace;
           74  +  (void)memcpy(block, buffer, 64);
           75  +
           76  +  /* Copy context->state[] to working vars */
           77  +  a = state[0];
           78  +  b = state[1];
           79  +  c = state[2];
           80  +  d = state[3];
           81  +  e = state[4];
           82  +
           83  +  /* 4 rounds of 20 operations each. Loop unrolled. */
           84  +  if( 1 == *(unsigned char*)&one ){
           85  +    Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3);
           86  +    Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7);
           87  +    Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11);
           88  +    Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15);
           89  +  }else{
           90  +    Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3);
           91  +    Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7);
           92  +    Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11);
           93  +    Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15);
           94  +  }
           95  +  R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
           96  +  R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
           97  +  R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
           98  +  R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
           99  +  R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
          100  +  R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
          101  +  R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
          102  +  R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
          103  +  R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
          104  +  R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
          105  +  R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
          106  +  R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
          107  +  R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
          108  +  R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
          109  +  R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
          110  +  R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
          111  +
          112  +  /* Add the working vars back into context.state[] */
          113  +  state[0] += a;
          114  +  state[1] += b;
          115  +  state[2] += c;
          116  +  state[3] += d;
          117  +  state[4] += e;
          118  +
          119  +  /* Wipe variables */
          120  +  a = b = c = d = e = 0;
          121  +}
          122  +
          123  +
          124  +/*
          125  + * SHA1Init - Initialize new context
   133    126    */
   134         -static int SHA1Result( SHA1Context *context,
   135         -                uint8_t Message_Digest[SHA1HashSize])
   136         -{
   137         -    int i;
   138         -
   139         -    if (context->Corrupted)
   140         -    {
   141         -        return context->Corrupted;
   142         -    }
   143         -
   144         -    if (!context->Computed)
   145         -    {
   146         -        SHA1PadMessage(context);
   147         -        for(i=0; i<64; ++i)
   148         -        {
   149         -            /* message may be sensitive, clear it out */
   150         -            context->Message_Block[i] = 0;
   151         -        }
   152         -        context->Length_Low = 0;    /* and clear length */
   153         -        context->Length_High = 0;
   154         -        context->Computed = 1;
   155         -
   156         -    }
   157         -
   158         -    for(i = 0; i < SHA1HashSize; ++i)
   159         -    {
   160         -        Message_Digest[i] = context->Intermediate_Hash[i>>2]
   161         -                            >> 8 * ( 3 - ( i & 0x03 ) );
   162         -    }
   163         -
   164         -    return shaSuccess;
          127  +static void SHA1Init(SHA1Context *context){
          128  +    /* SHA1 initialization constants */
          129  +    context->state[0] = 0x67452301;
          130  +    context->state[1] = 0xEFCDAB89;
          131  +    context->state[2] = 0x98BADCFE;
          132  +    context->state[3] = 0x10325476;
          133  +    context->state[4] = 0xC3D2E1F0;
          134  +    context->count[0] = context->count[1] = 0;
   165    135   }
          136  +
   166    137   
   167    138   /*
   168         - *  SHA1Input
   169         - *
   170         - *  Description:
   171         - *      This function accepts an array of octets as the next portion
   172         - *      of the message.
   173         - *
   174         - *  Parameters:
   175         - *      context: [in/out]
   176         - *          The SHA context to update
   177         - *      message_array: [in]
   178         - *          An array of characters representing the next portion of
   179         - *          the message.
   180         - *      length: [in]
   181         - *          The length of the message in message_array
   182         - *
   183         - *  Returns:
   184         - *      sha Error Code.
   185         - *
          139  + * Run your data through this.
   186    140    */
   187         -static
   188         -int SHA1Input(    SHA1Context    *context,
   189         -                  const uint8_t  *message_array,
   190         -                  unsigned       length)
   191         -{
   192         -    if (!length)
   193         -    {
   194         -        return shaSuccess;
          141  +static void SHA1Update(
          142  +  SHA1Context *context,
          143  +  const unsigned char *data,
          144  +  unsigned int len
          145  +){
          146  +    unsigned int i, j;
          147  +
          148  +    j = context->count[0];
          149  +    if ((context->count[0] += len << 3) < j)
          150  +	context->count[1] += (len>>29)+1;
          151  +    j = (j >> 3) & 63;
          152  +    if ((j + len) > 63) {
          153  +	(void)memcpy(&context->buffer[j], data, (i = 64-j));
          154  +	SHA1Transform(context->state, context->buffer);
          155  +	for ( ; i + 63 < len; i += 64)
          156  +	    SHA1Transform(context->state, &data[i]);
          157  +	j = 0;
          158  +    } else {
          159  +	i = 0;
   195    160       }
   196         -
   197         -    if (context->Computed)
   198         -    {
   199         -        context->Corrupted = shaStateError;
   200         -
   201         -        return shaStateError;
   202         -    }
   203         -
   204         -    if (context->Corrupted)
   205         -    {
   206         -         return context->Corrupted;
   207         -    }
   208         -    while(length-- && !context->Corrupted)
   209         -    {
   210         -    context->Message_Block[context->Message_Block_Index++] =
   211         -                    (*message_array & 0xFF);
   212         -
   213         -    context->Length_Low += 8;
   214         -    if (context->Length_Low == 0)
   215         -    {
   216         -        context->Length_High++;
   217         -        if (context->Length_High == 0)
   218         -        {
   219         -            /* Message is too long */
   220         -            context->Corrupted = 1;
   221         -        }
   222         -    }
   223         -
   224         -    if (context->Message_Block_Index == 64)
   225         -    {
   226         -        SHA1ProcessMessageBlock(context);
   227         -    }
   228         -
   229         -    message_array++;
   230         -    }
   231         -
   232         -    return shaSuccess;
          161  +    (void)memcpy(&context->buffer[j], &data[i], len - i);
   233    162   }
   234    163   
   235         -/*
   236         - *  SHA1ProcessMessageBlock
   237         - *
   238         - *  Description:
   239         - *      This function will process the next 512 bits of the message
   240         - *      stored in the Message_Block array.
   241         - *
   242         - *  Parameters:
   243         - *      None.
   244         - *
   245         - *  Returns:
   246         - *      Nothing.
   247         - *
   248         - *  Comments:
   249         - *      Many of the variable names in this code, especially the
   250         - *      single character names, were used because those were the
   251         - *      names used in the publication.
   252         - *
   253         - *
   254         - */
   255         -static void SHA1ProcessMessageBlock(SHA1Context *context)
   256         -{
   257         -    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
   258         -                            0x5A827999,
   259         -                            0x6ED9EBA1,
   260         -                            0x8F1BBCDC,
   261         -                            0xCA62C1D6
   262         -                            };
   263         -    int           t;                 /* Loop counter                */
   264         -    uint32_t      temp;              /* Temporary word value        */
   265         -    uint32_t      W[80];             /* Word sequence               */
   266         -    uint32_t      A, B, C, D, E;     /* Word buffers                */
   267         -
   268         -    /*
   269         -     *  Initialize the first 16 words in the array W
   270         -     */
   271         -    for(t = 0; t < 16; t++)
   272         -    {
   273         -        W[t] = context->Message_Block[t * 4] << 24;
   274         -        W[t] |= context->Message_Block[t * 4 + 1] << 16;
   275         -        W[t] |= context->Message_Block[t * 4 + 2] << 8;
   276         -        W[t] |= context->Message_Block[t * 4 + 3];
   277         -    }
   278         -
   279         -    for(t = 16; t < 80; t++)
   280         -    {
   281         -       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
   282         -    }
   283         -
   284         -    A = context->Intermediate_Hash[0];
   285         -    B = context->Intermediate_Hash[1];
   286         -    C = context->Intermediate_Hash[2];
   287         -    D = context->Intermediate_Hash[3];
   288         -    E = context->Intermediate_Hash[4];
   289         -
   290         -    for(t = 0; t < 20; t++)
   291         -    {
   292         -        temp =  SHA1CircularShift(5,A) +
   293         -                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
   294         -        E = D;
   295         -        D = C;
   296         -        C = SHA1CircularShift(30,B);
   297         -
   298         -        B = A;
   299         -        A = temp;
   300         -    }
   301         -
   302         -    for(t = 20; t < 40; t++)
   303         -    {
   304         -        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
   305         -        E = D;
   306         -        D = C;
   307         -        C = SHA1CircularShift(30,B);
   308         -        B = A;
   309         -        A = temp;
   310         -    }
   311         -
   312         -    for(t = 40; t < 60; t++)
   313         -    {
   314         -        temp = SHA1CircularShift(5,A) +
   315         -               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
   316         -        E = D;
   317         -        D = C;
   318         -        C = SHA1CircularShift(30,B);
   319         -        B = A;
   320         -        A = temp;
   321         -    }
   322         -
   323         -    for(t = 60; t < 80; t++)
   324         -    {
   325         -        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
   326         -        E = D;
   327         -        D = C;
   328         -        C = SHA1CircularShift(30,B);
   329         -        B = A;
   330         -        A = temp;
   331         -    }
   332         -
   333         -    context->Intermediate_Hash[0] += A;
   334         -    context->Intermediate_Hash[1] += B;
   335         -    context->Intermediate_Hash[2] += C;
   336         -    context->Intermediate_Hash[3] += D;
   337         -    context->Intermediate_Hash[4] += E;
   338         -
   339         -    context->Message_Block_Index = 0;
   340         -}
   341    164   
   342    165   /*
   343         - *  SHA1PadMessage
   344         - *
   345         -
   346         - *  Description:
   347         - *      According to the standard, the message must be padded to an even
   348         - *      512 bits.  The first padding bit must be a '1'.  The last 64
   349         - *      bits represent the length of the original message.  All bits in
   350         - *      between should be 0.  This function will pad the message
   351         - *      according to those rules by filling the Message_Block array
   352         - *      accordingly.  It will also call the ProcessMessageBlock function
   353         - *      provided appropriately.  When it returns, it can be assumed that
   354         - *      the message digest has been computed.
   355         - *
   356         - *  Parameters:
   357         - *      context: [in/out]
   358         - *          The context to pad
   359         - *      ProcessMessageBlock: [in]
   360         - *          The appropriate SHA*ProcessMessageBlock function
   361         - *  Returns:
   362         - *      Nothing.
   363         - *
          166  + * Add padding and return the message digest.
   364    167    */
   365         -static void SHA1PadMessage(SHA1Context *context)
   366         -{
   367         -    /*
   368         -     *  Check to see if the current message block is too small to hold
   369         -     *  the initial padding bits and length.  If so, we will pad the
   370         -     *  block, process it, and then continue padding into a second
   371         -     *  block.
   372         -     */
   373         -    if (context->Message_Block_Index > 55)
   374         -    {
   375         -        context->Message_Block[context->Message_Block_Index++] = 0x80;
   376         -        while(context->Message_Block_Index < 64)
   377         -        {
   378         -            context->Message_Block[context->Message_Block_Index++] = 0;
   379         -        }
          168  +static void SHA1Final(SHA1Context *context, unsigned char digest[20]){
          169  +    unsigned int i;
          170  +    unsigned char finalcount[8];
   380    171   
   381         -        SHA1ProcessMessageBlock(context);
   382         -
   383         -        while(context->Message_Block_Index < 56)
   384         -        {
   385         -            context->Message_Block[context->Message_Block_Index++] = 0;
   386         -        }
          172  +    for (i = 0; i < 8; i++) {
          173  +	finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
          174  +	 >> ((3-(i & 3)) * 8) ) & 255);	 /* Endian independent */
   387    175       }
   388         -    else
   389         -    {
   390         -        context->Message_Block[context->Message_Block_Index++] = 0x80;
   391         -        while(context->Message_Block_Index < 56)
   392         -        {
          176  +    SHA1Update(context, (const unsigned char *)"\200", 1);
          177  +    while ((context->count[0] & 504) != 448)
          178  +	SHA1Update(context, (const unsigned char *)"\0", 1);
          179  +    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
   393    180   
   394         -            context->Message_Block[context->Message_Block_Index++] = 0;
   395         -        }
          181  +    if (digest) {
          182  +	for (i = 0; i < 20; i++)
          183  +	    digest[i] = (unsigned char)
          184  +		((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
   396    185       }
   397         -
   398         -    /*
   399         -     *  Store the message length as the last 8 octets
   400         -     */
   401         -    context->Message_Block[56] = context->Length_High >> 24;
   402         -    context->Message_Block[57] = context->Length_High >> 16;
   403         -    context->Message_Block[58] = context->Length_High >> 8;
   404         -    context->Message_Block[59] = context->Length_High;
   405         -    context->Message_Block[60] = context->Length_Low >> 24;
   406         -    context->Message_Block[61] = context->Length_Low >> 16;
   407         -    context->Message_Block[62] = context->Length_Low >> 8;
   408         -    context->Message_Block[63] = context->Length_Low;
   409         -
   410         -    SHA1ProcessMessageBlock(context);
   411    186   }
   412    187   
   413    188   
   414    189   /*
   415    190   ** Convert a digest into base-16.  digest should be declared as
   416    191   ** "unsigned char digest[20]" in the calling function.  The SHA1
   417    192   ** digest is stored in the first 20 bytes.  zBuf should
................................................................................
   437    212   static int incrInit = 0;
   438    213   
   439    214   /*
   440    215   ** Add more text to the incremental SHA1 checksum.
   441    216   */
   442    217   void sha1sum_step_text(const char *zText, int nBytes){
   443    218     if( !incrInit ){
   444         -    SHA1Reset(&incrCtx);
          219  +    SHA1Init(&incrCtx);
   445    220       incrInit = 1;
   446    221     }
   447    222     if( nBytes<=0 ){
   448    223       if( nBytes==0 ) return;
   449    224       nBytes = strlen(zText);
   450    225     }
   451         -  SHA1Input(&incrCtx, (unsigned char*)zText, nBytes);
          226  +  SHA1Update(&incrCtx, (unsigned char*)zText, nBytes);
   452    227   }
   453    228   
   454    229   /*
   455    230   ** Add the content of a blob to the incremental SHA1 checksum.
   456    231   */
   457    232   void sha1sum_step_blob(Blob *p){
   458    233     sha1sum_step_text(blob_buffer(p), blob_size(p));
................................................................................
   466    241   ** of computation.  The return pointer points to a static buffer that
   467    242   ** is overwritten by subsequent calls to this function.
   468    243   */
   469    244   char *sha1sum_finish(Blob *pOut){
   470    245     unsigned char zResult[20];
   471    246     static char zOut[41];
   472    247     sha1sum_step_text(0,0);
   473         -  SHA1Result(&incrCtx, zResult);
          248  +  SHA1Final(&incrCtx, zResult);
   474    249     incrInit = 0;
   475    250     DigestToBase16(zResult, zOut);
   476    251     if( pOut ){
   477    252       blob_zero(pOut);
   478    253       blob_append(pOut, zOut, 40);
   479    254     }
   480    255     return zOut;
................................................................................
   493    268     unsigned char zResult[20];
   494    269     char zBuf[10240];
   495    270   
   496    271     in = fopen(zFilename,"rb");
   497    272     if( in==0 ){
   498    273       return 1;
   499    274     }
   500         -  SHA1Reset(&ctx);
          275  +  SHA1Init(&ctx);
   501    276     for(;;){
   502    277       int n;
   503    278       n = fread(zBuf, 1, sizeof(zBuf), in);
   504    279       if( n<=0 ) break;
   505         -    SHA1Input(&ctx, (unsigned char*)zBuf, (unsigned)n);
          280  +    SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
   506    281     }
   507    282     fclose(in);
   508    283     blob_zero(pCksum);
   509    284     blob_resize(pCksum, 40);
   510         -  SHA1Result(&ctx, zResult);
          285  +  SHA1Final(&ctx, zResult);
   511    286     DigestToBase16(zResult, blob_buffer(pCksum));
   512    287     return 0;
   513    288   }
   514    289   
   515    290   /*
   516    291   ** Compute the SHA1 checksum of a blob in memory.  Store the resulting
   517    292   ** checksum in the blob pCksum.  pCksum is assumed to be either
................................................................................
   519    294   **
   520    295   ** Return the number of errors.
   521    296   */
   522    297   int sha1sum_blob(const Blob *pIn, Blob *pCksum){
   523    298     SHA1Context ctx;
   524    299     unsigned char zResult[20];
   525    300   
   526         -  SHA1Reset(&ctx);
   527         -  SHA1Input(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn));
          301  +  SHA1Init(&ctx);
          302  +  SHA1Update(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn));
   528    303     if( pIn==pCksum ){
   529    304       blob_reset(pCksum);
   530    305     }else{
   531    306       blob_zero(pCksum);
   532    307     }
   533    308     blob_resize(pCksum, 40);
   534         -  SHA1Result(&ctx, zResult);
          309  +  SHA1Final(&ctx, zResult);
   535    310     DigestToBase16(zResult, blob_buffer(pCksum));
   536    311     return 0;
   537    312   }
   538    313   
   539    314   /*
   540    315   ** Compute the SHA1 checksum of a zero-terminated string.  The
   541    316   ** result is held in memory obtained from mprintf().
   542    317   */
   543    318   char *sha1sum(const char *zIn){
   544    319     SHA1Context ctx;
   545    320     unsigned char zResult[20];
   546    321     char zDigest[41];
   547    322   
   548         -  SHA1Reset(&ctx);
   549         -  SHA1Input(&ctx, (unsigned const char*)zIn, strlen(zIn));
   550         -  SHA1Result(&ctx, zResult);
          323  +  SHA1Init(&ctx);
          324  +  SHA1Update(&ctx, (unsigned const char*)zIn, strlen(zIn));
          325  +  SHA1Final(&ctx, zResult);
   551    326     DigestToBase16(zResult, zDigest);
   552    327     return mprintf("%s", zDigest);
   553    328   }
   554    329   
   555    330   /*
   556    331   ** Convert a cleartext password for a specific user into a SHA1 hash.
   557    332   ** 
................................................................................
   571    346   */
   572    347   char *sha1_shared_secret(const char *zPw, const char *zLogin){
   573    348     static char *zProjectId = 0;
   574    349     SHA1Context ctx;
   575    350     unsigned char zResult[20];
   576    351     char zDigest[41];
   577    352   
   578         -  SHA1Reset(&ctx);
          353  +  SHA1Init(&ctx);
   579    354     if( zProjectId==0 ){
   580    355       zProjectId = db_get("project-code", 0);
   581    356   
   582    357       /* On the first xfer request of a clone, the project-code is not yet
   583    358       ** known.  Use the cleartext password, since that is all we have.
   584    359       */
   585    360       if( zProjectId==0 ){
   586    361         return mprintf("%s", zPw);
   587    362       }
   588    363     }
   589         -  SHA1Input(&ctx, (unsigned char*)zProjectId, strlen(zProjectId));
   590         -  SHA1Input(&ctx, (unsigned char*)"/", 1);
   591         -  SHA1Input(&ctx, (unsigned char*)zLogin, strlen(zLogin));
   592         -  SHA1Input(&ctx, (unsigned char*)"/", 1);
   593         -  SHA1Input(&ctx, (unsigned const char*)zPw, strlen(zPw));
   594         -  SHA1Result(&ctx, zResult);
          364  +  SHA1Update(&ctx, (unsigned char*)zProjectId, strlen(zProjectId));
          365  +  SHA1Update(&ctx, (unsigned char*)"/", 1);
          366  +  SHA1Update(&ctx, (unsigned char*)zLogin, strlen(zLogin));
          367  +  SHA1Update(&ctx, (unsigned char*)"/", 1);
          368  +  SHA1Update(&ctx, (unsigned const char*)zPw, strlen(zPw));
          369  +  SHA1Final(&ctx, zResult);
   595    370     DigestToBase16(zResult, zDigest);
   596    371     return mprintf("%s", zDigest);
   597    372   }
   598    373   
   599    374   /*
   600    375   ** COMMAND: sha1sum
   601    376   ** %fossil sha1sum FILE...

Added src/shell.c.

            1  +/*
            2  +** 2001 September 15
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** This file contains code to implement the "sqlite" command line
           13  +** utility for accessing SQLite databases.
           14  +*/
           15  +#if defined(_WIN32) || defined(WIN32)
           16  +/* This needs to come before any includes for MSVC compiler */
           17  +#define _CRT_SECURE_NO_WARNINGS
           18  +#endif
           19  +
           20  +#include <stdlib.h>
           21  +#include <string.h>
           22  +#include <stdio.h>
           23  +#include <assert.h>
           24  +#include "sqlite3.h"
           25  +#include <ctype.h>
           26  +#include <stdarg.h>
           27  +
           28  +#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
           29  +# include <signal.h>
           30  +# if !defined(__RTP__) && !defined(_WRS_KERNEL)
           31  +#  include <pwd.h>
           32  +# endif
           33  +# include <unistd.h>
           34  +# include <sys/types.h>
           35  +#endif
           36  +
           37  +#ifdef __OS2__
           38  +# include <unistd.h>
           39  +#endif
           40  +
           41  +#if defined(HAVE_READLINE) && HAVE_READLINE==1
           42  +# include <readline/readline.h>
           43  +# include <readline/history.h>
           44  +#else
           45  +# define readline(p) local_getline(p,stdin)
           46  +# define add_history(X)
           47  +# define read_history(X)
           48  +# define write_history(X)
           49  +# define stifle_history(X)
           50  +#endif
           51  +
           52  +#if defined(_WIN32) || defined(WIN32)
           53  +# include <io.h>
           54  +#define isatty(h) _isatty(h)
           55  +#define access(f,m) _access((f),(m))
           56  +#else
           57  +/* Make sure isatty() has a prototype.
           58  +*/
           59  +extern int isatty();
           60  +#endif
           61  +
           62  +#if defined(_WIN32_WCE)
           63  +/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
           64  + * thus we always assume that we have a console. That can be
           65  + * overridden with the -batch command line option.
           66  + */
           67  +#define isatty(x) 1
           68  +#endif
           69  +
           70  +#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
           71  +#include <sys/time.h>
           72  +#include <sys/resource.h>
           73  +
           74  +/* Saved resource information for the beginning of an operation */
           75  +static struct rusage sBegin;
           76  +
           77  +/* True if the timer is enabled */
           78  +static int enableTimer = 0;
           79  +
           80  +/*
           81  +** Begin timing an operation
           82  +*/
           83  +static void beginTimer(void){
           84  +  if( enableTimer ){
           85  +    getrusage(RUSAGE_SELF, &sBegin);
           86  +  }
           87  +}
           88  +
           89  +/* Return the difference of two time_structs in seconds */
           90  +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
           91  +  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + 
           92  +         (double)(pEnd->tv_sec - pStart->tv_sec);
           93  +}
           94  +
           95  +/*
           96  +** Print the timing results.
           97  +*/
           98  +static void endTimer(void){
           99  +  if( enableTimer ){
          100  +    struct rusage sEnd;
          101  +    getrusage(RUSAGE_SELF, &sEnd);
          102  +    printf("CPU Time: user %f sys %f\n",
          103  +       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
          104  +       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
          105  +  }
          106  +}
          107  +
          108  +#define BEGIN_TIMER beginTimer()
          109  +#define END_TIMER endTimer()
          110  +#define HAS_TIMER 1
          111  +
          112  +#elif (defined(_WIN32) || defined(WIN32))
          113  +
          114  +#include <windows.h>
          115  +
          116  +/* Saved resource information for the beginning of an operation */
          117  +static HANDLE hProcess;
          118  +static FILETIME ftKernelBegin;
          119  +static FILETIME ftUserBegin;
          120  +typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
          121  +static GETPROCTIMES getProcessTimesAddr = NULL;
          122  +
          123  +/* True if the timer is enabled */
          124  +static int enableTimer = 0;
          125  +
          126  +/*
          127  +** Check to see if we have timer support.  Return 1 if necessary
          128  +** support found (or found previously).
          129  +*/
          130  +static int hasTimer(void){
          131  +  if( getProcessTimesAddr ){
          132  +    return 1;
          133  +  } else {
          134  +    /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
          135  +    ** See if the version we are running on has it, and if it does, save off
          136  +    ** a pointer to it and the current process handle.
          137  +    */
          138  +    hProcess = GetCurrentProcess();
          139  +    if( hProcess ){
          140  +      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
          141  +      if( NULL != hinstLib ){
          142  +        getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
          143  +        if( NULL != getProcessTimesAddr ){
          144  +          return 1;
          145  +        }
          146  +        FreeLibrary(hinstLib); 
          147  +      }
          148  +    }
          149  +  }
          150  +  return 0;
          151  +}
          152  +
          153  +/*
          154  +** Begin timing an operation
          155  +*/
          156  +static void beginTimer(void){
          157  +  if( enableTimer && getProcessTimesAddr ){
          158  +    FILETIME ftCreation, ftExit;
          159  +    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
          160  +  }
          161  +}
          162  +
          163  +/* Return the difference of two FILETIME structs in seconds */
          164  +static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
          165  +  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
          166  +  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
          167  +  return (double) ((i64End - i64Start) / 10000000.0);
          168  +}
          169  +
          170  +/*
          171  +** Print the timing results.
          172  +*/
          173  +static void endTimer(void){
          174  +  if( enableTimer && getProcessTimesAddr){
          175  +    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
          176  +    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
          177  +    printf("CPU Time: user %f sys %f\n",
          178  +       timeDiff(&ftUserBegin, &ftUserEnd),
          179  +       timeDiff(&ftKernelBegin, &ftKernelEnd));
          180  +  }
          181  +}
          182  +
          183  +#define BEGIN_TIMER beginTimer()
          184  +#define END_TIMER endTimer()
          185  +#define HAS_TIMER hasTimer()
          186  +
          187  +#else
          188  +#define BEGIN_TIMER 
          189  +#define END_TIMER
          190  +#define HAS_TIMER 0
          191  +#endif
          192  +
          193  +/*
          194  +** Used to prevent warnings about unused parameters
          195  +*/
          196  +#define UNUSED_PARAMETER(x) (void)(x)
          197  +
          198  +/*
          199  +** If the following flag is set, then command execution stops
          200  +** at an error if we are not interactive.
          201  +*/
          202  +static int bail_on_error = 0;
          203  +
          204  +/*
          205  +** Threat stdin as an interactive input if the following variable
          206  +** is true.  Otherwise, assume stdin is connected to a file or pipe.
          207  +*/
          208  +static int stdin_is_interactive = 1;
          209  +
          210  +/*
          211  +** The following is the open SQLite database.  We make a pointer
          212  +** to this database a static variable so that it can be accessed
          213  +** by the SIGINT handler to interrupt database processing.
          214  +*/
          215  +static sqlite3 *db = 0;
          216  +
          217  +/*
          218  +** True if an interrupt (Control-C) has been received.
          219  +*/
          220  +static volatile int seenInterrupt = 0;
          221  +
          222  +/*
          223  +** This is the name of our program. It is set in main(), used
          224  +** in a number of other places, mostly for error messages.
          225  +*/
          226  +static char *Argv0;
          227  +
          228  +/*
          229  +** Prompt strings. Initialized in main. Settable with
          230  +**   .prompt main continue
          231  +*/
          232  +static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
          233  +static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
          234  +
          235  +/*
          236  +** Write I/O traces to the following stream.
          237  +*/
          238  +#ifdef SQLITE_ENABLE_IOTRACE
          239  +static FILE *iotrace = 0;
          240  +#endif
          241  +
          242  +/*
          243  +** This routine works like printf in that its first argument is a
          244  +** format string and subsequent arguments are values to be substituted
          245  +** in place of % fields.  The result of formatting this string
          246  +** is written to iotrace.
          247  +*/
          248  +#ifdef SQLITE_ENABLE_IOTRACE
          249  +static void iotracePrintf(const char *zFormat, ...){
          250  +  va_list ap;
          251  +  char *z;
          252  +  if( iotrace==0 ) return;
          253  +  va_start(ap, zFormat);
          254  +  z = sqlite3_vmprintf(zFormat, ap);
          255  +  va_end(ap);
          256  +  fprintf(iotrace, "%s", z);
          257  +  sqlite3_free(z);
          258  +}
          259  +#endif
          260  +
          261  +
          262  +/*
          263  +** Determines if a string is a number of not.
          264  +*/
          265  +static int isNumber(const char *z, int *realnum){
          266  +  if( *z=='-' || *z=='+' ) z++;
          267  +  if( !isdigit(*z) ){
          268  +    return 0;
          269  +  }
          270  +  z++;
          271  +  if( realnum ) *realnum = 0;
          272  +  while( isdigit(*z) ){ z++; }
          273  +  if( *z=='.' ){
          274  +    z++;
          275  +    if( !isdigit(*z) ) return 0;
          276  +    while( isdigit(*z) ){ z++; }
          277  +    if( realnum ) *realnum = 1;
          278  +  }
          279  +  if( *z=='e' || *z=='E' ){
          280  +    z++;
          281  +    if( *z=='+' || *z=='-' ) z++;
          282  +    if( !isdigit(*z) ) return 0;
          283  +    while( isdigit(*z) ){ z++; }
          284  +    if( realnum ) *realnum = 1;
          285  +  }
          286  +  return *z==0;
          287  +}
          288  +
          289  +/*
          290  +** A global char* and an SQL function to access its current value 
          291  +** from within an SQL statement. This program used to use the 
          292  +** sqlite_exec_printf() API to substitue a string into an SQL statement.
          293  +** The correct way to do this with sqlite3 is to use the bind API, but
          294  +** since the shell is built around the callback paradigm it would be a lot
          295  +** of work. Instead just use this hack, which is quite harmless.
          296  +*/
          297  +static const char *zShellStatic = 0;
          298  +static void shellstaticFunc(
          299  +  sqlite3_context *context,
          300  +  int argc,
          301  +  sqlite3_value **argv
          302  +){
          303  +  assert( 0==argc );
          304  +  assert( zShellStatic );
          305  +  UNUSED_PARAMETER(argc);
          306  +  UNUSED_PARAMETER(argv);
          307  +  sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
          308  +}
          309  +
          310  +
          311  +/*
          312  +** This routine reads a line of text from FILE in, stores
          313  +** the text in memory obtained from malloc() and returns a pointer
          314  +** to the text.  NULL is returned at end of file, or if malloc()
          315  +** fails.
          316  +**
          317  +** The interface is like "readline" but no command-line editing
          318  +** is done.
          319  +*/
          320  +static char *local_getline(char *zPrompt, FILE *in){
          321  +  char *zLine;
          322  +  int nLine;
          323  +  int n;
          324  +  int eol;
          325  +
          326  +  if( zPrompt && *zPrompt ){
          327  +    printf("%s",zPrompt);
          328  +    fflush(stdout);
          329  +  }
          330  +  nLine = 100;
          331  +  zLine = malloc( nLine );
          332  +  if( zLine==0 ) return 0;
          333  +  n = 0;
          334  +  eol = 0;
          335  +  while( !eol ){
          336  +    if( n+100>nLine ){
          337  +      nLine = nLine*2 + 100;
          338  +      zLine = realloc(zLine, nLine);
          339  +      if( zLine==0 ) return 0;
          340  +    }
          341  +    if( fgets(&zLine[n], nLine - n, in)==0 ){
          342  +      if( n==0 ){
          343  +        free(zLine);
          344  +        return 0;
          345  +      }
          346  +      zLine[n] = 0;
          347  +      eol = 1;
          348  +      break;
          349  +    }
          350  +    while( zLine[n] ){ n++; }
          351  +    if( n>0 && zLine[n-1]=='\n' ){
          352  +      n--;
          353  +      if( n>0 && zLine[n-1]=='\r' ) n--;
          354  +      zLine[n] = 0;
          355  +      eol = 1;
          356  +    }
          357  +  }
          358  +  zLine = realloc( zLine, n+1 );
          359  +  return zLine;
          360  +}
          361  +
          362  +/*
          363  +** Retrieve a single line of input text.
          364  +**
          365  +** zPrior is a string of prior text retrieved.  If not the empty
          366  +** string, then issue a continuation prompt.
          367  +*/
          368  +static char *one_input_line(const char *zPrior, FILE *in){
          369  +  char *zPrompt;
          370  +  char *zResult;
          371  +  if( in!=0 ){
          372  +    return local_getline(0, in);
          373  +  }
          374  +  if( zPrior && zPrior[0] ){
          375  +    zPrompt = continuePrompt;
          376  +  }else{
          377  +    zPrompt = mainPrompt;
          378  +  }
          379  +  zResult = readline(zPrompt);
          380  +#if defined(HAVE_READLINE) && HAVE_READLINE==1
          381  +  if( zResult && *zResult ) add_history(zResult);
          382  +#endif
          383  +  return zResult;
          384  +}
          385  +
          386  +struct previous_mode_data {
          387  +  int valid;        /* Is there legit data in here? */
          388  +  int mode;
          389  +  int showHeader;
          390  +  int colWidth[100];
          391  +};
          392  +
          393  +/*
          394  +** An pointer to an instance of this structure is passed from
          395  +** the main program to the callback.  This is used to communicate
          396  +** state and mode information.
          397  +*/
          398  +struct callback_data {
          399  +  sqlite3 *db;           /* The database */
          400  +  int echoOn;            /* True to echo input commands */
          401  +  int statsOn;           /* True to display memory stats before each finalize */
          402  +  int cnt;               /* Number of records displayed so far */
          403  +  FILE *out;             /* Write results here */
          404  +  int mode;              /* An output mode setting */
          405  +  int writableSchema;    /* True if PRAGMA writable_schema=ON */
          406  +  int showHeader;        /* True to show column names in List or Column mode */
          407  +  char *zDestTable;      /* Name of destination table when MODE_Insert */
          408  +  char separator[20];    /* Separator character for MODE_List */
          409  +  int colWidth[100];     /* Requested width of each column when in column mode*/
          410  +  int actualWidth[100];  /* Actual width of each column */
          411  +  char nullvalue[20];    /* The text to print when a NULL comes back from
          412  +                         ** the database */
          413  +  struct previous_mode_data explainPrev;
          414  +                         /* Holds the mode information just before
          415  +                         ** .explain ON */
          416  +  char outfile[FILENAME_MAX]; /* Filename for *out */
          417  +  const char *zDbFilename;    /* name of the database file */
          418  +  sqlite3_stmt *pStmt;   /* Current statement if any. */
          419  +  FILE *pLog;            /* Write log output here */
          420  +};
          421  +
          422  +/*
          423  +** These are the allowed modes.
          424  +*/
          425  +#define MODE_Line     0  /* One column per line.  Blank line between records */
          426  +#define MODE_Column   1  /* One record per line in neat columns */
          427  +#define MODE_List     2  /* One record per line with a separator */
          428  +#define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
          429  +#define MODE_Html     4  /* Generate an XHTML table */
          430  +#define MODE_Insert   5  /* Generate SQL "insert" statements */
          431  +#define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
          432  +#define MODE_Csv      7  /* Quote strings, numbers are plain */
          433  +#define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
          434  +
          435  +static const char *modeDescr[] = {
          436  +  "line",
          437  +  "column",
          438  +  "list",
          439  +  "semi",
          440  +  "html",
          441  +  "insert",
          442  +  "tcl",
          443  +  "csv",
          444  +  "explain",
          445  +};
          446  +
          447  +/*
          448  +** Number of elements in an array
          449  +*/
          450  +#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
          451  +
          452  +/*
          453  +** Compute a string length that is limited to what can be stored in
          454  +** lower 30 bits of a 32-bit signed integer.
          455  +*/
          456  +static int strlen30(const char *z){
          457  +  const char *z2 = z;
          458  +  while( *z2 ){ z2++; }
          459  +  return 0x3fffffff & (int)(z2 - z);
          460  +}
          461  +
          462  +/*
          463  +** A callback for the sqlite3_log() interface.
          464  +*/
          465  +static void shellLog(void *pArg, int iErrCode, const char *zMsg){
          466  +  struct callback_data *p = (struct callback_data*)pArg;
          467  +  if( p->pLog==0 ) return;
          468  +  fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
          469  +  fflush(p->pLog);
          470  +}
          471  +
          472  +/*
          473  +** Output the given string as a hex-encoded blob (eg. X'1234' )
          474  +*/
          475  +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
          476  +  int i;
          477  +  char *zBlob = (char *)pBlob;
          478  +  fprintf(out,"X'");
          479  +  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
          480  +  fprintf(out,"'");
          481  +}
          482  +
          483  +/*
          484  +** Output the given string as a quoted string using SQL quoting conventions.
          485  +*/
          486  +static void output_quoted_string(FILE *out, const char *z){
          487  +  int i;
          488  +  int nSingle = 0;
          489  +  for(i=0; z[i]; i++){
          490  +    if( z[i]=='\'' ) nSingle++;
          491  +  }
          492  +  if( nSingle==0 ){
          493  +    fprintf(out,"'%s'",z);
          494  +  }else{
          495  +    fprintf(out,"'");
          496  +    while( *z ){
          497  +      for(i=0; z[i] && z[i]!='\''; i++){}
          498  +      if( i==0 ){
          499  +        fprintf(out,"''");
          500  +        z++;
          501  +      }else if( z[i]=='\'' ){
          502  +        fprintf(out,"%.*s''",i,z);
          503  +        z += i+1;
          504  +      }else{
          505  +        fprintf(out,"%s",z);
          506  +        break;
          507  +      }
          508  +    }
          509  +    fprintf(out,"'");
          510  +  }
          511  +}
          512  +
          513  +/*
          514  +** Output the given string as a quoted according to C or TCL quoting rules.
          515  +*/
          516  +static void output_c_string(FILE *out, const char *z){
          517  +  unsigned int c;
          518  +  fputc('"', out);
          519  +  while( (c = *(z++))!=0 ){
          520  +    if( c=='\\' ){
          521  +      fputc(c, out);
          522  +      fputc(c, out);
          523  +    }else if( c=='\t' ){
          524  +      fputc('\\', out);
          525  +      fputc('t', out);
          526  +    }else if( c=='\n' ){
          527  +      fputc('\\', out);
          528  +      fputc('n', out);
          529  +    }else if( c=='\r' ){
          530  +      fputc('\\', out);
          531  +      fputc('r', out);
          532  +    }else if( !isprint(c) ){
          533  +      fprintf(out, "\\%03o", c&0xff);
          534  +    }else{
          535  +      fputc(c, out);
          536  +    }
          537  +  }
          538  +  fputc('"', out);
          539  +}
          540  +
          541  +/*
          542  +** Output the given string with characters that are special to
          543  +** HTML escaped.
          544  +*/
          545  +static void output_html_string(FILE *out, const char *z){
          546  +  int i;
          547  +  while( *z ){
          548  +    for(i=0;   z[i] 
          549  +            && z[i]!='<' 
          550  +            && z[i]!='&' 
          551  +            && z[i]!='>' 
          552  +            && z[i]!='\"' 
          553  +            && z[i]!='\'';
          554  +        i++){}
          555  +    if( i>0 ){
          556  +      fprintf(out,"%.*s",i,z);
          557  +    }
          558  +    if( z[i]=='<' ){
          559  +      fprintf(out,"&lt;");
          560  +    }else if( z[i]=='&' ){
          561  +      fprintf(out,"&amp;");
          562  +    }else if( z[i]=='>' ){
          563  +      fprintf(out,"&gt;");
          564  +    }else if( z[i]=='\"' ){
          565  +      fprintf(out,"&quot;");
          566  +    }else if( z[i]=='\'' ){
          567  +      fprintf(out,"&#39;");
          568  +    }else{
          569  +      break;
          570  +    }
          571  +    z += i + 1;
          572  +  }
          573  +}
          574  +
          575  +/*
          576  +** If a field contains any character identified by a 1 in the following
          577  +** array, then the string must be quoted for CSV.
          578  +*/
          579  +static const char needCsvQuote[] = {
          580  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          581  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          582  +  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0, 
          583  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
          584  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
          585  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
          586  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
          587  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1, 
          588  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          589  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          590  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          591  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          592  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          593  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          594  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          595  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
          596  +};
          597  +
          598  +/*
          599  +** Output a single term of CSV.  Actually, p->separator is used for
          600  +** the separator, which may or may not be a comma.  p->nullvalue is
          601  +** the null value.  Strings are quoted using ANSI-C rules.  Numbers
          602  +** appear outside of quotes.
          603  +*/
          604  +static void output_csv(struct callback_data *p, const char *z, int bSep){
          605  +  FILE *out = p->out;
          606  +  if( z==0 ){
          607  +    fprintf(out,"%s",p->nullvalue);
          608  +  }else{
          609  +    int i;
          610  +    int nSep = strlen30(p->separator);
          611  +    for(i=0; z[i]; i++){
          612  +      if( needCsvQuote[((unsigned char*)z)[i]] 
          613  +         || (z[i]==p->separator[0] && 
          614  +             (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
          615  +        i = 0;
          616  +        break;
          617  +      }
          618  +    }
          619  +    if( i==0 ){
          620  +      putc('"', out);
          621  +      for(i=0; z[i]; i++){
          622  +        if( z[i]=='"' ) putc('"', out);
          623  +        putc(z[i], out);
          624  +      }
          625  +      putc('"', out);
          626  +    }else{
          627  +      fprintf(out, "%s", z);
          628  +    }
          629  +  }
          630  +  if( bSep ){
          631  +    fprintf(p->out, "%s", p->separator);
          632  +  }
          633  +}
          634  +
          635  +#ifdef SIGINT
          636  +/*
          637  +** This routine runs when the user presses Ctrl-C
          638  +*/
          639  +static void interrupt_handler(int NotUsed){
          640  +  UNUSED_PARAMETER(NotUsed);
          641  +  seenInterrupt = 1;
          642  +  if( db ) sqlite3_interrupt(db);
          643  +}
          644  +#endif
          645  +
          646  +/*
          647  +** This is the callback routine that the shell
          648  +** invokes for each row of a query result.
          649  +*/
          650  +static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
          651  +  int i;
          652  +  struct callback_data *p = (struct callback_data*)pArg;
          653  +
          654  +  switch( p->mode ){
          655  +    case MODE_Line: {
          656  +      int w = 5;
          657  +      if( azArg==0 ) break;
          658  +      for(i=0; i<nArg; i++){
          659  +        int len = strlen30(azCol[i] ? azCol[i] : "");
          660  +        if( len>w ) w = len;
          661  +      }
          662  +      if( p->cnt++>0 ) fprintf(p->out,"\n");
          663  +      for(i=0; i<nArg; i++){
          664  +        fprintf(p->out,"%*s = %s\n", w, azCol[i],
          665  +                azArg[i] ? azArg[i] : p->nullvalue);
          666  +      }
          667  +      break;
          668  +    }
          669  +    case MODE_Explain:
          670  +    case MODE_Column: {
          671  +      if( p->cnt++==0 ){
          672  +        for(i=0; i<nArg; i++){
          673  +          int w, n;
          674  +          if( i<ArraySize(p->colWidth) ){
          675  +            w = p->colWidth[i];
          676  +          }else{
          677  +            w = 0;
          678  +          }
          679  +          if( w<=0 ){
          680  +            w = strlen30(azCol[i] ? azCol[i] : "");
          681  +            if( w<10 ) w = 10;
          682  +            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
          683  +            if( w<n ) w = n;
          684  +          }
          685  +          if( i<ArraySize(p->actualWidth) ){
          686  +            p->actualWidth[i] = w;
          687  +          }
          688  +          if( p->showHeader ){
          689  +            fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
          690  +          }
          691  +        }
          692  +        if( p->showHeader ){
          693  +          for(i=0; i<nArg; i++){
          694  +            int w;
          695  +            if( i<ArraySize(p->actualWidth) ){
          696  +               w = p->actualWidth[i];
          697  +            }else{
          698  +               w = 10;
          699  +            }
          700  +            fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
          701  +                   "----------------------------------------------------------",
          702  +                    i==nArg-1 ? "\n": "  ");
          703  +          }
          704  +        }
          705  +      }
          706  +      if( azArg==0 ) break;
          707  +      for(i=0; i<nArg; i++){
          708  +        int w;
          709  +        if( i<ArraySize(p->actualWidth) ){
          710  +           w = p->actualWidth[i];
          711  +        }else{
          712  +           w = 10;
          713  +        }
          714  +        if( p->mode==MODE_Explain && azArg[i] && 
          715  +           strlen30(azArg[i])>w ){
          716  +          w = strlen30(azArg[i]);
          717  +        }
          718  +        fprintf(p->out,"%-*.*s%s",w,w,
          719  +            azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
          720  +      }
          721  +      break;
          722  +    }
          723  +    case MODE_Semi:
          724  +    case MODE_List: {
          725  +      if( p->cnt++==0 && p->showHeader ){
          726  +        for(i=0; i<nArg; i++){
          727  +          fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
          728  +        }
          729  +      }
          730  +      if( azArg==0 ) break;
          731  +      for(i=0; i<nArg; i++){
          732  +        char *z = azArg[i];
          733  +        if( z==0 ) z = p->nullvalue;
          734  +        fprintf(p->out, "%s", z);
          735  +        if( i<nArg-1 ){
          736  +          fprintf(p->out, "%s", p->separator);
          737  +        }else if( p->mode==MODE_Semi ){
          738  +          fprintf(p->out, ";\n");
          739  +        }else{
          740  +          fprintf(p->out, "\n");
          741  +        }
          742  +      }
          743  +      break;
          744  +    }
          745  +    case MODE_Html: {
          746  +      if( p->cnt++==0 && p->showHeader ){
          747  +        fprintf(p->out,"<TR>");
          748  +        for(i=0; i<nArg; i++){
          749  +          fprintf(p->out,"<TH>");
          750  +          output_html_string(p->out, azCol[i]);
          751  +          fprintf(p->out,"</TH>\n");
          752  +        }
          753  +        fprintf(p->out,"</TR>\n");
          754  +      }
          755  +      if( azArg==0 ) break;
          756  +      fprintf(p->out,"<TR>");
          757  +      for(i=0; i<nArg; i++){
          758  +        fprintf(p->out,"<TD>");
          759  +        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
          760  +        fprintf(p->out,"</TD>\n");
          761  +      }
          762  +      fprintf(p->out,"</TR>\n");
          763  +      break;
          764  +    }
          765  +    case MODE_Tcl: {
          766  +      if( p->cnt++==0 && p->showHeader ){
          767  +        for(i=0; i<nArg; i++){
          768  +          output_c_string(p->out,azCol[i] ? azCol[i] : "");
          769  +          fprintf(p->out, "%s", p->separator);
          770  +        }
          771  +        fprintf(p->out,"\n");
          772  +      }
          773  +      if( azArg==0 ) break;
          774  +      for(i=0; i<nArg; i++){
          775  +        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
          776  +        fprintf(p->out, "%s", p->separator);
          777  +      }
          778  +      fprintf(p->out,"\n");
          779  +      break;
          780  +    }
          781  +    case MODE_Csv: {
          782  +      if( p->cnt++==0 && p->showHeader ){
          783  +        for(i=0; i<nArg; i++){
          784  +          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
          785  +        }
          786  +        fprintf(p->out,"\n");
          787  +      }
          788  +      if( azArg==0 ) break;
          789  +      for(i=0; i<nArg; i++){
          790  +        output_csv(p, azArg[i], i<nArg-1);
          791  +      }
          792  +      fprintf(p->out,"\n");
          793  +      break;
          794  +    }
          795  +    case MODE_Insert: {
          796  +      p->cnt++;
          797  +      if( azArg==0 ) break;
          798  +      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
          799  +      for(i=0; i<nArg; i++){
          800  +        char *zSep = i>0 ? ",": "";
          801  +        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
          802  +          fprintf(p->out,"%sNULL",zSep);
          803  +        }else if( aiType && aiType[i]==SQLITE_TEXT ){
          804  +          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          805  +          output_quoted_string(p->out, azArg[i]);
          806  +        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
          807  +          fprintf(p->out,"%s%s",zSep, azArg[i]);
          808  +        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
          809  +          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
          810  +          int nBlob = sqlite3_column_bytes(p->pStmt, i);
          811  +          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          812  +          output_hex_blob(p->out, pBlob, nBlob);
          813  +        }else if( isNumber(azArg[i], 0) ){
          814  +          fprintf(p->out,"%s%s",zSep, azArg[i]);
          815  +        }else{
          816  +          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          817  +          output_quoted_string(p->out, azArg[i]);
          818  +        }
          819  +      }
          820  +      fprintf(p->out,");\n");
          821  +      break;
          822  +    }
          823  +  }
          824  +  return 0;
          825  +}
          826  +
          827  +/*
          828  +** This is the callback routine that the SQLite library
          829  +** invokes for each row of a query result.
          830  +*/
          831  +static int callback(void *pArg, int nArg, char **azArg, char **azCol){
          832  +  /* since we don't have type info, call the shell_callback with a NULL value */
          833  +  return shell_callback(pArg, nArg, azArg, azCol, NULL);
          834  +}
          835  +
          836  +/*
          837  +** Set the destination table field of the callback_data structure to
          838  +** the name of the table given.  Escape any quote characters in the
          839  +** table name.
          840  +*/
          841  +static void set_table_name(struct callback_data *p, const char *zName){
          842  +  int i, n;
          843  +  int needQuote;
          844  +  char *z;
          845  +
          846  +  if( p->zDestTable ){
          847  +    free(p->zDestTable);
          848  +    p->zDestTable = 0;
          849  +  }
          850  +  if( zName==0 ) return;
          851  +  needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
          852  +  for(i=n=0; zName[i]; i++, n++){
          853  +    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
          854  +      needQuote = 1;
          855  +      if( zName[i]=='\'' ) n++;
          856  +    }
          857  +  }
          858  +  if( needQuote ) n += 2;
          859  +  z = p->zDestTable = malloc( n+1 );
          860  +  if( z==0 ){
          861  +    fprintf(stderr,"Error: out of memory\n");
          862  +    exit(1);
          863  +  }
          864  +  n = 0;
          865  +  if( needQuote ) z[n++] = '\'';
          866  +  for(i=0; zName[i]; i++){
          867  +    z[n++] = zName[i];
          868  +    if( zName[i]=='\'' ) z[n++] = '\'';
          869  +  }
          870  +  if( needQuote ) z[n++] = '\'';
          871  +  z[n] = 0;
          872  +}
          873  +
          874  +/* zIn is either a pointer to a NULL-terminated string in memory obtained
          875  +** from malloc(), or a NULL pointer. The string pointed to by zAppend is
          876  +** added to zIn, and the result returned in memory obtained from malloc().
          877  +** zIn, if it was not NULL, is freed.
          878  +**
          879  +** If the third argument, quote, is not '\0', then it is used as a 
          880  +** quote character for zAppend.
          881  +*/
          882  +static char *appendText(char *zIn, char const *zAppend, char quote){
          883  +  int len;
          884  +  int i;
          885  +  int nAppend = strlen30(zAppend);
          886  +  int nIn = (zIn?strlen30(zIn):0);
          887  +
          888  +  len = nAppend+nIn+1;
          889  +  if( quote ){
          890  +    len += 2;
          891  +    for(i=0; i<nAppend; i++){
          892  +      if( zAppend[i]==quote ) len++;
          893  +    }
          894  +  }
          895  +
          896  +  zIn = (char *)realloc(zIn, len);
          897  +  if( !zIn ){
          898  +    return 0;
          899  +  }
          900  +
          901  +  if( quote ){
          902  +    char *zCsr = &zIn[nIn];
          903  +    *zCsr++ = quote;
          904  +    for(i=0; i<nAppend; i++){
          905  +      *zCsr++ = zAppend[i];
          906  +      if( zAppend[i]==quote ) *zCsr++ = quote;
          907  +    }
          908  +    *zCsr++ = quote;
          909  +    *zCsr++ = '\0';
          910  +    assert( (zCsr-zIn)==len );
          911  +  }else{
          912  +    memcpy(&zIn[nIn], zAppend, nAppend);
          913  +    zIn[len-1] = '\0';
          914  +  }
          915  +
          916  +  return zIn;
          917  +}
          918  +
          919  +
          920  +/*
          921  +** Execute a query statement that has a single result column.  Print
          922  +** that result column on a line by itself with a semicolon terminator.
          923  +**
          924  +** This is used, for example, to show the schema of the database by
          925  +** querying the SQLITE_MASTER table.
          926  +*/
          927  +static int run_table_dump_query(
          928  +  FILE *out,              /* Send output here */
          929  +  sqlite3 *db,            /* Database to query */
          930  +  const char *zSelect,    /* SELECT statement to extract content */
          931  +  const char *zFirstRow   /* Print before first row, if not NULL */
          932  +){
          933  +  sqlite3_stmt *pSelect;
          934  +  int rc;
          935  +  rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
          936  +  if( rc!=SQLITE_OK || !pSelect ){
          937  +    return rc;
          938  +  }
          939  +  rc = sqlite3_step(pSelect);
          940  +  while( rc==SQLITE_ROW ){
          941  +    if( zFirstRow ){
          942  +      fprintf(out, "%s", zFirstRow);
          943  +      zFirstRow = 0;
          944  +    }
          945  +    fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
          946  +    rc = sqlite3_step(pSelect);
          947  +  }
          948  +  return sqlite3_finalize(pSelect);
          949  +}
          950  +
          951  +/*
          952  +** Allocate space and save off current error string.
          953  +*/
          954  +static char *save_err_msg(
          955  +  sqlite3 *db            /* Database to query */
          956  +){
          957  +  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
          958  +  char *zErrMsg = sqlite3_malloc(nErrMsg);
          959  +  if( zErrMsg ){
          960  +    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
          961  +  }
          962  +  return zErrMsg;
          963  +}
          964  +
          965  +/*
          966  +** Display memory stats.
          967  +*/
          968  +static int display_stats(
          969  +  sqlite3 *db,                /* Database to query */
          970  +  struct callback_data *pArg, /* Pointer to struct callback_data */
          971  +  int bReset                  /* True to reset the stats */
          972  +){
          973  +  int iCur;
          974  +  int iHiwtr;
          975  +
          976  +  if( pArg && pArg->out ){
          977  +    
          978  +    iHiwtr = iCur = -1;
          979  +    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
          980  +    fprintf(pArg->out, "Memory Used:                         %d (max %d) bytes\n", iCur, iHiwtr);
          981  +    iHiwtr = iCur = -1;
          982  +    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
          983  +    fprintf(pArg->out, "Number of Allocations:               %d (max %d)\n", iCur, iHiwtr);
          984  +/*
          985  +** Not currently used by the CLI.
          986  +**    iHiwtr = iCur = -1;
          987  +**    sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
          988  +**    fprintf(pArg->out, "Number of Pcache Pages Used:         %d (max %d) pages\n", iCur, iHiwtr);
          989  +*/
          990  +    iHiwtr = iCur = -1;
          991  +    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
          992  +    fprintf(pArg->out, "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n", iCur, iHiwtr);
          993  +/*
          994  +** Not currently used by the CLI.
          995  +**    iHiwtr = iCur = -1;
          996  +**    sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
          997  +**    fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n", iCur, iHiwtr);
          998  +*/
          999  +    iHiwtr = iCur = -1;
         1000  +    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
         1001  +    fprintf(pArg->out, "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n", iCur, iHiwtr);
         1002  +    iHiwtr = iCur = -1;
         1003  +    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
         1004  +    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n", iHiwtr);
         1005  +    iHiwtr = iCur = -1;
         1006  +    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
         1007  +    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n", iHiwtr);
         1008  +    iHiwtr = iCur = -1;
         1009  +    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
         1010  +    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n", iHiwtr);
         1011  +#ifdef YYTRACKMAXSTACKDEPTH
         1012  +    iHiwtr = iCur = -1;
         1013  +    sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
         1014  +    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n", iCur, iHiwtr);
         1015  +#endif
         1016  +  }
         1017  +
         1018  +  if( pArg && pArg->out && db ){
         1019  +    iHiwtr = iCur = -1;
         1020  +    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
         1021  +    fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);
         1022  +    iHiwtr = iCur = -1;
         1023  +    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
         1024  +    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n", iCur); 
         1025  +    iHiwtr = iCur = -1;
         1026  +    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
         1027  +    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur); 
         1028  +    iHiwtr = iCur = -1;
         1029  +    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
         1030  +    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur); 
         1031  +  }
         1032  +
         1033  +  if( pArg && pArg->out && db && pArg->pStmt ){
         1034  +    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
         1035  +    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
         1036  +    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
         1037  +    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
         1038  +    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
         1039  +    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
         1040  +  }
         1041  +
         1042  +  return 0;
         1043  +}
         1044  +
         1045  +/*
         1046  +** Execute a statement or set of statements.  Print 
         1047  +** any result rows/columns depending on the current mode 
         1048  +** set via the supplied callback.
         1049  +**
         1050  +** This is very similar to SQLite's built-in sqlite3_exec() 
         1051  +** function except it takes a slightly different callback 
         1052  +** and callback data argument.
         1053  +*/
         1054  +static int shell_exec(
         1055  +  sqlite3 *db,                                /* An open database */
         1056  +  const char *zSql,                           /* SQL to be evaluated */
         1057  +  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
         1058  +                                              /* (not the same as sqlite3_exec) */
         1059  +  struct callback_data *pArg,                 /* Pointer to struct callback_data */
         1060  +  char **pzErrMsg                             /* Error msg written here */
         1061  +){
         1062  +  sqlite3_stmt *pStmt = NULL;     /* Statement to execute. */
         1063  +  int rc = SQLITE_OK;             /* Return Code */
         1064  +  const char *zLeftover;          /* Tail of unprocessed SQL */
         1065  +
         1066  +  if( pzErrMsg ){
         1067  +    *pzErrMsg = NULL;
         1068  +  }
         1069  +
         1070  +  while( zSql[0] && (SQLITE_OK == rc) ){
         1071  +    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
         1072  +    if( SQLITE_OK != rc ){
         1073  +      if( pzErrMsg ){
         1074  +        *pzErrMsg = save_err_msg(db);
         1075  +      }
         1076  +    }else{
         1077  +      if( !pStmt ){
         1078  +        /* this happens for a comment or white-space */
         1079  +        zSql = zLeftover;
         1080  +        while( isspace(zSql[0]) ) zSql++;
         1081  +        continue;
         1082  +      }
         1083  +
         1084  +      /* save off the prepared statment handle and reset row count */
         1085  +      if( pArg ){
         1086  +        pArg->pStmt = pStmt;
         1087  +        pArg->cnt = 0;
         1088  +      }
         1089  +
         1090  +      /* echo the sql statement if echo on */
         1091  +      if( pArg && pArg->echoOn ){
         1092  +        const char *zStmtSql = sqlite3_sql(pStmt);
         1093  +        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
         1094  +      }
         1095  +
         1096  +      /* perform the first step.  this will tell us if we
         1097  +      ** have a result set or not and how wide it is.
         1098  +      */
         1099  +      rc = sqlite3_step(pStmt);
         1100  +      /* if we have a result set... */
         1101  +      if( SQLITE_ROW == rc ){
         1102  +        /* if we have a callback... */
         1103  +        if( xCallback ){
         1104  +          /* allocate space for col name ptr, value ptr, and type */
         1105  +          int nCol = sqlite3_column_count(pStmt);
         1106  +          void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
         1107  +          if( !pData ){
         1108  +            rc = SQLITE_NOMEM;
         1109  +          }else{
         1110  +            char **azCols = (char **)pData;      /* Names of result columns */
         1111  +            char **azVals = &azCols[nCol];       /* Results */
         1112  +            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
         1113  +            int i;
         1114  +            assert(sizeof(int) <= sizeof(char *)); 
         1115  +            /* save off ptrs to column names */
         1116  +            for(i=0; i<nCol; i++){
         1117  +              azCols[i] = (char *)sqlite3_column_name(pStmt, i);
         1118  +            }
         1119  +            do{
         1120  +              /* extract the data and data types */
         1121  +              for(i=0; i<nCol; i++){
         1122  +                azVals[i] = (char *)sqlite3_column_text(pStmt, i);
         1123  +                aiTypes[i] = sqlite3_column_type(pStmt, i);
         1124  +                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
         1125  +                  rc = SQLITE_NOMEM;
         1126  +                  break; /* from for */
         1127  +                }
         1128  +              } /* end for */
         1129  +
         1130  +              /* if data and types extracted successfully... */
         1131  +              if( SQLITE_ROW == rc ){ 
         1132  +                /* call the supplied callback with the result row data */
         1133  +                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
         1134  +                  rc = SQLITE_ABORT;
         1135  +                }else{
         1136  +                  rc = sqlite3_step(pStmt);
         1137  +                }
         1138  +              }
         1139  +            } while( SQLITE_ROW == rc );
         1140  +            sqlite3_free(pData);
         1141  +          }
         1142  +        }else{
         1143  +          do{
         1144  +            rc = sqlite3_step(pStmt);
         1145  +          } while( rc == SQLITE_ROW );
         1146  +        }
         1147  +      }
         1148  +
         1149  +      /* print usage stats if stats on */
         1150  +      if( pArg && pArg->statsOn ){
         1151  +        display_stats(db, pArg, 0);
         1152  +      }
         1153  +
         1154  +      /* Finalize the statement just executed. If this fails, save a 
         1155  +      ** copy of the error message. Otherwise, set zSql to point to the
         1156  +      ** next statement to execute. */
         1157  +      rc = sqlite3_finalize(pStmt);
         1158  +      if( rc==SQLITE_OK ){
         1159  +        zSql = zLeftover;
         1160  +        while( isspace(zSql[0]) ) zSql++;
         1161  +      }else if( pzErrMsg ){
         1162  +        *pzErrMsg = save_err_msg(db);
         1163  +      }
         1164  +
         1165  +      /* clear saved stmt handle */
         1166  +      if( pArg ){
         1167  +        pArg->pStmt = NULL;
         1168  +      }
         1169  +    }
         1170  +  } /* end while */
         1171  +
         1172  +  return rc;
         1173  +}
         1174  +
         1175  +
         1176  +/*
         1177  +** This is a different callback routine used for dumping the database.
         1178  +** Each row received by this callback consists of a table name,
         1179  +** the table type ("index" or "table") and SQL to create the table.
         1180  +** This routine should print text sufficient to recreate the table.
         1181  +*/
         1182  +static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
         1183  +  int rc;
         1184  +  const char *zTable;
         1185  +  const char *zType;
         1186  +  const char *zSql;
         1187  +  const char *zPrepStmt = 0;
         1188  +  struct callback_data *p = (struct callback_data *)pArg;
         1189  +
         1190  +  UNUSED_PARAMETER(azCol);
         1191  +  if( nArg!=3 ) return 1;
         1192  +  zTable = azArg[0];
         1193  +  zType = azArg[1];
         1194  +  zSql = azArg[2];
         1195  +  
         1196  +  if( strcmp(zTable, "sqlite_sequence")==0 ){
         1197  +    zPrepStmt = "DELETE FROM sqlite_sequence;\n";
         1198  +  }else if( strcmp(zTable, "sqlite_stat1")==0 ){
         1199  +    fprintf(p->out, "ANALYZE sqlite_master;\n");
         1200  +  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
         1201  +    return 0;
         1202  +  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
         1203  +    char *zIns;
         1204  +    if( !p->writableSchema ){
         1205  +      fprintf(p->out, "PRAGMA writable_schema=ON;\n");
         1206  +      p->writableSchema = 1;
         1207  +    }
         1208  +    zIns = sqlite3_mprintf(
         1209  +       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
         1210  +       "VALUES('table','%q','%q',0,'%q');",
         1211  +       zTable, zTable, zSql);
         1212  +    fprintf(p->out, "%s\n", zIns);
         1213  +    sqlite3_free(zIns);
         1214  +    return 0;
         1215  +  }else{
         1216  +    fprintf(p->out, "%s;\n", zSql);
         1217  +  }
         1218  +
         1219  +  if( strcmp(zType, "table")==0 ){
         1220  +    sqlite3_stmt *pTableInfo = 0;
         1221  +    char *zSelect = 0;
         1222  +    char *zTableInfo = 0;
         1223  +    char *zTmp = 0;
         1224  +    int nRow = 0;
         1225  +   
         1226  +    zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
         1227  +    zTableInfo = appendText(zTableInfo, zTable, '"');
         1228  +    zTableInfo = appendText(zTableInfo, ");", 0);
         1229  +
         1230  +    rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
         1231  +    free(zTableInfo);
         1232  +    if( rc!=SQLITE_OK || !pTableInfo ){
         1233  +      return 1;
         1234  +    }
         1235  +
         1236  +    zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
         1237  +    zTmp = appendText(zTmp, zTable, '"');
         1238  +    if( zTmp ){
         1239  +      zSelect = appendText(zSelect, zTmp, '\'');
         1240  +    }
         1241  +    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
         1242  +    rc = sqlite3_step(pTableInfo);
         1243  +    while( rc==SQLITE_ROW ){
         1244  +      const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
         1245  +      zSelect = appendText(zSelect, "quote(", 0);
         1246  +      zSelect = appendText(zSelect, zText, '"');
         1247  +      rc = sqlite3_step(pTableInfo);
         1248  +      if( rc==SQLITE_ROW ){
         1249  +        zSelect = appendText(zSelect, ") || ',' || ", 0);
         1250  +      }else{
         1251  +        zSelect = appendText(zSelect, ") ", 0);
         1252  +      }
         1253  +      nRow++;
         1254  +    }
         1255  +    rc = sqlite3_finalize(pTableInfo);
         1256  +    if( rc!=SQLITE_OK || nRow==0 ){
         1257  +      free(zSelect);
         1258  +      return 1;
         1259  +    }
         1260  +    zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
         1261  +    zSelect = appendText(zSelect, zTable, '"');
         1262  +
         1263  +    rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
         1264  +    if( rc==SQLITE_CORRUPT ){
         1265  +      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
         1266  +      rc = run_table_dump_query(p->out, p->db, zSelect, 0);
         1267  +    }
         1268  +    if( zSelect ) free(zSelect);
         1269  +  }
         1270  +  return 0;
         1271  +}
         1272  +
         1273  +/*
         1274  +** Run zQuery.  Use dump_callback() as the callback routine so that
         1275  +** the contents of the query are output as SQL statements.
         1276  +**
         1277  +** If we get a SQLITE_CORRUPT error, rerun the query after appending
         1278  +** "ORDER BY rowid DESC" to the end.
         1279  +*/
         1280  +static int run_schema_dump_query(
         1281  +  struct callback_data *p, 
         1282  +  const char *zQuery,
         1283  +  char **pzErrMsg
         1284  +){
         1285  +  int rc;
         1286  +  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
         1287  +  if( rc==SQLITE_CORRUPT ){
         1288  +    char *zQ2;
         1289  +    int len = strlen30(zQuery);
         1290  +    if( pzErrMsg ) sqlite3_free(*pzErrMsg);
         1291  +    zQ2 = malloc( len+100 );
         1292  +    if( zQ2==0 ) return rc;
         1293  +    sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
         1294  +    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
         1295  +    free(zQ2);
         1296  +  }
         1297  +  return rc;
         1298  +}
         1299  +
         1300  +/*
         1301  +** Text of a help message
         1302  +*/
         1303  +static char zHelp[] =
         1304  +  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
         1305  +  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
         1306  +  ".databases             List names and files of attached databases\n"
         1307  +  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
         1308  +  "                         If TABLE specified, only dump tables matching\n"
         1309  +  "                         LIKE pattern TABLE.\n"
         1310  +  ".echo ON|OFF           Turn command echo on or off\n"
         1311  +  ".exit                  Exit this program\n"
         1312  +  ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"
         1313  +  "                         With no args, it turns EXPLAIN on.\n"
         1314  +  ".header(s) ON|OFF      Turn display of headers on or off\n"
         1315  +  ".help                  Show this message\n"
         1316  +  ".import FILE TABLE     Import data from FILE into TABLE\n"
         1317  +  ".indices ?TABLE?       Show names of all indices\n"
         1318  +  "                         If TABLE specified, only show indices for tables\n"
         1319  +  "                         matching LIKE pattern TABLE.\n"
         1320  +#ifdef SQLITE_ENABLE_IOTRACE
         1321  +  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
         1322  +#endif
         1323  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
         1324  +  ".load FILE ?ENTRY?     Load an extension library\n"
         1325  +#endif
         1326  +  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
         1327  +  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
         1328  +  "                         csv      Comma-separated values\n"
         1329  +  "                         column   Left-aligned columns.  (See .width)\n"
         1330  +  "                         html     HTML <table> code\n"
         1331  +  "                         insert   SQL insert statements for TABLE\n"
         1332  +  "                         line     One value per line\n"
         1333  +  "                         list     Values delimited by .separator string\n"
         1334  +  "                         tabs     Tab-separated values\n"
         1335  +  "                         tcl      TCL list elements\n"
         1336  +  ".nullvalue STRING      Print STRING in place of NULL values\n"
         1337  +  ".output FILENAME       Send output to FILENAME\n"
         1338  +  ".output stdout         Send output to the screen\n"
         1339  +  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
         1340  +  ".quit                  Exit this program\n"
         1341  +  ".read FILENAME         Execute SQL in FILENAME\n"
         1342  +  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
         1343  +  ".schema ?TABLE?        Show the CREATE statements\n"
         1344  +  "                         If TABLE specified, only show tables matching\n"
         1345  +  "                         LIKE pattern TABLE.\n"
         1346  +  ".separator STRING      Change separator used by output mode and .import\n"
         1347  +  ".show                  Show the current values for various settings\n"
         1348  +  ".stats ON|OFF          Turn stats on or off\n"
         1349  +  ".tables ?TABLE?        List names of tables\n"
         1350  +  "                         If TABLE specified, only list tables matching\n"
         1351  +  "                         LIKE pattern TABLE.\n"
         1352  +  ".timeout MS            Try opening locked tables for MS milliseconds\n"
         1353  +  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
         1354  +;
         1355  +
         1356  +static char zTimerHelp[] =
         1357  +  ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
         1358  +;
         1359  +
         1360  +/* Forward reference */
         1361  +static int process_input(struct callback_data *p, FILE *in);
         1362  +
         1363  +/*
         1364  +** Make sure the database is open.  If it is not, then open it.  If
         1365  +** the database fails to open, print an error message and exit.
         1366  +*/
         1367  +static void open_db(struct callback_data *p){
         1368  +  if( p->db==0 ){
         1369  +    sqlite3_open(p->zDbFilename, &p->db);
         1370  +    db = p->db;
         1371  +    if( db && sqlite3_errcode(db)==SQLITE_OK ){
         1372  +      sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
         1373  +          shellstaticFunc, 0, 0);
         1374  +    }
         1375  +    if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
         1376  +      fprintf(stderr,"Error: unable to open database \"%s\": %s\n", 
         1377  +          p->zDbFilename, sqlite3_errmsg(db));
         1378  +      exit(1);
         1379  +    }
         1380  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
         1381  +    sqlite3_enable_load_extension(p->db, 1);
         1382  +#endif
         1383  +  }
         1384  +}
         1385  +
         1386  +/*
         1387  +** Do C-language style dequoting.
         1388  +**
         1389  +**    \t    -> tab
         1390  +**    \n    -> newline
         1391  +**    \r    -> carriage return
         1392  +**    \NNN  -> ascii character NNN in octal
         1393  +**    \\    -> backslash
         1394  +*/
         1395  +static void resolve_backslashes(char *z){
         1396  +  int i, j;
         1397  +  char c;
         1398  +  for(i=j=0; (c = z[i])!=0; i++, j++){
         1399  +    if( c=='\\' ){
         1400  +      c = z[++i];
         1401  +      if( c=='n' ){
         1402  +        c = '\n';
         1403  +      }else if( c=='t' ){
         1404  +        c = '\t';
         1405  +      }else if( c=='r' ){
         1406  +        c = '\r';
         1407  +      }else if( c>='0' && c<='7' ){
         1408  +        c -= '0';
         1409  +        if( z[i+1]>='0' && z[i+1]<='7' ){
         1410  +          i++;
         1411  +          c = (c<<3) + z[i] - '0';
         1412  +          if( z[i+1]>='0' && z[i+1]<='7' ){
         1413  +            i++;
         1414  +            c = (c<<3) + z[i] - '0';
         1415  +          }
         1416  +        }
         1417  +      }
         1418  +    }
         1419  +    z[j] = c;
         1420  +  }
         1421  +  z[j] = 0;
         1422  +}
         1423  +
         1424  +/*
         1425  +** Interpret zArg as a boolean value.  Return either 0 or 1.
         1426  +*/
         1427  +static int booleanValue(char *zArg){
         1428  +  int val = atoi(zArg);
         1429  +  int j;
         1430  +  for(j=0; zArg[j]; j++){
         1431  +    zArg[j] = (char)tolower(zArg[j]);
         1432  +  }
         1433  +  if( strcmp(zArg,"on")==0 ){
         1434  +    val = 1;
         1435  +  }else if( strcmp(zArg,"yes")==0 ){
         1436  +    val = 1;
         1437  +  }
         1438  +  return val;
         1439  +}
         1440  +
         1441  +/*
         1442  +** If an input line begins with "." then invoke this routine to
         1443  +** process that line.
         1444  +**
         1445  +** Return 1 on error, 2 to exit, and 0 otherwise.
         1446  +*/
         1447  +static int do_meta_command(char *zLine, struct callback_data *p){
         1448  +  int i = 1;
         1449  +  int nArg = 0;
         1450  +  int n, c;
         1451  +  int rc = 0;
         1452  +  char *azArg[50];
         1453  +
         1454  +  /* Parse the input line into tokens.
         1455  +  */
         1456  +  while( zLine[i] && nArg<ArraySize(azArg) ){
         1457  +    while( isspace((unsigned char)zLine[i]) ){ i++; }
         1458  +    if( zLine[i]==0 ) break;
         1459  +    if( zLine[i]=='\'' || zLine[i]=='"' ){
         1460  +      int delim = zLine[i++];
         1461  +      azArg[nArg++] = &zLine[i];
         1462  +      while( zLine[i] && zLine[i]!=delim ){ i++; }
         1463  +      if( zLine[i]==delim ){
         1464  +        zLine[i++] = 0;
         1465  +      }
         1466  +      if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
         1467  +    }else{
         1468  +      azArg[nArg++] = &zLine[i];
         1469  +      while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
         1470  +      if( zLine[i] ) zLine[i++] = 0;
         1471  +      resolve_backslashes(azArg[nArg-1]);
         1472  +    }
         1473  +  }
         1474  +
         1475  +  /* Process the input line.
         1476  +  */
         1477  +  if( nArg==0 ) return 0; /* no tokens, no error */
         1478  +  n = strlen30(azArg[0]);
         1479  +  c = azArg[0][0];
         1480  +  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
         1481  +    const char *zDestFile;
         1482  +    const char *zDb;
         1483  +    sqlite3 *pDest;
         1484  +    sqlite3_backup *pBackup;
         1485  +    if( nArg==2 ){
         1486  +      zDestFile = azArg[1];
         1487  +      zDb = "main";
         1488  +    }else{
         1489  +      zDestFile = azArg[2];
         1490  +      zDb = azArg[1];
         1491  +    }
         1492  +    rc = sqlite3_open(zDestFile, &pDest);
         1493  +    if( rc!=SQLITE_OK ){
         1494  +      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
         1495  +      sqlite3_close(pDest);
         1496  +      return 1;
         1497  +    }
         1498  +    open_db(p);
         1499  +    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
         1500  +    if( pBackup==0 ){
         1501  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
         1502  +      sqlite3_close(pDest);
         1503  +      return 1;
         1504  +    }
         1505  +    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
         1506  +    sqlite3_backup_finish(pBackup);
         1507  +    if( rc==SQLITE_DONE ){
         1508  +      rc = 0;
         1509  +    }else{
         1510  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
         1511  +      rc = 1;
         1512  +    }
         1513  +    sqlite3_close(pDest);
         1514  +  }else
         1515  +
         1516  +  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
         1517  +    bail_on_error = booleanValue(azArg[1]);
         1518  +  }else
         1519  +
         1520  +  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
         1521  +    struct callback_data data;
         1522  +    char *zErrMsg = 0;
         1523  +    open_db(p);
         1524  +    memcpy(&data, p, sizeof(data));
         1525  +    data.showHeader = 1;
         1526  +    data.mode = MODE_Column;
         1527  +    data.colWidth[0] = 3;
         1528  +    data.colWidth[1] = 15;
         1529  +    data.colWidth[2] = 58;
         1530  +    data.cnt = 0;
         1531  +    sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
         1532  +    if( zErrMsg ){
         1533  +      fprintf(stderr,"Error: %s\n", zErrMsg);
         1534  +      sqlite3_free(zErrMsg);
         1535  +      rc = 1;
         1536  +    }
         1537  +  }else
         1538  +
         1539  +  if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
         1540  +    char *zErrMsg = 0;
         1541  +    open_db(p);
         1542  +    /* When playing back a "dump", the content might appear in an order
         1543  +    ** which causes immediate foreign key constraints to be violated.
         1544  +    ** So disable foreign-key constraint enforcement to prevent problems. */
         1545  +    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
         1546  +    fprintf(p->out, "BEGIN TRANSACTION;\n");
         1547  +    p->writableSchema = 0;
         1548  +    sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
         1549  +    if( nArg==1 ){
         1550  +      run_schema_dump_query(p, 
         1551  +        "SELECT name, type, sql FROM sqlite_master "
         1552  +        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
         1553  +      );
         1554  +      run_schema_dump_query(p, 
         1555  +        "SELECT name, type, sql FROM sqlite_master "
         1556  +        "WHERE name=='sqlite_sequence'", 0
         1557  +      );
         1558  +      run_table_dump_query(p->out, p->db,
         1559  +        "SELECT sql FROM sqlite_master "
         1560  +        "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
         1561  +      );
         1562  +    }else{
         1563  +      int i;
         1564  +      for(i=1; i<nArg; i++){
         1565  +        zShellStatic = azArg[i];
         1566  +        run_schema_dump_query(p,
         1567  +          "SELECT name, type, sql FROM sqlite_master "
         1568  +          "WHERE tbl_name LIKE shellstatic() AND type=='table'"
         1569  +          "  AND sql NOT NULL", 0);
         1570  +        run_table_dump_query(p->out, p->db,
         1571  +          "SELECT sql FROM sqlite_master "
         1572  +          "WHERE sql NOT NULL"
         1573  +          "  AND type IN ('index','trigger','view')"
         1574  +          "  AND tbl_name LIKE shellstatic()", 0
         1575  +        );
         1576  +        zShellStatic = 0;
         1577  +      }
         1578  +    }
         1579  +    if( p->writableSchema ){
         1580  +      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
         1581  +      p->writableSchema = 0;
         1582  +    }
         1583  +    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
         1584  +    if( zErrMsg ){
         1585  +      fprintf(stderr,"Error: %s\n", zErrMsg);
         1586  +      sqlite3_free(zErrMsg);
         1587  +    }else{
         1588  +      fprintf(p->out, "COMMIT;\n");
         1589  +    }
         1590  +  }else
         1591  +
         1592  +  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
         1593  +    p->echoOn = booleanValue(azArg[1]);
         1594  +  }else
         1595  +
         1596  +  if( c=='e' && strncmp(azArg[0], "exit", n)==0  && nArg==1 ){
         1597  +    rc = 2;
         1598  +  }else
         1599  +
         1600  +  if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
         1601  +    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
         1602  +    if(val == 1) {
         1603  +      if(!p->explainPrev.valid) {
         1604  +        p->explainPrev.valid = 1;
         1605  +        p->explainPrev.mode = p->mode;
         1606  +        p->explainPrev.showHeader = p->showHeader;
         1607  +        memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
         1608  +      }
         1609  +      /* We could put this code under the !p->explainValid
         1610  +      ** condition so that it does not execute if we are already in
         1611  +      ** explain mode. However, always executing it allows us an easy
         1612  +      ** was to reset to explain mode in case the user previously
         1613  +      ** did an .explain followed by a .width, .mode or .header
         1614  +      ** command.
         1615  +      */
         1616  +      p->mode = MODE_Explain;
         1617  +      p->showHeader = 1;
         1618  +      memset(p->colWidth,0,ArraySize(p->colWidth));
         1619  +      p->colWidth[0] = 4;                  /* addr */
         1620  +      p->colWidth[1] = 13;                 /* opcode */
         1621  +      p->colWidth[2] = 4;                  /* P1 */
         1622  +      p->colWidth[3] = 4;                  /* P2 */
         1623  +      p->colWidth[4] = 4;                  /* P3 */
         1624  +      p->colWidth[5] = 13;                 /* P4 */
         1625  +      p->colWidth[6] = 2;                  /* P5 */
         1626  +      p->colWidth[7] = 13;                  /* Comment */
         1627  +    }else if (p->explainPrev.valid) {
         1628  +      p->explainPrev.valid = 0;
         1629  +      p->mode = p->explainPrev.mode;
         1630  +      p->showHeader = p->explainPrev.showHeader;
         1631  +      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
         1632  +    }
         1633  +  }else
         1634  +
         1635  +  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
         1636  +                 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
         1637  +    p->showHeader = booleanValue(azArg[1]);
         1638  +  }else
         1639  +
         1640  +  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
         1641  +    fprintf(stderr,"%s",zHelp);
         1642  +    if( HAS_TIMER ){
         1643  +      fprintf(stderr,"%s",zTimerHelp);
         1644  +    }
         1645  +  }else
         1646  +
         1647  +  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
         1648  +    char *zTable = azArg[2];    /* Insert data into this table */
         1649  +    char *zFile = azArg[1];     /* The file from which to extract data */
         1650  +    sqlite3_stmt *pStmt = NULL; /* A statement */
         1651  +    int nCol;                   /* Number of columns in the table */
         1652  +    int nByte;                  /* Number of bytes in an SQL string */
         1653  +    int i, j;                   /* Loop counters */
         1654  +    int nSep;                   /* Number of bytes in p->separator[] */
         1655  +    char *zSql;                 /* An SQL statement */
         1656  +    char *zLine;                /* A single line of input from the file */
         1657  +    char **azCol;               /* zLine[] broken up into columns */
         1658  +    char *zCommit;              /* How to commit changes */   
         1659  +    FILE *in;                   /* The input file */
         1660  +    int lineno = 0;             /* Line number of input file */
         1661  +
         1662  +    open_db(p);
         1663  +    nSep = strlen30(p->separator);
         1664  +    if( nSep==0 ){
         1665  +      fprintf(stderr, "Error: non-null separator required for import\n");
         1666  +      return 1;
         1667  +    }
         1668  +    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
         1669  +    if( zSql==0 ){
         1670  +      fprintf(stderr, "Error: out of memory\n");
         1671  +      return 1;
         1672  +    }
         1673  +    nByte = strlen30(zSql);
         1674  +    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
         1675  +    sqlite3_free(zSql);
         1676  +    if( rc ){
         1677  +      if (pStmt) sqlite3_finalize(pStmt);
         1678  +      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
         1679  +      return 1;
         1680  +    }
         1681  +    nCol = sqlite3_column_count(pStmt);
         1682  +    sqlite3_finalize(pStmt);
         1683  +    pStmt = 0;
         1684  +    if( nCol==0 ) return 0; /* no columns, no error */
         1685  +    zSql = malloc( nByte + 20 + nCol*2 );
         1686  +    if( zSql==0 ){
         1687  +      fprintf(stderr, "Error: out of memory\n");
         1688  +      return 1;
         1689  +    }
         1690  +    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
         1691  +    j = strlen30(zSql);
         1692  +    for(i=1; i<nCol; i++){
         1693  +      zSql[j++] = ',';
         1694  +      zSql[j++] = '?';
         1695  +    }
         1696  +    zSql[j++] = ')';
         1697  +    zSql[j] = 0;
         1698  +    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
         1699  +    free(zSql);
         1700  +    if( rc ){
         1701  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
         1702  +      if (pStmt) sqlite3_finalize(pStmt);
         1703  +      return 1;
         1704  +    }
         1705  +    in = fopen(zFile, "rb");
         1706  +    if( in==0 ){
         1707  +      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
         1708  +      sqlite3_finalize(pStmt);
         1709  +      return 1;
         1710  +    }
         1711  +    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
         1712  +    if( azCol==0 ){
         1713  +      fprintf(stderr, "Error: out of memory\n");
         1714  +      fclose(in);
         1715  +      sqlite3_finalize(pStmt);
         1716  +      return 1;
         1717  +    }
         1718  +    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
         1719  +    zCommit = "COMMIT";
         1720  +    while( (zLine = local_getline(0, in))!=0 ){
         1721  +      char *z;
         1722  +      i = 0;
         1723  +      lineno++;
         1724  +      azCol[0] = zLine;
         1725  +      for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
         1726  +        if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
         1727  +          *z = 0;
         1728  +          i++;
         1729  +          if( i<nCol ){
         1730  +            azCol[i] = &z[nSep];
         1731  +            z += nSep-1;
         1732  +          }
         1733  +        }
         1734  +      } /* end for */
         1735  +      *z = 0;
         1736  +      if( i+1!=nCol ){
         1737  +        fprintf(stderr,
         1738  +                "Error: %s line %d: expected %d columns of data but found %d\n",
         1739  +                zFile, lineno, nCol, i+1);
         1740  +        zCommit = "ROLLBACK";
         1741  +        free(zLine);
         1742  +        rc = 1;
         1743  +        break; /* from while */
         1744  +      }
         1745  +      for(i=0; i<nCol; i++){
         1746  +        sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
         1747  +      }
         1748  +      sqlite3_step(pStmt);
         1749  +      rc = sqlite3_reset(pStmt);
         1750  +      free(zLine);
         1751  +      if( rc!=SQLITE_OK ){
         1752  +        fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
         1753  +        zCommit = "ROLLBACK";
         1754  +        rc = 1;
         1755  +        break; /* from while */
         1756  +      }
         1757  +    } /* end while */
         1758  +    free(azCol);
         1759  +    fclose(in);
         1760  +    sqlite3_finalize(pStmt);
         1761  +    sqlite3_exec(p->db, zCommit, 0, 0, 0);
         1762  +  }else
         1763  +
         1764  +  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
         1765  +    struct callback_data data;
         1766  +    char *zErrMsg = 0;
         1767  +    open_db(p);
         1768  +    memcpy(&data, p, sizeof(data));
         1769  +    data.showHeader = 0;
         1770  +    data.mode = MODE_List;
         1771  +    if( nArg==1 ){
         1772  +      rc = sqlite3_exec(p->db,
         1773  +        "SELECT name FROM sqlite_master "
         1774  +        "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
         1775  +        "UNION ALL "
         1776  +        "SELECT name FROM sqlite_temp_master "
         1777  +        "WHERE type='index' "
         1778  +        "ORDER BY 1",
         1779  +        callback, &data, &zErrMsg
         1780  +      );
         1781  +    }else{
         1782  +      zShellStatic = azArg[1];
         1783  +      rc = sqlite3_exec(p->db,
         1784  +        "SELECT name FROM sqlite_master "
         1785  +        "WHERE type='index' AND tbl_name LIKE shellstatic() "
         1786  +        "UNION ALL "
         1787  +        "SELECT name FROM sqlite_temp_master "
         1788  +        "WHERE type='index' AND tbl_name LIKE shellstatic() "
         1789  +        "ORDER BY 1",
         1790  +        callback, &data, &zErrMsg
         1791  +      );
         1792  +      zShellStatic = 0;
         1793  +    }
         1794  +    if( zErrMsg ){
         1795  +      fprintf(stderr,"Error: %s\n", zErrMsg);
         1796  +      sqlite3_free(zErrMsg);
         1797  +      rc = 1;
         1798  +    }else if( rc != SQLITE_OK ){
         1799  +      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
         1800  +      rc = 1;
         1801  +    }
         1802  +  }else
         1803  +
         1804  +#ifdef SQLITE_ENABLE_IOTRACE
         1805  +  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
         1806  +    extern void (*sqlite3IoTrace)(const char*, ...);
         1807  +    if( iotrace && iotrace!=stdout ) fclose(iotrace);
         1808  +    iotrace = 0;
         1809  +    if( nArg<2 ){
         1810  +      sqlite3IoTrace = 0;
         1811  +    }else if( strcmp(azArg[1], "-")==0 ){
         1812  +      sqlite3IoTrace = iotracePrintf;
         1813  +      iotrace = stdout;
         1814  +    }else{
         1815  +      iotrace = fopen(azArg[1], "w");
         1816  +      if( iotrace==0 ){
         1817  +        fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
         1818  +        sqlite3IoTrace = 0;
         1819  +        rc = 1;
         1820  +      }else{
         1821  +        sqlite3IoTrace = iotracePrintf;
         1822  +      }
         1823  +    }
         1824  +  }else
         1825  +#endif
         1826  +
         1827  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
         1828  +  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
         1829  +    const char *zFile, *zProc;
         1830  +    char *zErrMsg = 0;
         1831  +    zFile = azArg[1];
         1832  +    zProc = nArg>=3 ? azArg[2] : 0;
         1833  +    open_db(p);
         1834  +    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
         1835  +    if( rc!=SQLITE_OK ){
         1836  +      fprintf(stderr, "Error: %s\n", zErrMsg);
         1837  +      sqlite3_free(zErrMsg);
         1838  +      rc = 1;
         1839  +    }
         1840  +  }else
         1841  +#endif
         1842  +
         1843  +  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
         1844  +    const char *zFile = azArg[1];
         1845  +    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
         1846  +      fclose(p->pLog);
         1847  +      p->pLog = 0;
         1848  +    }
         1849  +    if( strcmp(zFile,"stdout")==0 ){
         1850  +      p->pLog = stdout;
         1851  +    }else if( strcmp(zFile, "stderr")==0 ){
         1852  +      p->pLog = stderr;
         1853  +    }else if( strcmp(zFile, "off")==0 ){
         1854  +      p->pLog = 0;
         1855  +    }else{
         1856  +      p->pLog = fopen(zFile, "w");
         1857  +      if( p->pLog==0 ){
         1858  +        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
         1859  +      }
         1860  +    }
         1861  +  }else
         1862  +
         1863  +  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
         1864  +    int n2 = strlen30(azArg[1]);
         1865  +    if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
         1866  +        ||
         1867  +        (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
         1868  +      p->mode = MODE_Line;
         1869  +    }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
         1870  +              ||
         1871  +              (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
         1872  +      p->mode = MODE_Column;
         1873  +    }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
         1874  +      p->mode = MODE_List;
         1875  +    }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
         1876  +      p->mode = MODE_Html;
         1877  +    }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
         1878  +      p->mode = MODE_Tcl;
         1879  +    }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
         1880  +      p->mode = MODE_Csv;
         1881  +      sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
         1882  +    }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
         1883  +      p->mode = MODE_List;
         1884  +      sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
         1885  +    }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
         1886  +      p->mode = MODE_Insert;
         1887  +      set_table_name(p, "table");
         1888  +    }else {
         1889  +      fprintf(stderr,"Error: mode should be one of: "
         1890  +         "column csv html insert line list tabs tcl\n");
         1891  +      rc = 1;
         1892  +    }
         1893  +  }else
         1894  +
         1895  +  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
         1896  +    int n2 = strlen30(azArg[1]);
         1897  +    if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
         1898  +      p->mode = MODE_Insert;
         1899  +      set_table_name(p, azArg[2]);
         1900  +    }else {
         1901  +      fprintf(stderr, "Error: invalid arguments: "
         1902  +        " \"%s\". Enter \".help\" for help\n", azArg[2]);
         1903  +      rc = 1;
         1904  +    }
         1905  +  }else
         1906  +
         1907  +  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
         1908  +    sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
         1909  +                     "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
         1910  +  }else
         1911  +
         1912  +  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
         1913  +    if( p->out!=stdout ){
         1914  +      fclose(p->out);
         1915  +    }
         1916  +    if( strcmp(azArg[1],"stdout")==0 ){
         1917  +      p->out = stdout;
         1918  +      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
         1919  +    }else{
         1920  +      p->out = fopen(azArg[1], "wb");
         1921  +      if( p->out==0 ){
         1922  +        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         1923  +        p->out = stdout;
         1924  +        rc = 1;
         1925  +      } else {
         1926  +         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
         1927  +      }
         1928  +    }
         1929  +  }else
         1930  +
         1931  +  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
         1932  +    if( nArg >= 2) {
         1933  +      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
         1934  +    }
         1935  +    if( nArg >= 3) {
         1936  +      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
         1937  +    }
         1938  +  }else
         1939  +
         1940  +  if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
         1941  +    rc = 2;
         1942  +  }else
         1943  +
         1944  +  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
         1945  +    FILE *alt = fopen(azArg[1], "rb");
         1946  +    if( alt==0 ){
         1947  +      fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
         1948  +      rc = 1;
         1949  +    }else{
         1950  +      rc = process_input(p, alt);
         1951  +      fclose(alt);
         1952  +    }
         1953  +  }else
         1954  +
         1955  +  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
         1956  +    const char *zSrcFile;
         1957  +    const char *zDb;
         1958  +    sqlite3 *pSrc;
         1959  +    sqlite3_backup *pBackup;
         1960  +    int nTimeout = 0;
         1961  +
         1962  +    if( nArg==2 ){
         1963  +      zSrcFile = azArg[1];
         1964  +      zDb = "main";
         1965  +    }else{
         1966  +      zSrcFile = azArg[2];
         1967  +      zDb = azArg[1];
         1968  +    }
         1969  +    rc = sqlite3_open(zSrcFile, &pSrc);
         1970  +    if( rc!=SQLITE_OK ){
         1971  +      fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
         1972  +      sqlite3_close(pSrc);
         1973  +      return 1;
         1974  +    }
         1975  +    open_db(p);
         1976  +    pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
         1977  +    if( pBackup==0 ){
         1978  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
         1979  +      sqlite3_close(pSrc);
         1980  +      return 1;
         1981  +    }
         1982  +    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
         1983  +          || rc==SQLITE_BUSY  ){
         1984  +      if( rc==SQLITE_BUSY ){
         1985  +        if( nTimeout++ >= 3 ) break;
         1986  +        sqlite3_sleep(100);
         1987  +      }
         1988  +    }
         1989  +    sqlite3_backup_finish(pBackup);
         1990  +    if( rc==SQLITE_DONE ){
         1991  +      rc = 0;
         1992  +    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
         1993  +      fprintf(stderr, "Error: source database is busy\n");
         1994  +      rc = 1;
         1995  +    }else{
         1996  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
         1997  +      rc = 1;
         1998  +    }
         1999  +    sqlite3_close(pSrc);
         2000  +  }else
         2001  +
         2002  +  if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
         2003  +    struct callback_data data;
         2004  +    char *zErrMsg = 0;
         2005  +    open_db(p);
         2006  +    memcpy(&data, p, sizeof(data));
         2007  +    data.showHeader = 0;
         2008  +    data.mode = MODE_Semi;
         2009  +    if( nArg>1 ){
         2010  +      int i;
         2011  +      for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
         2012  +      if( strcmp(azArg[1],"sqlite_master")==0 ){
         2013  +        char *new_argv[2], *new_colv[2];
         2014  +        new_argv[0] = "CREATE TABLE sqlite_master (\n"
         2015  +                      "  type text,\n"
         2016  +                      "  name text,\n"
         2017  +                      "  tbl_name text,\n"
         2018  +                      "  rootpage integer,\n"
         2019  +                      "  sql text\n"
         2020  +                      ")";
         2021  +        new_argv[1] = 0;
         2022  +        new_colv[0] = "sql";
         2023  +        new_colv[1] = 0;
         2024  +        callback(&data, 1, new_argv, new_colv);
         2025  +        rc = SQLITE_OK;
         2026  +      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
         2027  +        char *new_argv[2], *new_colv[2];
         2028  +        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
         2029  +                      "  type text,\n"
         2030  +                      "  name text,\n"
         2031  +                      "  tbl_name text,\n"
         2032  +                      "  rootpage integer,\n"
         2033  +                      "  sql text\n"
         2034  +                      ")";
         2035  +        new_argv[1] = 0;
         2036  +        new_colv[0] = "sql";
         2037  +        new_colv[1] = 0;
         2038  +        callback(&data, 1, new_argv, new_colv);
         2039  +        rc = SQLITE_OK;
         2040  +      }else{
         2041  +        zShellStatic = azArg[1];
         2042  +        rc = sqlite3_exec(p->db,
         2043  +          "SELECT sql FROM "
         2044  +          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
         2045  +          "     FROM sqlite_master UNION ALL"
         2046  +          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
         2047  +          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
         2048  +          "ORDER BY substr(type,2,1), name",
         2049  +          callback, &data, &zErrMsg);
         2050  +        zShellStatic = 0;
         2051  +      }
         2052  +    }else{
         2053  +      rc = sqlite3_exec(p->db,
         2054  +         "SELECT sql FROM "
         2055  +         "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
         2056  +         "     FROM sqlite_master UNION ALL"
         2057  +         "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
         2058  +         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
         2059  +         "ORDER BY substr(type,2,1), name",
         2060  +         callback, &data, &zErrMsg
         2061  +      );
         2062  +    }
         2063  +    if( zErrMsg ){
         2064  +      fprintf(stderr,"Error: %s\n", zErrMsg);
         2065  +      sqlite3_free(zErrMsg);
         2066  +      rc = 1;
         2067  +    }else if( rc != SQLITE_OK ){
         2068  +      fprintf(stderr,"Error: querying schema information\n");
         2069  +      rc = 1;
         2070  +    }else{
         2071  +      rc = 0;
         2072  +    }
         2073  +  }else
         2074  +
         2075  +  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
         2076  +    sqlite3_snprintf(sizeof(p->separator), p->separator,
         2077  +                     "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
         2078  +  }else
         2079  +
         2080  +  if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
         2081  +    int i;
         2082  +    fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
         2083  +    fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
         2084  +    fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
         2085  +    fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
         2086  +    fprintf(p->out,"%9.9s: ", "nullvalue");
         2087  +      output_c_string(p->out, p->nullvalue);
         2088  +      fprintf(p->out, "\n");
         2089  +    fprintf(p->out,"%9.9s: %s\n","output",
         2090  +            strlen30(p->outfile) ? p->outfile : "stdout");
         2091  +    fprintf(p->out,"%9.9s: ", "separator");
         2092  +      output_c_string(p->out, p->separator);
         2093  +      fprintf(p->out, "\n");
         2094  +    fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
         2095  +    fprintf(p->out,"%9.9s: ","width");
         2096  +    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
         2097  +      fprintf(p->out,"%d ",p->colWidth[i]);
         2098  +    }
         2099  +    fprintf(p->out,"\n");
         2100  +  }else
         2101  +
         2102  +  if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
         2103  +    p->statsOn = booleanValue(azArg[1]);
         2104  +  }else
         2105  +
         2106  +  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
         2107  +    char **azResult;
         2108  +    int nRow;
         2109  +    char *zErrMsg;
         2110  +    open_db(p);
         2111  +    if( nArg==1 ){
         2112  +      rc = sqlite3_get_table(p->db,
         2113  +        "SELECT name FROM sqlite_master "
         2114  +        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
         2115  +        "UNION ALL "
         2116  +        "SELECT name FROM sqlite_temp_master "
         2117  +        "WHERE type IN ('table','view') "
         2118  +        "ORDER BY 1",
         2119  +        &azResult, &nRow, 0, &zErrMsg
         2120  +      );
         2121  +    }else{
         2122  +      zShellStatic = azArg[1];
         2123  +      rc = sqlite3_get_table(p->db,
         2124  +        "SELECT name FROM sqlite_master "
         2125  +        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
         2126  +        "UNION ALL "
         2127  +        "SELECT name FROM sqlite_temp_master "
         2128  +        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
         2129  +        "ORDER BY 1",
         2130  +        &azResult, &nRow, 0, &zErrMsg
         2131  +      );
         2132  +      zShellStatic = 0;
         2133  +    }
         2134  +    if( zErrMsg ){
         2135  +      fprintf(stderr,"Error: %s\n", zErrMsg);
         2136  +      sqlite3_free(zErrMsg);
         2137  +      rc = 1;
         2138  +    }else if( rc != SQLITE_OK ){
         2139  +      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
         2140  +      rc = 1;
         2141  +    }else{
         2142  +      int len, maxlen = 0;
         2143  +      int i, j;
         2144  +      int nPrintCol, nPrintRow;
         2145  +      for(i=1; i<=nRow; i++){
         2146  +        if( azResult[i]==0 ) continue;
         2147  +        len = strlen30(azResult[i]);
         2148  +        if( len>maxlen ) maxlen = len;
         2149  +      }
         2150  +      nPrintCol = 80/(maxlen+2);
         2151  +      if( nPrintCol<1 ) nPrintCol = 1;
         2152  +      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
         2153  +      for(i=0; i<nPrintRow; i++){
         2154  +        for(j=i+1; j<=nRow; j+=nPrintRow){
         2155  +          char *zSp = j<=nPrintRow ? "" : "  ";
         2156  +          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
         2157  +        }
         2158  +        printf("\n");
         2159  +      }
         2160  +    }
         2161  +    sqlite3_free_table(azResult);
         2162  +  }else
         2163  +
         2164  +  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
         2165  +    open_db(p);
         2166  +    sqlite3_busy_timeout(p->db, atoi(azArg[1]));
         2167  +  }else
         2168  +    
         2169  +  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
         2170  +    enableTimer = booleanValue(azArg[1]);
         2171  +  }else
         2172  +  
         2173  +  if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
         2174  +    int j;
         2175  +    assert( nArg<=ArraySize(azArg) );
         2176  +    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
         2177  +      p->colWidth[j-1] = atoi(azArg[j]);
         2178  +    }
         2179  +  }else
         2180  +
         2181  +  {
         2182  +    fprintf(stderr, "Error: unknown command or invalid arguments: "
         2183  +      " \"%s\". Enter \".help\" for help\n", azArg[0]);
         2184  +    rc = 1;
         2185  +  }
         2186  +
         2187  +  return rc;
         2188  +}
         2189  +
         2190  +/*
         2191  +** Return TRUE if a semicolon occurs anywhere in the first N characters
         2192  +** of string z[].
         2193  +*/
         2194  +static int _contains_semicolon(const char *z, int N){
         2195  +  int i;
         2196  +  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
         2197  +  return 0;
         2198  +}
         2199  +
         2200  +/*
         2201  +** Test to see if a line consists entirely of whitespace.
         2202  +*/
         2203  +static int _all_whitespace(const char *z){
         2204  +  for(; *z; z++){
         2205  +    if( isspace(*(unsigned char*)z) ) continue;
         2206  +    if( *z=='/' && z[1]=='*' ){
         2207  +      z += 2;
         2208  +      while( *z && (*z!='*' || z[1]!='/') ){ z++; }
         2209  +      if( *z==0 ) return 0;
         2210  +      z++;
         2211  +      continue;
         2212  +    }
         2213  +    if( *z=='-' && z[1]=='-' ){
         2214  +      z += 2;
         2215  +      while( *z && *z!='\n' ){ z++; }
         2216  +      if( *z==0 ) return 1;
         2217  +      continue;
         2218  +    }
         2219  +    return 0;
         2220  +  }
         2221  +  return 1;
         2222  +}
         2223  +
         2224  +/*
         2225  +** Return TRUE if the line typed in is an SQL command terminator other
         2226  +** than a semi-colon.  The SQL Server style "go" command is understood
         2227  +** as is the Oracle "/".
         2228  +*/
         2229  +static int _is_command_terminator(const char *zLine){
         2230  +  while( isspace(*(unsigned char*)zLine) ){ zLine++; };
         2231  +  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
         2232  +    return 1;  /* Oracle */
         2233  +  }
         2234  +  if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
         2235  +         && _all_whitespace(&zLine[2]) ){
         2236  +    return 1;  /* SQL Server */
         2237  +  }
         2238  +  return 0;
         2239  +}
         2240  +
         2241  +/*
         2242  +** Return true if zSql is a complete SQL statement.  Return false if it
         2243  +** ends in the middle of a string literal or C-style comment.
         2244  +*/
         2245  +static int _is_complete(char *zSql, int nSql){
         2246  +  int rc;
         2247  +  if( zSql==0 ) return 1;
         2248  +  zSql[nSql] = ';';
         2249  +  zSql[nSql+1] = 0;
         2250  +  rc = sqlite3_complete(zSql);
         2251  +  zSql[nSql] = 0;
         2252  +  return rc;
         2253  +}
         2254  +
         2255  +/*
         2256  +** Read input from *in and process it.  If *in==0 then input
         2257  +** is interactive - the user is typing it it.  Otherwise, input
         2258  +** is coming from a file or device.  A prompt is issued and history
         2259  +** is saved only if input is interactive.  An interrupt signal will
         2260  +** cause this routine to exit immediately, unless input is interactive.
         2261  +**
         2262  +** Return the number of errors.
         2263  +*/
         2264  +static int process_input(struct callback_data *p, FILE *in){
         2265  +  char *zLine = 0;
         2266  +  char *zSql = 0;
         2267  +  int nSql = 0;
         2268  +  int nSqlPrior = 0;
         2269  +  char *zErrMsg;
         2270  +  int rc;
         2271  +  int errCnt = 0;
         2272  +  int lineno = 0;
         2273  +  int startline = 0;
         2274  +
         2275  +  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
         2276  +    fflush(p->out);
         2277  +    free(zLine);
         2278  +    zLine = one_input_line(zSql, in);
         2279  +    if( zLine==0 ){
         2280  +      break;  /* We have reached EOF */
         2281  +    }
         2282  +    if( seenInterrupt ){
         2283  +      if( in!=0 ) break;
         2284  +      seenInterrupt = 0;
         2285  +    }
         2286  +    lineno++;
         2287  +    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
         2288  +    if( zLine && zLine[0]=='.' && nSql==0 ){
         2289  +      if( p->echoOn ) printf("%s\n", zLine);
         2290  +      rc = do_meta_command(zLine, p);
         2291  +      if( rc==2 ){ /* exit requested */
         2292  +        break;
         2293  +      }else if( rc ){
         2294  +        errCnt++;
         2295  +      }
         2296  +      continue;
         2297  +    }
         2298  +    if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
         2299  +      memcpy(zLine,";",2);
         2300  +    }
         2301  +    nSqlPrior = nSql;
         2302  +    if( zSql==0 ){
         2303  +      int i;
         2304  +      for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
         2305  +      if( zLine[i]!=0 ){
         2306  +        nSql = strlen30(zLine);
         2307  +        zSql = malloc( nSql+3 );
         2308  +        if( zSql==0 ){
         2309  +          fprintf(stderr, "Error: out of memory\n");
         2310  +          exit(1);
         2311  +        }
         2312  +        memcpy(zSql, zLine, nSql+1);
         2313  +        startline = lineno;
         2314  +      }
         2315  +    }else{
         2316  +      int len = strlen30(zLine);
         2317  +      zSql = realloc( zSql, nSql + len + 4 );
         2318  +      if( zSql==0 ){
         2319  +        fprintf(stderr,"Error: out of memory\n");
         2320  +        exit(1);
         2321  +      }
         2322  +      zSql[nSql++] = '\n';
         2323  +      memcpy(&zSql[nSql], zLine, len+1);
         2324  +      nSql += len;
         2325  +    }
         2326  +    if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
         2327  +                && sqlite3_complete(zSql) ){
         2328  +      p->cnt = 0;
         2329  +      open_db(p);
         2330  +      BEGIN_TIMER;
         2331  +      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
         2332  +      END_TIMER;
         2333  +      if( rc || zErrMsg ){
         2334  +        char zPrefix[100];
         2335  +        if( in!=0 || !stdin_is_interactive ){
         2336  +          sqlite3_snprintf(sizeof(zPrefix), zPrefix, 
         2337  +                           "Error: near line %d:", startline);
         2338  +        }else{
         2339  +          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
         2340  +        }
         2341  +        if( zErrMsg!=0 ){
         2342  +          fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
         2343  +          sqlite3_free(zErrMsg);
         2344  +          zErrMsg = 0;
         2345  +        }else{
         2346  +          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
         2347  +        }
         2348  +        errCnt++;
         2349  +      }
         2350  +      free(zSql);
         2351  +      zSql = 0;
         2352  +      nSql = 0;
         2353  +    }
         2354  +  }
         2355  +  if( zSql ){
         2356  +    if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
         2357  +    free(zSql);
         2358  +  }
         2359  +  free(zLine);
         2360  +  return errCnt;
         2361  +}
         2362  +
         2363  +/*
         2364  +** Return a pathname which is the user's home directory.  A
         2365  +** 0 return indicates an error of some kind.  Space to hold the
         2366  +** resulting string is obtained from malloc().  The calling
         2367  +** function should free the result.
         2368  +*/
         2369  +static char *find_home_dir(void){
         2370  +  char *home_dir = NULL;
         2371  +
         2372  +#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
         2373  +  struct passwd *pwent;
         2374  +  uid_t uid = getuid();
         2375  +  if( (pwent=getpwuid(uid)) != NULL) {
         2376  +    home_dir = pwent->pw_dir;
         2377  +  }
         2378  +#endif
         2379  +
         2380  +#if defined(_WIN32_WCE)
         2381  +  /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
         2382  +   */
         2383  +  home_dir = strdup("/");
         2384  +#else
         2385  +
         2386  +#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
         2387  +  if (!home_dir) {
         2388  +    home_dir = getenv("USERPROFILE");
         2389  +  }
         2390  +#endif
         2391  +
         2392  +  if (!home_dir) {
         2393  +    home_dir = getenv("HOME");
         2394  +  }
         2395  +
         2396  +#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
         2397  +  if (!home_dir) {
         2398  +    char *zDrive, *zPath;
         2399  +    int n;
         2400  +    zDrive = getenv("HOMEDRIVE");
         2401  +    zPath = getenv("HOMEPATH");
         2402  +    if( zDrive && zPath ){
         2403  +      n = strlen30(zDrive) + strlen30(zPath) + 1;
         2404  +      home_dir = malloc( n );
         2405  +      if( home_dir==0 ) return 0;
         2406  +      sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
         2407  +      return home_dir;
         2408  +    }
         2409  +    home_dir = "c:\\";
         2410  +  }
         2411  +#endif
         2412  +
         2413  +#endif /* !_WIN32_WCE */
         2414  +
         2415  +  if( home_dir ){
         2416  +    int n = strlen30(home_dir) + 1;
         2417  +    char *z = malloc( n );
         2418  +    if( z ) memcpy(z, home_dir, n);
         2419  +    home_dir = z;
         2420  +  }
         2421  +
         2422  +  return home_dir;
         2423  +}
         2424  +
         2425  +/*
         2426  +** Read input from the file given by sqliterc_override.  Or if that
         2427  +** parameter is NULL, take input from ~/.sqliterc
         2428  +**
         2429  +** Returns the number of errors.
         2430  +*/
         2431  +static int process_sqliterc(
         2432  +  struct callback_data *p,        /* Configuration data */
         2433  +  const char *sqliterc_override   /* Name of config file. NULL to use default */
         2434  +){
         2435  +  char *home_dir = NULL;
         2436  +  const char *sqliterc = sqliterc_override;
         2437  +  char *zBuf = 0;
         2438  +  FILE *in = NULL;
         2439  +  int nBuf;
         2440  +  int rc = 0;
         2441  +
         2442  +  if (sqliterc == NULL) {
         2443  +    home_dir = find_home_dir();
         2444  +    if( home_dir==0 ){
         2445  +#if !defined(__RTP__) && !defined(_WRS_KERNEL)
         2446  +      fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
         2447  +#endif
         2448  +      return 1;
         2449  +    }
         2450  +    nBuf = strlen30(home_dir) + 16;
         2451  +    zBuf = malloc( nBuf );
         2452  +    if( zBuf==0 ){
         2453  +      fprintf(stderr,"%s: Error: out of memory\n",Argv0);
         2454  +      return 1;
         2455  +    }
         2456  +    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
         2457  +    free(home_dir);
         2458  +    sqliterc = (const char*)zBuf;
         2459  +  }
         2460  +  in = fopen(sqliterc,"rb");
         2461  +  if( in ){
         2462  +    if( stdin_is_interactive ){
         2463  +      fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
         2464  +    }
         2465  +    rc = process_input(p,in);
         2466  +    fclose(in);
         2467  +  }
         2468  +  free(zBuf);
         2469  +  return rc;
         2470  +}
         2471  +
         2472  +/*
         2473  +** Show available command line options
         2474  +*/
         2475  +static const char zOptions[] = 
         2476  +  "   -help                show this message\n"
         2477  +  "   -init filename       read/process named file\n"
         2478  +  "   -echo                print commands before execution\n"
         2479  +  "   -[no]header          turn headers on or off\n"
         2480  +  "   -bail                stop after hitting an error\n"
         2481  +  "   -interactive         force interactive I/O\n"
         2482  +  "   -batch               force batch I/O\n"
         2483  +  "   -column              set output mode to 'column'\n"
         2484  +  "   -csv                 set output mode to 'csv'\n"
         2485  +  "   -html                set output mode to HTML\n"
         2486  +  "   -line                set output mode to 'line'\n"
         2487  +  "   -list                set output mode to 'list'\n"
         2488  +  "   -separator 'x'       set output field separator (|)\n"
         2489  +  "   -stats               print memory stats before each finalize\n"
         2490  +  "   -nullvalue 'text'    set text string for NULL values\n"
         2491  +  "   -version             show SQLite version\n"
         2492  +;
         2493  +static void usage(int showDetail){
         2494  +  fprintf(stderr,
         2495  +      "Usage: %s [OPTIONS] FILENAME [SQL]\n"  
         2496  +      "FILENAME is the name of an SQLite database. A new database is created\n"
         2497  +      "if the file does not previously exist.\n", Argv0);
         2498  +  if( showDetail ){
         2499  +    fprintf(stderr, "OPTIONS include:\n%s", zOptions);
         2500  +  }else{
         2501  +    fprintf(stderr, "Use the -help option for additional information\n");
         2502  +  }
         2503  +  exit(1);
         2504  +}
         2505  +
         2506  +/*
         2507  +** Initialize the state information in data
         2508  +*/
         2509  +static void main_init(struct callback_data *data) {
         2510  +  memset(data, 0, sizeof(*data));
         2511  +  data->mode = MODE_List;
         2512  +  memcpy(data->separator,"|", 2);
         2513  +  data->showHeader = 0;
         2514  +  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
         2515  +  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
         2516  +  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
         2517  +  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
         2518  +}
         2519  +
         2520  +int main(int argc, char **argv){
         2521  +  char *zErrMsg = 0;
         2522  +  struct callback_data data;
         2523  +  const char *zInitFile = 0;
         2524  +  char *zFirstCmd = 0;
         2525  +  int i;
         2526  +  int rc = 0;
         2527  +
         2528  +  Argv0 = argv[0];
         2529  +  main_init(&data);
         2530  +  stdin_is_interactive = isatty(0);
         2531  +
         2532  +  /* Make sure we have a valid signal handler early, before anything
         2533  +  ** else is done.
         2534  +  */
         2535  +#ifdef SIGINT
         2536  +  signal(SIGINT, interrupt_handler);
         2537  +#endif
         2538  +
         2539  +  /* Do an initial pass through the command-line argument to locate
         2540  +  ** the name of the database file, the name of the initialization file,
         2541  +  ** and the first command to execute.
         2542  +  */
         2543  +  for(i=1; i<argc-1; i++){
         2544  +    char *z;
         2545  +    if( argv[i][0]!='-' ) break;
         2546  +    z = argv[i];
         2547  +    if( z[0]=='-' && z[1]=='-' ) z++;
         2548  +    if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
         2549  +      i++;
         2550  +    }else if( strcmp(argv[i],"-init")==0 ){
         2551  +      i++;
         2552  +      zInitFile = argv[i];
         2553  +    /* Need to check for batch mode here to so we can avoid printing
         2554  +    ** informational messages (like from process_sqliterc) before 
         2555  +    ** we do the actual processing of arguments later in a second pass.
         2556  +    */
         2557  +    }else if( strcmp(argv[i],"-batch")==0 ){
         2558  +      stdin_is_interactive = 0;
         2559  +    }
         2560  +  }
         2561  +  if( i<argc ){
         2562  +#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
         2563  +    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
         2564  +#else
         2565  +    data.zDbFilename = argv[i++];
         2566  +#endif
         2567  +  }else{
         2568  +#ifndef SQLITE_OMIT_MEMORYDB
         2569  +    data.zDbFilename = ":memory:";
         2570  +#else
         2571  +    data.zDbFilename = 0;
         2572  +#endif
         2573  +    /***** Begin Fossil Patch *****/
         2574  +    {
         2575  +      extern void fossil_open(sqlite3**, const char **);
         2576  +      fossil_open(&data.db, &data.zDbFilename);
         2577  +    }
         2578  +    /***** End Fossil Patch *****/
         2579  +  }
         2580  +  if( i<argc ){
         2581  +    zFirstCmd = argv[i++];
         2582  +  }
         2583  +  if( i<argc ){
         2584  +    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
         2585  +    fprintf(stderr,"Use -help for a list of options.\n");
         2586  +    return 1;
         2587  +  }
         2588  +  data.out = stdout;
         2589  +
         2590  +#ifdef SQLITE_OMIT_MEMORYDB
         2591  +  if( data.zDbFilename==0 ){
         2592  +    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
         2593  +    return 1;
         2594  +  }
         2595  +#endif
         2596  +
         2597  +  /* Go ahead and open the database file if it already exists.  If the
         2598  +  ** file does not exist, delay opening it.  This prevents empty database
         2599  +  ** files from being created if a user mistypes the database name argument
         2600  +  ** to the sqlite command-line tool.
         2601  +  */
         2602  +  if( access(data.zDbFilename, 0)==0 ){
         2603  +    open_db(&data);
         2604  +  }
         2605  +
         2606  +  /* Process the initialization file if there is one.  If no -init option
         2607  +  ** is given on the command line, look for a file named ~/.sqliterc and
         2608  +  ** try to process it.
         2609  +  */
         2610  +  rc = process_sqliterc(&data,zInitFile);
         2611  +  if( rc>0 ){
         2612  +    return rc;
         2613  +  }
         2614  +
         2615  +  /* Make a second pass through the command-line argument and set
         2616  +  ** options.  This second pass is delayed until after the initialization
         2617  +  ** file is processed so that the command-line arguments will override
         2618  +  ** settings in the initialization file.
         2619  +  */
         2620  +  for(i=1; i<argc && argv[i][0]=='-'; i++){
         2621  +    char *z = argv[i];
         2622  +    if( z[1]=='-' ){ z++; }
         2623  +    if( strcmp(z,"-init")==0 ){
         2624  +      i++;
         2625  +    }else if( strcmp(z,"-html")==0 ){
         2626  +      data.mode = MODE_Html;
         2627  +    }else if( strcmp(z,"-list")==0 ){
         2628  +      data.mode = MODE_List;
         2629  +    }else if( strcmp(z,"-line")==0 ){
         2630  +      data.mode = MODE_Line;
         2631  +    }else if( strcmp(z,"-column")==0 ){
         2632  +      data.mode = MODE_Column;
         2633  +    }else if( strcmp(z,"-csv")==0 ){
         2634  +      data.mode = MODE_Csv;
         2635  +      memcpy(data.separator,",",2);
         2636  +    }else if( strcmp(z,"-separator")==0 ){
         2637  +      i++;
         2638  +      if(i>=argc){
         2639  +        fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
         2640  +        fprintf(stderr,"Use -help for a list of options.\n");
         2641  +        return 1;
         2642  +      }
         2643  +      sqlite3_snprintf(sizeof(data.separator), data.separator,
         2644  +                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
         2645  +    }else if( strcmp(z,"-nullvalue")==0 ){
         2646  +      i++;
         2647  +      if(i>=argc){
         2648  +        fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
         2649  +        fprintf(stderr,"Use -help for a list of options.\n");
         2650  +        return 1;
         2651  +      }
         2652  +      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
         2653  +                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
         2654  +    }else if( strcmp(z,"-header")==0 ){
         2655  +      data.showHeader = 1;
         2656  +    }else if( strcmp(z,"-noheader")==0 ){
         2657  +      data.showHeader = 0;
         2658  +    }else if( strcmp(z,"-echo")==0 ){
         2659  +      data.echoOn = 1;
         2660  +    }else if( strcmp(z,"-stats")==0 ){
         2661  +      data.statsOn = 1;
         2662  +    }else if( strcmp(z,"-bail")==0 ){
         2663  +      bail_on_error = 1;
         2664  +    }else if( strcmp(z,"-version")==0 ){
         2665  +      printf("%s\n", sqlite3_libversion());
         2666  +      return 0;
         2667  +    }else if( strcmp(z,"-interactive")==0 ){
         2668  +      stdin_is_interactive = 1;
         2669  +    }else if( strcmp(z,"-batch")==0 ){
         2670  +      stdin_is_interactive = 0;
         2671  +    }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
         2672  +      usage(1);
         2673  +    }else{
         2674  +      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
         2675  +      fprintf(stderr,"Use -help for a list of options.\n");
         2676  +      return 1;
         2677  +    }
         2678  +  }
         2679  +
         2680  +  if( zFirstCmd ){
         2681  +    /* Run just the command that follows the database name
         2682  +    */
         2683  +    if( zFirstCmd[0]=='.' ){
         2684  +      rc = do_meta_command(zFirstCmd, &data);
         2685  +    }else{
         2686  +      open_db(&data);
         2687  +      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
         2688  +      if( zErrMsg!=0 ){
         2689  +        fprintf(stderr,"Error: %s\n", zErrMsg);
         2690  +        return rc!=0 ? rc : 1;
         2691  +      }else if( rc!=0 ){
         2692  +        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
         2693  +        return rc;
         2694  +      }
         2695  +    }
         2696  +  }else{
         2697  +    /* Run commands received from standard input
         2698  +    */
         2699  +    if( stdin_is_interactive ){
         2700  +      char *zHome;
         2701  +      char *zHistory = 0;
         2702  +      int nHistory;
         2703  +      printf(
         2704  +        "SQLite version %s\n"
         2705  +        "Enter \".help\" for instructions\n"
         2706  +        "Enter SQL statements terminated with a \";\"\n",
         2707  +        sqlite3_libversion()
         2708  +      );
         2709  +      zHome = find_home_dir();
         2710  +      if( zHome ){
         2711  +        nHistory = strlen30(zHome) + 20;
         2712  +        if( (zHistory = malloc(nHistory))!=0 ){
         2713  +          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
         2714  +        }
         2715  +      }
         2716  +#if defined(HAVE_READLINE) && HAVE_READLINE==1
         2717  +      if( zHistory ) read_history(zHistory);
         2718  +#endif
         2719  +      rc = process_input(&data, 0);
         2720  +      if( zHistory ){
         2721  +        stifle_history(100);
         2722  +        write_history(zHistory);
         2723  +        free(zHistory);
         2724  +      }
         2725  +      free(zHome);
         2726  +    }else{
         2727  +      rc = process_input(&data, stdin);
         2728  +    }
         2729  +  }
         2730  +  set_table_name(&data, 0);
         2731  +  if( data.db ){
         2732  +    if( sqlite3_close(data.db)!=SQLITE_OK ){
         2733  +      fprintf(stderr,"Error: cannot close database \"%s\"\n",
         2734  +              sqlite3_errmsg(db));
         2735  +      rc++;
         2736  +    }
         2737  +  }
         2738  +  return rc;
         2739  +}

Changes to src/shun.c.

    67     67       }
    68     68     }
    69     69     style_header("Shunned Artifacts");
    70     70     if( zUuid && P("sub") ){
    71     71       login_verify_csrf_secret();
    72     72       db_multi_exec("DELETE FROM shun WHERE uuid='%s'", zUuid);
    73     73       if( db_exists("SELECT 1 FROM blob WHERE uuid='%s'", zUuid) ){
    74         -      @ <p><font color="blue">Artifact 
           74  +      @ <p class="noMoreShun">Artifact 
    75     75         @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> is no
    76         -      @ longer being shunned.</font></p>
           76  +      @ longer being shunned.</p>
    77     77       }else{
    78         -      @ <p><font color="blue">Artifact %s(zUuid)</a> will no longer
           78  +      @ <p class="noMoreShun">Artifact %s(zUuid) will no longer
    79     79         @ be shunned.  But it does not exist in the repository.  It
    80     80         @ may be necessary to rebuild the repository using the
    81     81         @ <b>fossil rebuild</b> command-line before the artifact content
    82         -      @ can pulled in from other respositories.</font></p>
           82  +      @ can pulled in from other respositories.</p>
    83     83       }
    84     84     }
    85     85     if( zUuid && P("add") ){
    86     86       login_verify_csrf_secret();
    87     87       db_multi_exec("INSERT OR IGNORE INTO shun VALUES('%s')", zUuid);
    88         -    @ <p><font color="blue">Artifact
           88  +    @ <p class="shunned">Artifact
    89     89       @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> has been
    90     90       @ shunned.  It will no longer be pushed.
    91     91       @ It will be removed from the repository the next time the respository
    92         -    @ is rebuilt using the <b>fossil rebuild</b> command-line</font></p>
           92  +    @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
    93     93     }
    94     94     @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
    95     95     @ artifact content will be purged from the repository the next time the
    96     96     @ repository is rebuilt.  A list of shunned artifacts can be seen at the
    97     97     @ bottom of this page.</p>
    98     98     @ 
    99     99     @ <a name="addshun"></a>
................................................................................
   110    110     @ from the repository.  Inappropriate content includes such things as
   111    111     @ spam added to Wiki, files that violate copyright or patent agreements,
   112    112     @ or artifacts that by design or accident interfere with the processing
   113    113     @ of the repository.  Do not shun artifacts merely to remove them from
   114    114     @ sight - set the "hidden" tag on such artifacts instead.</p>
   115    115     @ 
   116    116     @ <blockquote>
   117         -  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
          117  +  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   118    118     login_insert_csrf_secret();
   119         -  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50">
   120         -  @ <input type="submit" name="add" value="Shun">
   121         -  @ </form>
          119  +  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
          120  +  @ <input type="submit" name="add" value="Shun" />
          121  +  @ </div></form>
   122    122     @ </blockquote>
   123    123     @
   124    124     @ <p>Enter the UUID of a previous shunned artifact to cause it to be
   125    125     @ accepted again in the repository.  The artifact content is not
   126    126     @ restored because the content is unknown.  The only change is that
   127    127     @ the formerly shunned artifact will be accepted on subsequent sync
   128    128     @ operations.</p>
   129    129     @
   130    130     @ <blockquote>
   131         -  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
          131  +  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   132    132     login_insert_csrf_secret();
   133         -  @ <input type="text" name="uuid" size="50">
   134         -  @ <input type="submit" name="sub" value="Accept">
   135         -  @ </form>
          133  +  @ <input type="text" name="uuid" size="50" />
          134  +  @ <input type="submit" name="sub" value="Accept" />
          135  +  @ </div></form>
   136    136     @ </blockquote>
   137    137     @
   138    138     @ <p>Press the Rebuild button below to rebuild the respository.  The
   139    139     @ content of newly shunned artifacts is not purged until the repository
   140    140     @ is rebuilt.  On larger repositories, the rebuild may take minute or
   141    141     @ two, so be patient after pressing the button.</p>
   142    142     @
   143    143     @ <blockquote>
   144         -  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
          144  +  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   145    145     login_insert_csrf_secret();
   146         -  @ <input type="submit" name="rebuild" value="Rebuild">
   147         -  @ </form>
          146  +  @ <input type="submit" name="rebuild" value="Rebuild" />
          147  +  @ </div></form>
   148    148     @ </blockquote>
   149    149     @ 
   150         -  @ <hr><p>Shunned Artifacts:</p>
   151         -  @ <blockquote>
          150  +  @ <hr /><p>Shunned Artifacts:</p>
          151  +  @ <blockquote><p>
   152    152     db_prepare(&q, 
   153    153        "SELECT uuid, EXISTS(SELECT 1 FROM blob WHERE blob.uuid=shun.uuid)"
   154    154        "  FROM shun ORDER BY uuid");
   155    155     while( db_step(&q)==SQLITE_ROW ){
   156    156       const char *zUuid = db_column_text(&q, 0);
   157    157       int stillExists = db_column_int(&q, 1);
   158    158       cnt++;
   159    159       if( stillExists ){
   160         -      @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br>
          160  +      @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br />
   161    161       }else{
   162         -      @ <b>%s(zUuid)</b><br>
          162  +      @ <b>%s(zUuid)</b><br />
   163    163       }
   164    164     }
   165    165     if( cnt==0 ){
   166    166       @ <i>no artifacts are shunned on this server</i>
   167    167     }
   168    168     db_finalize(&q);
   169         -  @ </blockquote>
          169  +  @ </p></blockquote>
   170    170     style_footer();
   171    171   }
   172    172   
   173    173   /*
   174    174   ** Remove from the BLOB table all artifacts that are in the SHUN table.
   175    175   */
   176    176   void shun_artifacts(void){
................................................................................
   227    227     @ finding and fixing attempts to inject illicit content into the
   228    228     @ repository.</p>
   229    229     @
   230    230     @ <p>Click on the "rcvid" to show a list of specific artifacts received
   231    231     @ by a transaction.  After identifying illicit artifacts, remove them
   232    232     @ using the "Shun" feature.</p>
   233    233     @
   234         -  @ <table cellpadding=0 cellspacing=0 border=0>
   235         -  @ <tr><th>rcvid</th><th width=15>
   236         -  @     <th>Date</th><th width=15><th>User</th>
   237         -  @     <th width=15><th>IP&nbsp;Address</th></tr>
          234  +  @ <table cellpadding="0" cellspacing="0" border="0">
          235  +  @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th>
          236  +  @     <th style="padding-right: 15px;text-align: left;">Date</th>
          237  +  @     <th style="padding-right: 15px;text-align: left;">User</th>
          238  +  @     <th style="text-align: left;">IP&nbsp;Address</th></tr>
   238    239     cnt = 0;
   239    240     while( db_step(&q)==SQLITE_ROW ){
   240    241       int rcvid = db_column_int(&q, 0);
   241    242       const char *zUser = db_column_text(&q, 1);
   242    243       const char *zDate = db_column_text(&q, 2);
   243    244       const char *zIpAddr = db_column_text(&q, 3);
   244    245       if( cnt==30 ){
   245    246         style_submenu_element("Older", "Older",
   246    247            "rcvfromlist?ofst=%d", ofst+30);
   247    248       }else{
   248    249         cnt++;
   249    250         @ <tr>
   250         -      @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td>
   251         -      @ <td>%s(zDate)</td><td>
   252         -      @ <td>%h(zUser)</td><td>
   253         -      @ <td>&nbsp;%s(zIpAddr)&nbsp</td>
          251  +      @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td>
          252  +      @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td>
          253  +      @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td>
          254  +      @ <td style="text-align: left;">%s(zIpAddr)</td>
   254    255         @ </tr>
   255    256       }
   256    257     }
   257    258     db_finalize(&q);
   258    259     @ </table>
   259    260     style_footer();
   260    261   }
................................................................................
   275    276     style_header("Content Source %d", rcvid);
   276    277     db_prepare(&q, 
   277    278       "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
   278    279       "  FROM rcvfrom LEFT JOIN user USING(uid)"
   279    280       " WHERE rcvid=%d",
   280    281       rcvid
   281    282     );
   282         -  @ <table cellspacing=15 cellpadding=0 border=0>
          283  +  @ <table cellspacing="15" cellpadding="0" border="0">
   283    284     @ <tr><td valign="top" align="right"><b>rcvid:</b></td>
   284    285     @ <td valign="top">%d(rcvid)</td></tr>
   285    286     if( db_step(&q)==SQLITE_ROW ){
   286    287       const char *zUser = db_column_text(&q, 0);
   287    288       const char *zDate = db_column_text(&q, 1);
   288    289       const char *zIpAddr = db_column_text(&q, 2);
   289    290       @ <tr><td valign="top" align="right"><b>User:</b></td>
................................................................................
   300    301     @ <tr><td valign="top" align="right"><b>Artifacts:</b></td>
   301    302     @ <td valign="top">
   302    303     while( db_step(&q)==SQLITE_ROW ){
   303    304       int rid = db_column_int(&q, 0);
   304    305       const char *zUuid = db_column_text(&q, 1);
   305    306       int size = db_column_int(&q, 2);
   306    307       @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a>
   307         -    @ (rid: %d(rid), size: %d(size))<br>
          308  +    @ (rid: %d(rid), size: %d(size))<br />
   308    309     }
   309    310     @ </td></tr>
   310    311     @ </table>
          312  +  db_finalize(&q);
          313  +  style_footer();
   311    314   }

Changes to src/skins.c.

   163    163   @       media="screen">
   164    164   @ </head>
   165    165   @ <body>
   166    166   @ <div class="header">
   167    167   @   <div class="logo">
   168    168   @     <img src="$baseurl/logo" alt="logo">
   169    169   @   </div>
   170         -@   <div class="title"><small>$<project_name></small><br>$<title></div>
          170  +@   <div class="title"><small>$<project_name></small><br />$<title></div>
   171    171   @   <div class="status"><nobr><th1>
   172    172   @      if {[info exists login]} {
   173    173   @        puts "Logged in as $login"
   174    174   @      } else {
   175    175   @        puts "Not logged in"
   176    176   @      }
   177    177   @   </th1></nobr></div>
................................................................................
   598    598   @ <link rel="stylesheet" href="$baseurl/style.css?black2" type="text/css"
   599    599   @       media="screen">
   600    600   @ </head>
   601    601   @ <body>
   602    602   @ <div class="header">
   603    603   @   <div class="logo">
   604    604   @     <!-- <img src="$baseurl/logo" alt="logo"> -->
   605         -@     <br><nobr>$<project_name></nobr>
          605  +@     <br /><nobr>$<project_name></nobr>
   606    606   @   </div>
   607    607   @   <div class="title">$<title></div>
   608    608   @   <div class="status"><nobr><th1>
   609    609   @      if {[info exists login]} {
   610    610   @        puts "Logged in as $login"
   611    611   @      } else {
   612    612   @        puts "Not logged in"
................................................................................
   654    654   ;
   655    655   /*
   656    656   ** An array of available built-in skins.
   657    657   */
   658    658   static struct BuiltinSkin {
   659    659     const char *zName;
   660    660     const char *zValue;
          661  +  const char *zAuthor;
   661    662   } aBuiltinSkin[] = {
   662         -  { "Default",                     0 /* Filled in at runtime */ },
   663         -  { "Plain Gray, No Logo",         zBuiltinSkin1                },
   664         -  { "Khaki, No Logo",              zBuiltinSkin2                },
   665         -  { "Black & White, Menu on Left", zBuiltinSkin3                },
          663  +  { "Default",                     0 /* Filled in at runtime */, 0},
          664  +  { "Plain Gray, No Logo",         zBuiltinSkin1,                "Unknown"},
          665  +  { "Khaki, No Logo",              zBuiltinSkin2,                "Unknown"},
          666  +  { "Black & White, Menu on Left", zBuiltinSkin3,                "Unknown"},
   666    667   };
   667    668   
   668    669   /*
   669    670   ** For a skin named zSkinName, compute the name of the CONFIG table
   670    671   ** entry where that skin is stored and return it.
   671    672   **
   672    673   ** Return NULL if zSkinName is NULL or an empty string.
................................................................................
   729    730       login_needed();
   730    731     }
   731    732     db_begin_transaction();
   732    733   
   733    734     /* Process requests to delete a user-defined skin */
   734    735     if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
   735    736       style_header("Confirm Custom Skin Delete");
   736         -    @ <form action="%s(g.zBaseURL)/setup_skin" method="POST">
          737  +    @ <form action="%s(g.zBaseURL)/setup_skin" method="post"><div>
   737    738       @ <p>Deletion of a custom skin is a permanent action that cannot
   738    739       @ be undone.  Please confirm that this is what you want to do:</p>
   739         -    @ <input type="hidden" name="sn" value="%h(P("sn"))">
   740         -    @ <input type="submit" name="del2" value="Confirm - Delete The Skin">
   741         -    @ <input type="submit" name="cancel" value="Cancel - Do Not Delete">
          740  +    @ <input type="hidden" name="sn" value="%h(P("sn"))" />
          741  +    @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
          742  +    @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
   742    743       login_insert_csrf_secret();
   743         -    @ </form>
          744  +    @ </div></form>
   744    745       style_footer();
   745    746       return;
   746    747     }
   747    748     if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
   748    749       db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
   749    750     }
   750    751   
................................................................................
   810    811     @ <h2>Available Skins:</h2>
   811    812     @ <ol>
   812    813     for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
   813    814       z = aBuiltinSkin[i].zName;
   814    815       if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){
   815    816         @ <li><p>%h(z).&nbsp;&nbsp; <b>Currently In Use</b></p>
   816    817       }else{
   817         -      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="POST">
          818  +      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="post"><div>
   818    819         @ %h(z).&nbsp;&nbsp; 
   819         -      @ <input type="hidden" name="sn" value="%h(z)">
   820         -      @ <input type="submit" name="load" value="Use This Skin">
   821         -      @ </form></li>
          820  +      @ <input type="hidden" name="sn" value="%h(z)" />
          821  +      @ <input type="submit" name="load" value="Use This Skin" />
          822  +      @ </div></form></li>
   822    823       }
   823    824     }
   824    825     db_prepare(&q,
   825    826        "SELECT substr(name, 6), value FROM config"
   826    827        " WHERE name GLOB 'skin:*'"
   827    828        " ORDER BY name"
   828    829     );
   829    830     while( db_step(&q)==SQLITE_ROW ){
   830    831       const char *zN = db_column_text(&q, 0);
   831    832       const char *zV = db_column_text(&q, 1);
   832    833       if( strcmp(zV, zCurrent)==0 ){
   833    834         @ <li><p>%h(zN).&nbsp;&nbsp;  <b>Currently In Use</b></p>
   834    835       }else{
   835         -      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="POST">
          836  +      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="post">
   836    837         @ %h(zN).&nbsp;&nbsp; 
   837    838         @ <input type="hidden" name="sn" value="%h(zN)">
   838    839         @ <input type="submit" name="load" value="Use This Skin">
   839    840         @ <input type="submit" name="del1" value="Delete This Skin">
   840    841         @ </form></li>
   841    842       }
   842    843     }
   843    844     db_finalize(&q);
   844    845     @ </ol>
   845    846     style_footer();
   846    847     db_end_transaction(0);
   847    848   }

Changes to src/sqlite3.c.

     1      1   /******************************************************************************
     2      2   ** This file is an amalgamation of many separate C source files from SQLite
     3         -** version 3.7.1.  By combining all the individual C code files into this 
            3  +** version 3.7.3.  By combining all the individual C code files into this 
     4      4   ** single large file, the entire code can be compiled as a one translation
     5      5   ** unit.  This allows many compilers to do optimizations that would not be
     6      6   ** possible if the files were compiled separately.  Performance improvements
     7      7   ** of 5% are more are commonly seen when SQLite is compiled as a single
     8      8   ** translation unit.
     9      9   **
    10     10   ** This file is all you need to compile SQLite.  To use SQLite in other
................................................................................
   211    211   /*
   212    212   ** The maximum value of a ?nnn wildcard that the parser will accept.
   213    213   */
   214    214   #ifndef SQLITE_MAX_VARIABLE_NUMBER
   215    215   # define SQLITE_MAX_VARIABLE_NUMBER 999
   216    216   #endif
   217    217   
   218         -/* Maximum page size.  The upper bound on this value is 32768.  This a limit
   219         -** imposed by the necessity of storing the value in a 2-byte unsigned integer
   220         -** and the fact that the page size must be a power of 2.
          218  +/* Maximum page size.  The upper bound on this value is 65536.  This a limit
          219  +** imposed by the use of 16-bit offsets within each page.
   221    220   **
   222         -** If this limit is changed, then the compiled library is technically
   223         -** incompatible with an SQLite library compiled with a different limit. If
   224         -** a process operating on a database with a page-size of 65536 bytes 
   225         -** crashes, then an instance of SQLite compiled with the default page-size 
   226         -** limit will not be able to rollback the aborted transaction. This could
   227         -** lead to database corruption.
          221  +** Earlier versions of SQLite allowed the user to change this value at
          222  +** compile time. This is no longer permitted, on the grounds that it creates
          223  +** a library that is technically incompatible with an SQLite library 
          224  +** compiled with a different limit. If a process operating on a database 
          225  +** with a page-size of 65536 bytes crashes, then an instance of SQLite 
          226  +** compiled with the default page-size limit will not be able to rollback 
          227  +** the aborted transaction. This could lead to database corruption.
   228    228   */
   229         -#ifndef SQLITE_MAX_PAGE_SIZE
   230         -# define SQLITE_MAX_PAGE_SIZE 32768
          229  +#ifdef SQLITE_MAX_PAGE_SIZE
          230  +# undef SQLITE_MAX_PAGE_SIZE
   231    231   #endif
          232  +#define SQLITE_MAX_PAGE_SIZE 65536
   232    233   
   233    234   
   234    235   /*
   235    236   ** The default size of a database page.
   236    237   */
   237    238   #ifndef SQLITE_DEFAULT_PAGE_SIZE
   238    239   # define SQLITE_DEFAULT_PAGE_SIZE 1024
................................................................................
   349    350   # define SQLITE_PTR_TO_INT(X)  ((int)(intptr_t)(X))
   350    351   #else                          /* Generates a warning - but it always works */
   351    352   # define SQLITE_INT_TO_PTR(X)  ((void*)(X))
   352    353   # define SQLITE_PTR_TO_INT(X)  ((int)(X))
   353    354   #endif
   354    355   
   355    356   /*
   356         -** The SQLITE_THREADSAFE macro must be defined as either 0 or 1.
          357  +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
          358  +** 0 means mutexes are permanently disable and the library is never
          359  +** threadsafe.  1 means the library is serialized which is the highest
          360  +** level of threadsafety.  2 means the libary is multithreaded - multiple
          361  +** threads can use SQLite as long as no two threads try to use the same
          362  +** database connection at the same time.
          363  +**
   357    364   ** Older versions of SQLite used an optional THREADSAFE macro.
   358         -** We support that for legacy
          365  +** We support that for legacy.
   359    366   */
   360    367   #if !defined(SQLITE_THREADSAFE)
   361    368   #if defined(THREADSAFE)
   362    369   # define SQLITE_THREADSAFE THREADSAFE
   363    370   #else
   364         -# define SQLITE_THREADSAFE 1
          371  +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
   365    372   #endif
   366    373   #endif
   367    374   
   368    375   /*
   369    376   ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
   370    377   ** It determines whether or not the features related to 
   371    378   ** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
................................................................................
   629    636   ** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
   630    637   ** be larger than the release from which it is derived.  Either Y will
   631    638   ** be held constant and Z will be incremented or else Y will be incremented
   632    639   ** and Z will be reset to zero.
   633    640   **
   634    641   ** Since version 3.6.18, SQLite source code has been stored in the
   635    642   ** <a href="http://www.fossil-scm.org/">Fossil configuration management
   636         -** system</a>.  ^The SQLITE_SOURCE_ID macro evalutes to
          643  +** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
   637    644   ** a string which identifies a particular check-in of SQLite
   638    645   ** within its configuration management system.  ^The SQLITE_SOURCE_ID
   639    646   ** string contains the date and time of the check-in (UTC) and an SHA1
   640    647   ** hash of the entire source tree.
   641    648   **
   642    649   ** See also: [sqlite3_libversion()],
   643    650   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   644    651   ** [sqlite_version()] and [sqlite_source_id()].
   645    652   */
   646         -#define SQLITE_VERSION        "3.7.1"
   647         -#define SQLITE_VERSION_NUMBER 3007001
   648         -#define SQLITE_SOURCE_ID      "2010-08-05 03:21:40 fbe70e1106bcc5086ceb9d8f39cc39baf3643092"
          653  +#define SQLITE_VERSION        "3.7.3"
          654  +#define SQLITE_VERSION_NUMBER 3007003
          655  +#define SQLITE_SOURCE_ID      "2010-10-07 13:29:13 e55ada89246d4cc5f476891c70572dc7c1c3643e"
   649    656   
   650    657   /*
   651    658   ** CAPI3REF: Run-Time Library Version Numbers
   652    659   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   653    660   **
   654    661   ** These interfaces provide the same information as the [SQLITE_VERSION],
   655    662   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
   686    693   ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
   687    694   **
   688    695   ** ^The sqlite3_compileoption_used() function returns 0 or 1 
   689    696   ** indicating whether the specified option was defined at 
   690    697   ** compile time.  ^The SQLITE_ prefix may be omitted from the 
   691    698   ** option name passed to sqlite3_compileoption_used().  
   692    699   **
   693         -** ^The sqlite3_compileoption_get() function allows interating
          700  +** ^The sqlite3_compileoption_get() function allows iterating
   694    701   ** over the list of options that were defined at compile time by
   695    702   ** returning the N-th compile time option string.  ^If N is out of range,
   696    703   ** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_ 
   697    704   ** prefix is omitted from any strings returned by 
   698    705   ** sqlite3_compileoption_get().
   699    706   **
   700    707   ** ^Support for the diagnostic functions sqlite3_compileoption_used()
   701         -** and sqlite3_compileoption_get() may be omitted by specifing the 
          708  +** and sqlite3_compileoption_get() may be omitted by specifying the 
   702    709   ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
   703    710   **
   704    711   ** See also: SQL functions [sqlite_compileoption_used()] and
   705    712   ** [sqlite_compileoption_get()] and the [compile_options pragma].
   706    713   */
   707    714   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   708    715   SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
................................................................................
   800    807   #endif
   801    808   
   802    809   /*
   803    810   ** CAPI3REF: Closing A Database Connection
   804    811   **
   805    812   ** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
   806    813   ** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
   807         -** successfullly destroyed and all associated resources are deallocated.
          814  +** successfully destroyed and all associated resources are deallocated.
   808    815   **
   809    816   ** Applications must [sqlite3_finalize | finalize] all [prepared statements]
   810    817   ** and [sqlite3_blob_close | close] all [BLOB handles] associated with
   811    818   ** the [sqlite3] object prior to attempting to close the object.  ^If
   812    819   ** sqlite3_close() is called on a [database connection] that still has
   813    820   ** outstanding [prepared statements] or [BLOB handles], then it returns
   814    821   ** SQLITE_BUSY.
................................................................................
  1227   1234   **
  1228   1235   ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
  1229   1236   ** layer a hint of how large the database file will grow to be during the
  1230   1237   ** current transaction.  This hint is not guaranteed to be accurate but it
  1231   1238   ** is often close.  The underlying VFS might choose to preallocate database
  1232   1239   ** file space based on this hint in order to help writes to the database
  1233   1240   ** file run faster.
         1241  +**
         1242  +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
         1243  +** extends and truncates the database file in chunks of a size specified
         1244  +** by the user. The fourth argument to [sqlite3_file_control()] should 
         1245  +** point to an integer (type int) containing the new chunk-size to use
         1246  +** for the nominated database. Allocating database file space in large
         1247  +** chunks (say 1MB at a time), may reduce file-system fragmentation and
         1248  +** improve performance on some systems.
  1234   1249   */
  1235   1250   #define SQLITE_FCNTL_LOCKSTATE        1
  1236   1251   #define SQLITE_GET_LOCKPROXYFILE      2
  1237   1252   #define SQLITE_SET_LOCKPROXYFILE      3
  1238   1253   #define SQLITE_LAST_ERRNO             4
  1239   1254   #define SQLITE_FCNTL_SIZE_HINT        5
         1255  +#define SQLITE_FCNTL_CHUNK_SIZE       6
  1240   1256   
  1241   1257   /*
  1242   1258   ** CAPI3REF: Mutex Handle
  1243   1259   **
  1244   1260   ** The mutex module within SQLite defines [sqlite3_mutex] to be an
  1245   1261   ** abstract type for a mutex object.  The SQLite core never looks
  1246   1262   ** at the internal representation of an [sqlite3_mutex].  It only
................................................................................
  1280   1296   ** or modify this field while holding a particular static mutex.
  1281   1297   ** The application should never modify anything within the sqlite3_vfs
  1282   1298   ** object once the object has been registered.
  1283   1299   **
  1284   1300   ** The zName field holds the name of the VFS module.  The name must
  1285   1301   ** be unique across all VFS modules.
  1286   1302   **
  1287         -** SQLite will guarantee that the zFilename parameter to xOpen
         1303  +** ^SQLite guarantees that the zFilename parameter to xOpen
  1288   1304   ** is either a NULL pointer or string obtained
  1289         -** from xFullPathname().  SQLite further guarantees that
         1305  +** from xFullPathname() with an optional suffix added.
         1306  +** ^If a suffix is added to the zFilename parameter, it will
         1307  +** consist of a single "-" character followed by no more than
         1308  +** 10 alphanumeric and/or "-" characters.
         1309  +** ^SQLite further guarantees that
  1290   1310   ** the string will be valid and unchanged until xClose() is
  1291   1311   ** called. Because of the previous sentence,
  1292   1312   ** the [sqlite3_file] can safely store a pointer to the
  1293   1313   ** filename if it needs to remember the filename for some reason.
  1294         -** If the zFilename parameter is xOpen is a NULL pointer then xOpen
  1295         -** must invent its own temporary name for the file.  Whenever the 
         1314  +** If the zFilename parameter to xOpen is a NULL pointer then xOpen
         1315  +** must invent its own temporary name for the file.  ^Whenever the 
  1296   1316   ** xFilename parameter is NULL it will also be the case that the
  1297   1317   ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
  1298   1318   **
  1299   1319   ** The flags argument to xOpen() includes all bits set in
  1300   1320   ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
  1301   1321   ** or [sqlite3_open16()] is used, then flags includes at least
  1302   1322   ** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. 
  1303   1323   ** If xOpen() opens a file read-only then it sets *pOutFlags to
  1304   1324   ** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
  1305   1325   **
  1306         -** SQLite will also add one of the following flags to the xOpen()
         1326  +** ^(SQLite will also add one of the following flags to the xOpen()
  1307   1327   ** call, depending on the object being opened:
  1308   1328   **
  1309   1329   ** <ul>
  1310   1330   ** <li>  [SQLITE_OPEN_MAIN_DB]
  1311   1331   ** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
  1312   1332   ** <li>  [SQLITE_OPEN_TEMP_DB]
  1313   1333   ** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
  1314   1334   ** <li>  [SQLITE_OPEN_TRANSIENT_DB]
  1315   1335   ** <li>  [SQLITE_OPEN_SUBJOURNAL]
  1316   1336   ** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
  1317         -** </ul>
         1337  +** <li>  [SQLITE_OPEN_WAL]
         1338  +** </ul>)^
  1318   1339   **
  1319   1340   ** The file I/O implementation can use the object type flags to
  1320   1341   ** change the way it deals with files.  For example, an application
  1321   1342   ** that does not care about crash recovery or rollback might make
  1322   1343   ** the open of a journal file a no-op.  Writes to this journal would
  1323   1344   ** also be no-ops, and any attempt to read the journal would return
  1324   1345   ** SQLITE_IOERR.  Or the implementation might recognize that a database
................................................................................
  1329   1350   **
  1330   1351   ** <ul>
  1331   1352   ** <li> [SQLITE_OPEN_DELETEONCLOSE]
  1332   1353   ** <li> [SQLITE_OPEN_EXCLUSIVE]
  1333   1354   ** </ul>
  1334   1355   **
  1335   1356   ** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
  1336         -** deleted when it is closed.  The [SQLITE_OPEN_DELETEONCLOSE]
  1337         -** will be set for TEMP  databases, journals and for subjournals.
         1357  +** deleted when it is closed.  ^The [SQLITE_OPEN_DELETEONCLOSE]
         1358  +** will be set for TEMP databases and their journals, transient
         1359  +** databases, and subjournals.
  1338   1360   **
  1339         -** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
         1361  +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
  1340   1362   ** with the [SQLITE_OPEN_CREATE] flag, which are both directly
  1341   1363   ** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
  1342   1364   ** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
  1343   1365   ** SQLITE_OPEN_CREATE, is used to indicate that file should always
  1344   1366   ** be created, and that it is an error if it already exists.
  1345   1367   ** It is <i>not</i> used to indicate the file should be opened 
  1346   1368   ** for exclusive access.
  1347   1369   **
  1348         -** At least szOsFile bytes of memory are allocated by SQLite
         1370  +** ^At least szOsFile bytes of memory are allocated by SQLite
  1349   1371   ** to hold the  [sqlite3_file] structure passed as the third
  1350   1372   ** argument to xOpen.  The xOpen method does not have to
  1351   1373   ** allocate the structure; it should just fill it in.  Note that
  1352   1374   ** the xOpen method must set the sqlite3_file.pMethods to either
  1353   1375   ** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
  1354   1376   ** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
  1355   1377   ** element will be valid after xOpen returns regardless of the success
  1356   1378   ** or failure of the xOpen call.
  1357   1379   **
  1358         -** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
         1380  +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
  1359   1381   ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
  1360   1382   ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
  1361   1383   ** to test whether a file is at least readable.   The file can be a
  1362   1384   ** directory.
  1363   1385   **
  1364         -** SQLite will always allocate at least mxPathname+1 bytes for the
         1386  +** ^SQLite will always allocate at least mxPathname+1 bytes for the
  1365   1387   ** output buffer xFullPathname.  The exact size of the output buffer
  1366   1388   ** is also passed as a parameter to both  methods. If the output buffer
  1367   1389   ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
  1368   1390   ** handled as a fatal error by SQLite, vfs implementations should endeavor
  1369   1391   ** to prevent this by setting mxPathname to a sufficiently large value.
  1370   1392   **
  1371   1393   ** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
  1372   1394   ** interfaces are not strictly a part of the filesystem, but they are
  1373   1395   ** included in the VFS structure for completeness.
  1374   1396   ** The xRandomness() function attempts to return nBytes bytes
  1375   1397   ** of good-quality randomness into zOut.  The return value is
  1376   1398   ** the actual number of bytes of randomness obtained.
  1377   1399   ** The xSleep() method causes the calling thread to sleep for at
  1378         -** least the number of microseconds given.  The xCurrentTime()
         1400  +** least the number of microseconds given.  ^The xCurrentTime()
  1379   1401   ** method returns a Julian Day Number for the current date and time as
  1380   1402   ** a floating point value.
  1381         -** The xCurrentTimeInt64() method returns, as an integer, the Julian
         1403  +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
  1382   1404   ** Day Number multipled by 86400000 (the number of milliseconds in 
  1383   1405   ** a 24-hour day).  
  1384   1406   ** ^SQLite will use the xCurrentTimeInt64() method to get the current
  1385   1407   ** date and time if that method is available (if iVersion is 2 or 
  1386   1408   ** greater and the function pointer is not NULL) and will fall back
  1387   1409   ** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
  1388   1410   */
................................................................................
  1771   1793   ** <dd> ^This option takes single argument of type int, interpreted as a 
  1772   1794   ** boolean, which enables or disables the collection of memory allocation 
  1773   1795   ** statistics. ^(When memory allocation statistics are disabled, the 
  1774   1796   ** following SQLite interfaces become non-operational:
  1775   1797   **   <ul>
  1776   1798   **   <li> [sqlite3_memory_used()]
  1777   1799   **   <li> [sqlite3_memory_highwater()]
  1778         -**   <li> [sqlite3_soft_heap_limit()]
         1800  +**   <li> [sqlite3_soft_heap_limit64()]
  1779   1801   **   <li> [sqlite3_status()]
  1780   1802   **   </ul>)^
  1781   1803   ** ^Memory allocation statistics are enabled by default unless SQLite is
  1782   1804   ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
  1783   1805   ** allocation statistics are disabled by default.
  1784   1806   ** </dd>
  1785   1807   **
  1786   1808   ** <dt>SQLITE_CONFIG_SCRATCH</dt>
  1787   1809   ** <dd> ^This option specifies a static memory buffer that SQLite can use for
  1788   1810   ** scratch memory.  There are three arguments:  A pointer an 8-byte
  1789   1811   ** aligned memory buffer from which the scrach allocations will be
  1790   1812   ** drawn, the size of each scratch allocation (sz),
  1791   1813   ** and the maximum number of scratch allocations (N).  The sz
  1792         -** argument must be a multiple of 16. The sz parameter should be a few bytes
  1793         -** larger than the actual scratch space required due to internal overhead.
         1814  +** argument must be a multiple of 16.
  1794   1815   ** The first argument must be a pointer to an 8-byte aligned buffer
  1795   1816   ** of at least sz*N bytes of memory.
  1796         -** ^SQLite will use no more than one scratch buffer per thread.  So
  1797         -** N should be set to the expected maximum number of threads.  ^SQLite will
  1798         -** never require a scratch buffer that is more than 6 times the database
  1799         -** page size. ^If SQLite needs needs additional scratch memory beyond 
  1800         -** what is provided by this configuration option, then 
         1817  +** ^SQLite will use no more than two scratch buffers per thread.  So
         1818  +** N should be set to twice the expected maximum number of threads.
         1819  +** ^SQLite will never require a scratch buffer that is more than 6
         1820  +** times the database page size. ^If SQLite needs needs additional
         1821  +** scratch memory beyond what is provided by this configuration option, then 
  1801   1822   ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
  1802   1823   **
  1803   1824   ** <dt>SQLITE_CONFIG_PAGECACHE</dt>
  1804   1825   ** <dd> ^This option specifies a static memory buffer that SQLite can use for
  1805   1826   ** the database page cache with the default page cache implemenation.  
  1806   1827   ** This configuration should not be used if an application-define page
  1807   1828   ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
................................................................................
  1813   1834   ** the host architecture.  ^It is harmless, apart from the wasted memory,
  1814   1835   ** to make sz a little too large.  The first
  1815   1836   ** argument should point to an allocation of at least sz*N bytes of memory.
  1816   1837   ** ^SQLite will use the memory provided by the first argument to satisfy its
  1817   1838   ** memory needs for the first N pages that it adds to cache.  ^If additional
  1818   1839   ** page cache memory is needed beyond what is provided by this option, then
  1819   1840   ** SQLite goes to [sqlite3_malloc()] for the additional storage space.
  1820         -** ^The implementation might use one or more of the N buffers to hold 
  1821         -** memory accounting information. The pointer in the first argument must
         1841  +** The pointer in the first argument must
  1822   1842   ** be aligned to an 8-byte boundary or subsequent behavior of SQLite
  1823   1843   ** will be undefined.</dd>
  1824   1844   **
  1825   1845   ** <dt>SQLITE_CONFIG_HEAP</dt>
  1826   1846   ** <dd> ^This option specifies a static memory buffer that SQLite will use
  1827   1847   ** for all of its dynamic memory allocation needs beyond those provided
  1828   1848   ** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
................................................................................
  1943   1963   ** may be NULL in which case SQLite will allocate the
  1944   1964   ** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
  1945   1965   ** size of each lookaside buffer slot.  ^The third argument is the number of
  1946   1966   ** slots.  The size of the buffer in the first argument must be greater than
  1947   1967   ** or equal to the product of the second and third arguments.  The buffer
  1948   1968   ** must be aligned to an 8-byte boundary.  ^If the second argument to
  1949   1969   ** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
  1950         -** rounded down to the next smaller
  1951         -** multiple of 8.  See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
         1970  +** rounded down to the next smaller multiple of 8.  ^(The lookaside memory
         1971  +** configuration for a database connection can only be changed when that
         1972  +** connection is not currently using lookaside memory, or in other words
         1973  +** when the "current value" returned by
         1974  +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
         1975  +** Any attempt to change the lookaside memory configuration when lookaside
         1976  +** memory is in use leaves the configuration unchanged and returns 
         1977  +** [SQLITE_BUSY].)^</dd>
  1952   1978   **
  1953   1979   ** </dl>
  1954   1980   */
  1955   1981   #define SQLITE_DBCONFIG_LOOKASIDE    1001  /* void* int int */
  1956   1982   
  1957   1983   
  1958   1984   /*
................................................................................
  2248   2274   ** was defined  (using [sqlite3_busy_handler()]) prior to calling
  2249   2275   ** this routine, that other busy handler is cleared.)^
  2250   2276   */
  2251   2277   SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
  2252   2278   
  2253   2279   /*
  2254   2280   ** CAPI3REF: Convenience Routines For Running Queries
         2281  +**
         2282  +** This is a legacy interface that is preserved for backwards compatibility.
         2283  +** Use of this interface is not recommended.
  2255   2284   **
  2256   2285   ** Definition: A <b>result table</b> is memory data structure created by the
  2257   2286   ** [sqlite3_get_table()] interface.  A result table records the
  2258   2287   ** complete query results from one or more queries.
  2259   2288   **
  2260   2289   ** The table conceptually has a number of rows and columns.  But
  2261   2290   ** these numbers are not part of the result table itself.  These
................................................................................
  2269   2298   ** in NULL pointers.  All other values are in their UTF-8 zero-terminated
  2270   2299   ** string representation as returned by [sqlite3_column_text()].
  2271   2300   **
  2272   2301   ** A result table might consist of one or more memory allocations.
  2273   2302   ** It is not safe to pass a result table directly to [sqlite3_free()].
  2274   2303   ** A result table should be deallocated using [sqlite3_free_table()].
  2275   2304   **
  2276         -** As an example of the result table format, suppose a query result
         2305  +** ^(As an example of the result table format, suppose a query result
  2277   2306   ** is as follows:
  2278   2307   **
  2279   2308   ** <blockquote><pre>
  2280   2309   **        Name        | Age
  2281   2310   **        -----------------------
  2282   2311   **        Alice       | 43
  2283   2312   **        Bob         | 28
................................................................................
  2293   2322   **        azResult&#91;1] = "Age";
  2294   2323   **        azResult&#91;2] = "Alice";
  2295   2324   **        azResult&#91;3] = "43";
  2296   2325   **        azResult&#91;4] = "Bob";
  2297   2326   **        azResult&#91;5] = "28";
  2298   2327   **        azResult&#91;6] = "Cindy";
  2299   2328   **        azResult&#91;7] = "21";
  2300         -** </pre></blockquote>
         2329  +** </pre></blockquote>)^
  2301   2330   **
  2302   2331   ** ^The sqlite3_get_table() function evaluates one or more
  2303   2332   ** semicolon-separated SQL statements in the zero-terminated UTF-8
  2304   2333   ** string of its 2nd parameter and returns a result table to the
  2305   2334   ** pointer given in its 3rd parameter.
  2306   2335   **
  2307   2336   ** After the application has finished with the result from sqlite3_get_table(),
  2308         -** it should pass the result table pointer to sqlite3_free_table() in order to
         2337  +** it must pass the result table pointer to sqlite3_free_table() in order to
  2309   2338   ** release the memory that was malloced.  Because of the way the
  2310   2339   ** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
  2311   2340   ** function must not try to call [sqlite3_free()] directly.  Only
  2312   2341   ** [sqlite3_free_table()] is able to release the memory properly and safely.
  2313   2342   **
  2314         -** ^(The sqlite3_get_table() interface is implemented as a wrapper around
         2343  +** The sqlite3_get_table() interface is implemented as a wrapper around
  2315   2344   ** [sqlite3_exec()].  The sqlite3_get_table() routine does not have access
  2316   2345   ** to any internal data structures of SQLite.  It uses only the public
  2317   2346   ** interface defined here.  As a consequence, errors that occur in the
  2318   2347   ** wrapper layer outside of the internal [sqlite3_exec()] call are not
  2319   2348   ** reflected in subsequent calls to [sqlite3_errcode()] or
  2320         -** [sqlite3_errmsg()].)^
         2349  +** [sqlite3_errmsg()].
  2321   2350   */
  2322   2351   SQLITE_API int sqlite3_get_table(
  2323   2352     sqlite3 *db,          /* An open database */
  2324   2353     const char *zSql,     /* SQL to be evaluated */
  2325   2354     char ***pazResult,    /* Results of the query */
  2326   2355     int *pnRow,           /* Number of result rows written here */
  2327   2356     int *pnColumn,        /* Number of result columns written here */
................................................................................
  2465   2494   ** ^If M is the size of the prior allocation, then min(N,M) bytes
  2466   2495   ** of the prior allocation are copied into the beginning of buffer returned
  2467   2496   ** by sqlite3_realloc() and the prior allocation is freed.
  2468   2497   ** ^If sqlite3_realloc() returns NULL, then the prior allocation
  2469   2498   ** is not freed.
  2470   2499   **
  2471   2500   ** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
  2472         -** is always aligned to at least an 8 byte boundary.
         2501  +** is always aligned to at least an 8 byte boundary, or to a
         2502  +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
         2503  +** option is used.
  2473   2504   **
  2474   2505   ** In SQLite version 3.5.0 and 3.5.1, it was possible to define
  2475   2506   ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
  2476   2507   ** implementation of these routines to be omitted.  That capability
  2477   2508   ** is no longer provided.  Only built-in memory allocators can be used.
  2478   2509   **
  2479   2510   ** The Windows OS interface layer calls
................................................................................
  2723   2754   SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
  2724   2755   SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
  2725   2756      void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
  2726   2757   
  2727   2758   /*
  2728   2759   ** CAPI3REF: Query Progress Callbacks
  2729   2760   **
  2730         -** ^This routine configures a callback function - the
  2731         -** progress callback - that is invoked periodically during long
  2732         -** running calls to [sqlite3_exec()], [sqlite3_step()] and
  2733         -** [sqlite3_get_table()].  An example use for this
         2761  +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
         2762  +** function X to be invoked periodically during long running calls to
         2763  +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
         2764  +** database connection D.  An example use for this
  2734   2765   ** interface is to keep a GUI updated during a large query.
         2766  +**
         2767  +** ^The parameter P is passed through as the only parameter to the 
         2768  +** callback function X.  ^The parameter N is the number of 
         2769  +** [virtual machine instructions] that are evaluated between successive
         2770  +** invocations of the callback X.
         2771  +**
         2772  +** ^Only a single progress handler may be defined at one time per
         2773  +** [database connection]; setting a new progress handler cancels the
         2774  +** old one.  ^Setting parameter X to NULL disables the progress handler.
         2775  +** ^The progress handler is also disabled by setting N to a value less
         2776  +** than 1.
  2735   2777   **
  2736   2778   ** ^If the progress callback returns non-zero, the operation is
  2737   2779   ** interrupted.  This feature can be used to implement a
  2738   2780   ** "Cancel" button on a GUI progress dialog box.
  2739   2781   **
  2740         -** The progress handler must not do anything that will modify
         2782  +** The progress handler callback must not do anything that will modify
  2741   2783   ** the database connection that invoked the progress handler.
  2742   2784   ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
  2743   2785   ** database connections for the meaning of "modify" in this paragraph.
  2744   2786   **
  2745   2787   */
  2746   2788   SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
  2747   2789   
................................................................................
  2792   2834   ** it does not already exist. This is the behavior that is always used for
  2793   2835   ** sqlite3_open() and sqlite3_open16().</dd>)^
  2794   2836   ** </dl>
  2795   2837   **
  2796   2838   ** If the 3rd parameter to sqlite3_open_v2() is not one of the
  2797   2839   ** combinations shown above or one of the combinations shown above combined
  2798   2840   ** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
  2799         -** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
         2841  +** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_PRIVATECACHE] flags,
  2800   2842   ** then the behavior is undefined.
  2801   2843   **
  2802   2844   ** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
  2803   2845   ** opens in the multi-thread [threading mode] as long as the single-thread
  2804   2846   ** mode has not been set at compile-time or start-time.  ^If the
  2805   2847   ** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
  2806   2848   ** in the serialized [threading mode] unless single-thread was
................................................................................
  2917   2959   ** CAPI3REF: Run-time Limits
  2918   2960   **
  2919   2961   ** ^(This interface allows the size of various constructs to be limited
  2920   2962   ** on a connection by connection basis.  The first parameter is the
  2921   2963   ** [database connection] whose limit is to be set or queried.  The
  2922   2964   ** second parameter is one of the [limit categories] that define a
  2923   2965   ** class of constructs to be size limited.  The third parameter is the
  2924         -** new limit for that construct.  The function returns the old limit.)^
         2966  +** new limit for that construct.)^
  2925   2967   **
  2926   2968   ** ^If the new limit is a negative number, the limit is unchanged.
  2927         -** ^(For the limit category of SQLITE_LIMIT_XYZ there is a 
         2969  +** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a 
  2928   2970   ** [limits | hard upper bound]
  2929         -** set by a compile-time C preprocessor macro named 
  2930         -** [limits | SQLITE_MAX_XYZ].
         2971  +** set at compile-time by a C preprocessor macro called
         2972  +** [limits | SQLITE_MAX_<i>NAME</i>].
  2931   2973   ** (The "_LIMIT_" in the name is changed to "_MAX_".))^
  2932   2974   ** ^Attempts to increase a limit above its hard upper bound are
  2933   2975   ** silently truncated to the hard upper bound.
  2934   2976   **
         2977  +** ^Regardless of whether or not the limit was changed, the 
         2978  +** [sqlite3_limit()] interface returns the prior value of the limit.
         2979  +** ^Hence, to find the current value of a limit without changing it,
         2980  +** simply invoke this interface with the third parameter set to -1.
         2981  +**
  2935   2982   ** Run-time limits are intended for use in applications that manage
  2936   2983   ** both their own internal database and also databases that are controlled
  2937   2984   ** by untrusted external sources.  An example application might be a
  2938   2985   ** web browser that has its own databases for storing history and
  2939   2986   ** separate databases controlled by JavaScript applications downloaded
  2940   2987   ** off the Internet.  The internal databases can be given the
  2941   2988   ** large, default limits.  Databases managed by external sources can
................................................................................
  2956   3003   ** These constants define various performance limits
  2957   3004   ** that can be lowered at run-time using [sqlite3_limit()].
  2958   3005   ** The synopsis of the meanings of the various limits is shown below.
  2959   3006   ** Additional information is available at [limits | Limits in SQLite].
  2960   3007   **
  2961   3008   ** <dl>
  2962   3009   ** ^(<dt>SQLITE_LIMIT_LENGTH</dt>
  2963         -** <dd>The maximum size of any string or BLOB or table row.<dd>)^
         3010  +** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
  2964   3011   **
  2965   3012   ** ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
  2966   3013   ** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
  2967   3014   **
  2968   3015   ** ^(<dt>SQLITE_LIMIT_COLUMN</dt>
  2969   3016   ** <dd>The maximum number of columns in a table definition or in the
  2970   3017   ** result set of a [SELECT] or the maximum number of columns in an index
................................................................................
  2974   3021   ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
  2975   3022   **
  2976   3023   ** ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
  2977   3024   ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
  2978   3025   **
  2979   3026   ** ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
  2980   3027   ** <dd>The maximum number of instructions in a virtual machine program
  2981         -** used to implement an SQL statement.</dd>)^
         3028  +** used to implement an SQL statement.  This limit is not currently
         3029  +** enforced, though that might be added in some future release of
         3030  +** SQLite.</dd>)^
  2982   3031   **
  2983   3032   ** ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
  2984   3033   ** <dd>The maximum number of arguments on a function.</dd>)^
  2985   3034   **
  2986   3035   ** ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
  2987   3036   ** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
  2988   3037   **
  2989   3038   ** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
  2990   3039   ** <dd>The maximum length of the pattern argument to the [LIKE] or
  2991   3040   ** [GLOB] operators.</dd>)^
  2992   3041   **
  2993   3042   ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
  2994         -** <dd>The maximum number of variables in an SQL statement that can
  2995         -** be bound.</dd>)^
         3043  +** <dd>The maximum index number of any [parameter] in an SQL statement.)^
  2996   3044   **
  2997   3045   ** ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
  2998   3046   ** <dd>The maximum depth of recursion for triggers.</dd>)^
  2999   3047   ** </dl>
  3000   3048   */
  3001   3049   #define SQLITE_LIMIT_LENGTH                    0
  3002   3050   #define SQLITE_LIMIT_SQL_LENGTH                1
................................................................................
  3060   3108   ** original SQL text. This causes the [sqlite3_step()] interface to
  3061   3109   ** behave differently in three ways:
  3062   3110   **
  3063   3111   ** <ol>
  3064   3112   ** <li>
  3065   3113   ** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
  3066   3114   ** always used to do, [sqlite3_step()] will automatically recompile the SQL
  3067         -** statement and try to run it again.  ^If the schema has changed in
  3068         -** a way that makes the statement no longer valid, [sqlite3_step()] will still
  3069         -** return [SQLITE_SCHEMA].  But unlike the legacy behavior, [SQLITE_SCHEMA] is
  3070         -** now a fatal error.  Calling [sqlite3_prepare_v2()] again will not make the
  3071         -** error go away.  Note: use [sqlite3_errmsg()] to find the text
  3072         -** of the parsing error that results in an [SQLITE_SCHEMA] return.
         3115  +** statement and try to run it again.
  3073   3116   ** </li>
  3074   3117   **
  3075   3118   ** <li>
  3076   3119   ** ^When an error occurs, [sqlite3_step()] will return one of the detailed
  3077   3120   ** [error codes] or [extended error codes].  ^The legacy behavior was that
  3078   3121   ** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
  3079   3122   ** and the application would have to make a second call to [sqlite3_reset()]
  3080   3123   ** in order to find the underlying cause of the problem. With the "v2" prepare
  3081   3124   ** interfaces, the underlying reason for the error is returned immediately.
  3082   3125   ** </li>
  3083   3126   **
  3084   3127   ** <li>
  3085         -** ^If the value of a [parameter | host parameter] in the WHERE clause might
  3086         -** change the query plan for a statement, then the statement may be
  3087         -** automatically recompiled (as if there had been a schema change) on the first 
  3088         -** [sqlite3_step()] call following any change to the 
  3089         -** [sqlite3_bind_text | bindings] of the [parameter]. 
         3128  +** ^If the specific value bound to [parameter | host parameter] in the 
         3129  +** WHERE clause might influence the choice of query plan for a statement,
         3130  +** then the statement will be automatically recompiled, as if there had been 
         3131  +** a schema change, on the first  [sqlite3_step()] call following any change
         3132  +** to the [sqlite3_bind_text | bindings] of that [parameter]. 
         3133  +** ^The specific value of WHERE-clause [parameter] might influence the 
         3134  +** choice of query plan if the parameter is the left-hand side of a [LIKE]
         3135  +** or [GLOB] operator or if the parameter is compared to an indexed column
         3136  +** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
         3137  +** the 
  3090   3138   ** </li>
  3091   3139   ** </ol>
  3092   3140   */
  3093   3141   SQLITE_API int sqlite3_prepare(
  3094   3142     sqlite3 *db,            /* Database handle */
  3095   3143     const char *zSql,       /* SQL statement, UTF-8 encoded */
  3096   3144     int nByte,              /* Maximum length of zSql in bytes. */
................................................................................
  3149   3197   ** sqlite3_value object.  If SQLite is compiled to be single-threaded
  3150   3198   ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
  3151   3199   ** or if SQLite is run in one of reduced mutex modes 
  3152   3200   ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
  3153   3201   ** then there is no distinction between protected and unprotected
  3154   3202   ** sqlite3_value objects and they can be used interchangeably.  However,
  3155   3203   ** for maximum code portability it is recommended that applications
  3156         -** still make the distinction between between protected and unprotected
         3204  +** still make the distinction between protected and unprotected
  3157   3205   ** sqlite3_value objects even when not strictly required.
  3158   3206   **
  3159   3207   ** ^The sqlite3_value objects that are passed as parameters into the
  3160   3208   ** implementation of [application-defined SQL functions] are protected.
  3161   3209   ** ^The sqlite3_value object returned by
  3162   3210   ** [sqlite3_column_value()] is unprotected.
  3163   3211   ** Unprotected sqlite3_value objects may only be used with
................................................................................
  3195   3243   ** <li>  ?NNN
  3196   3244   ** <li>  :VVV
  3197   3245   ** <li>  @VVV
  3198   3246   ** <li>  $VVV
  3199   3247   ** </ul>
  3200   3248   **
  3201   3249   ** In the templates above, NNN represents an integer literal,
  3202         -** and VVV represents an alphanumeric identifer.)^  ^The values of these
         3250  +** and VVV represents an alphanumeric identifier.)^  ^The values of these
  3203   3251   ** parameters (also called "host parameter names" or "SQL parameters")
  3204   3252   ** can be set using the sqlite3_bind_*() routines defined here.
  3205   3253   **
  3206   3254   ** ^The first argument to the sqlite3_bind_*() routines is always
  3207   3255   ** a pointer to the [sqlite3_stmt] object returned from
  3208   3256   ** [sqlite3_prepare_v2()] or its variants.
  3209   3257   **
................................................................................
  3344   3392   
  3345   3393   /*
  3346   3394   ** CAPI3REF: Number Of Columns In A Result Set
  3347   3395   **
  3348   3396   ** ^Return the number of columns in the result set returned by the
  3349   3397   ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
  3350   3398   ** statement that does not return data (for example an [UPDATE]).
         3399  +**
         3400  +** See also: [sqlite3_data_count()]
  3351   3401   */
  3352   3402   SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
  3353   3403   
  3354   3404   /*
  3355   3405   ** CAPI3REF: Column Names In A Result Set
  3356   3406   **
  3357   3407   ** ^These routines return the name assigned to a particular column
................................................................................
  3534   3584   ** by sqlite3_step().  The use of the "v2" interface is recommended.
  3535   3585   */
  3536   3586   SQLITE_API int sqlite3_step(sqlite3_stmt*);
  3537   3587   
  3538   3588   /*
  3539   3589   ** CAPI3REF: Number of columns in a result set
  3540   3590   **
  3541         -** ^The sqlite3_data_count(P) the number of columns in the
  3542         -** of the result set of [prepared statement] P.
         3591  +** ^The sqlite3_data_count(P) interface returns the number of columns in the
         3592  +** current row of the result set of [prepared statement] P.
         3593  +** ^If prepared statement P does not have results ready to return
         3594  +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
         3595  +** interfaces) then sqlite3_data_count(P) returns 0.
         3596  +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
         3597  +**
         3598  +** See also: [sqlite3_column_count()]
  3543   3599   */
  3544   3600   SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
  3545   3601   
  3546   3602   /*
  3547   3603   ** CAPI3REF: Fundamental Datatypes
  3548   3604   ** KEYWORDS: SQLITE_TEXT
  3549   3605   **
................................................................................
  3615   3671   ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
  3616   3672   ** routine returns the number of bytes in that BLOB or string.
  3617   3673   ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
  3618   3674   ** the string to UTF-8 and then returns the number of bytes.
  3619   3675   ** ^If the result is a numeric value then sqlite3_column_bytes() uses
  3620   3676   ** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
  3621   3677   ** the number of bytes in that string.
  3622         -** ^The value returned does not include the zero terminator at the end
  3623         -** of the string.  ^For clarity: the value returned is the number of
         3678  +** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
         3679  +**
         3680  +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
         3681  +** routine returns the number of bytes in that BLOB or string.
         3682  +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
         3683  +** the string to UTF-16 and then returns the number of bytes.
         3684  +** ^If the result is a numeric value then sqlite3_column_bytes16() uses
         3685  +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
         3686  +** the number of bytes in that string.
         3687  +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
         3688  +**
         3689  +** ^The values returned by [sqlite3_column_bytes()] and 
         3690  +** [sqlite3_column_bytes16()] do not include the zero terminators at the end
         3691  +** of the string.  ^For clarity: the values returned by
         3692  +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
  3624   3693   ** bytes in the string, not the number of characters.
  3625   3694   **
  3626   3695   ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
  3627   3696   ** even empty strings, are always zero terminated.  ^The return
  3628         -** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
  3629         -** pointer, possibly even a NULL pointer.
  3630         -**
  3631         -** ^The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
  3632         -** but leaves the result in UTF-16 in native byte order instead of UTF-8.
  3633         -** ^The zero terminator is not included in this count.
         3697  +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
  3634   3698   **
  3635   3699   ** ^The object returned by [sqlite3_column_value()] is an
  3636   3700   ** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
  3637   3701   ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
  3638   3702   ** If the [unprotected sqlite3_value] object returned by
  3639   3703   ** [sqlite3_column_value()] is used in any other way, including calls
  3640   3704   ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
................................................................................
  3671   3735   **
  3672   3736   ** The table above makes reference to standard C library functions atoi()
  3673   3737   ** and atof().  SQLite does not really use these functions.  It has its
  3674   3738   ** own equivalent internal routines.  The atoi() and atof() names are
  3675   3739   ** used in the table for brevity and because they are familiar to most
  3676   3740   ** C programmers.
  3677   3741   **
  3678         -** ^Note that when type conversions occur, pointers returned by prior
         3742  +** Note that when type conversions occur, pointers returned by prior
  3679   3743   ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
  3680   3744   ** sqlite3_column_text16() may be invalidated.
  3681         -** ^(Type conversions and pointer invalidations might occur
         3745  +** Type conversions and pointer invalidations might occur
  3682   3746   ** in the following cases:
  3683   3747   **
  3684   3748   ** <ul>
  3685   3749   ** <li> The initial content is a BLOB and sqlite3_column_text() or
  3686   3750   **      sqlite3_column_text16() is called.  A zero-terminator might
  3687   3751   **      need to be added to the string.</li>
  3688   3752   ** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
  3689   3753   **      sqlite3_column_text16() is called.  The content must be converted
  3690   3754   **      to UTF-16.</li>
  3691   3755   ** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
  3692   3756   **      sqlite3_column_text() is called.  The content must be converted
  3693   3757   **      to UTF-8.</li>
  3694         -** </ul>)^
         3758  +** </ul>
  3695   3759   **
  3696   3760   ** ^Conversions between UTF-16be and UTF-16le are always done in place and do
  3697   3761   ** not invalidate a prior pointer, though of course the content of the buffer
  3698         -** that the prior pointer points to will have been modified.  Other kinds
         3762  +** that the prior pointer references will have been modified.  Other kinds
  3699   3763   ** of conversion are done in place when it is possible, but sometimes they
  3700   3764   ** are not possible and in those cases prior pointers are invalidated.
  3701   3765   **
  3702         -** ^(The safest and easiest to remember policy is to invoke these routines
         3766  +** The safest and easiest to remember policy is to invoke these routines
  3703   3767   ** in one of the following ways:
  3704   3768   **
  3705   3769   ** <ul>
  3706   3770   **  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
  3707   3771   **  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
  3708   3772   **  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
  3709         -** </ul>)^
         3773  +** </ul>
  3710   3774   **
  3711   3775   ** In other words, you should call sqlite3_column_text(),
  3712   3776   ** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
  3713   3777   ** into the desired format, then invoke sqlite3_column_bytes() or
  3714   3778   ** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
  3715   3779   ** to sqlite3_column_text() or sqlite3_column_blob() with calls to
  3716   3780   ** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
................................................................................
  3740   3804   SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
  3741   3805   SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
  3742   3806   
  3743   3807   /*
  3744   3808   ** CAPI3REF: Destroy A Prepared Statement Object
  3745   3809   **
  3746   3810   ** ^The sqlite3_finalize() function is called to delete a [prepared statement].
  3747         -** ^If the statement was executed successfully or not executed at all, then
  3748         -** SQLITE_OK is returned. ^If execution of the statement failed then an
  3749         -** [error code] or [extended error code] is returned.
         3811  +** ^If the most recent evaluation of the statement encountered no errors or
         3812  +** or if the statement is never been evaluated, then sqlite3_finalize() returns
         3813  +** SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
         3814  +** sqlite3_finalize(S) returns the appropriate [error code] or
         3815  +** [extended error code].
  3750   3816   **
  3751         -** ^This routine can be called at any point during the execution of the
  3752         -** [prepared statement].  ^If the virtual machine has not
  3753         -** completed execution when this routine is called, that is like
  3754         -** encountering an error or an [sqlite3_interrupt | interrupt].
  3755         -** ^Incomplete updates may be rolled back and transactions canceled,
  3756         -** depending on the circumstances, and the
  3757         -** [error code] returned will be [SQLITE_ABORT].
         3817  +** ^The sqlite3_finalize(S) routine can be called at any point during
         3818  +** the life cycle of [prepared statement] S:
         3819  +** before statement S is ever evaluated, after
         3820  +** one or more calls to [sqlite3_reset()], or after any call
         3821  +** to [sqlite3_step()] regardless of whether or not the statement has
         3822  +** completed execution.
         3823  +**
         3824  +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
         3825  +**
         3826  +** The application must finalize every [prepared statement] in order to avoid
         3827  +** resource leaks.  It is a grievous error for the application to try to use
         3828  +** a prepared statement after it has been finalized.  Any use of a prepared
         3829  +** statement after it has been finalized can result in undefined and
         3830  +** undesirable behavior such as segfaults and heap corruption.
  3758   3831   */
  3759   3832   SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
  3760   3833   
  3761   3834   /*
  3762   3835   ** CAPI3REF: Reset A Prepared Statement Object
  3763   3836   **
  3764   3837   ** The sqlite3_reset() function is called to reset a [prepared statement]
................................................................................
  3786   3859   
  3787   3860   /*
  3788   3861   ** CAPI3REF: Create Or Redefine SQL Functions
  3789   3862   ** KEYWORDS: {function creation routines}
  3790   3863   ** KEYWORDS: {application-defined SQL function}
  3791   3864   ** KEYWORDS: {application-defined SQL functions}
  3792   3865   **
  3793         -** ^These two functions (collectively known as "function creation routines")
         3866  +** ^These functions (collectively known as "function creation routines")
  3794   3867   ** are used to add SQL functions or aggregates or to redefine the behavior
  3795         -** of existing SQL functions or aggregates.  The only difference between the
  3796         -** two is that the second parameter, the name of the (scalar) function or
  3797         -** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
  3798         -** for sqlite3_create_function16().
         3868  +** of existing SQL functions or aggregates.  The only differences between
         3869  +** these routines are the text encoding expected for
         3870  +** the the second parameter (the name of the function being created)
         3871  +** and the presence or absence of a destructor callback for
         3872  +** the application data pointer.
  3799   3873   **
  3800   3874   ** ^The first parameter is the [database connection] to which the SQL
  3801   3875   ** function is to be added.  ^If an application uses more than one database
  3802   3876   ** connection then application-defined SQL functions must be added
  3803   3877   ** to each database connection separately.
  3804   3878   **
  3805         -** The second parameter is the name of the SQL function to be created or
  3806         -** redefined.  ^The length of the name is limited to 255 bytes, exclusive of
  3807         -** the zero-terminator.  Note that the name length limit is in bytes, not
  3808         -** characters.  ^Any attempt to create a function with a longer name
  3809         -** will result in [SQLITE_ERROR] being returned.
         3879  +** ^The second parameter is the name of the SQL function to be created or
         3880  +** redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
         3881  +** representation, exclusive of the zero-terminator.  ^Note that the name
         3882  +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.  
         3883  +** ^Any attempt to create a function with a longer name
         3884  +** will result in [SQLITE_MISUSE] being returned.
  3810   3885   **
  3811   3886   ** ^The third parameter (nArg)
  3812   3887   ** is the number of arguments that the SQL function or
  3813   3888   ** aggregate takes. ^If this parameter is -1, then the SQL function or
  3814   3889   ** aggregate may take any number of arguments between 0 and the limit
  3815   3890   ** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
  3816   3891   ** parameter is less than -1 or greater than 127 then the behavior is
  3817   3892   ** undefined.
  3818   3893   **
  3819         -** The fourth parameter, eTextRep, specifies what
         3894  +** ^The fourth parameter, eTextRep, specifies what
  3820   3895   ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
  3821         -** its parameters.  Any SQL function implementation should be able to work
  3822         -** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
         3896  +** its parameters.  Every SQL function implementation must be able to work
         3897  +** with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
  3823   3898   ** more efficient with one encoding than another.  ^An application may
  3824   3899   ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
  3825   3900   ** times with the same function but with different values of eTextRep.
  3826   3901   ** ^When multiple implementations of the same function are available, SQLite
  3827   3902   ** will pick the one that involves the least amount of data conversion.
  3828   3903   ** If there is only a single implementation which does not care what text
  3829   3904   ** encoding is used, then the fourth argument should be [SQLITE_ANY].
  3830   3905   **
  3831   3906   ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
  3832   3907   ** function can gain access to this pointer using [sqlite3_user_data()].)^
  3833   3908   **
  3834         -** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
         3909  +** ^The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
  3835   3910   ** pointers to C-language functions that implement the SQL function or
  3836   3911   ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
  3837         -** callback only; NULL pointers should be passed as the xStep and xFinal
         3912  +** callback only; NULL pointers must be passed as the xStep and xFinal
  3838   3913   ** parameters. ^An aggregate SQL function requires an implementation of xStep
  3839         -** and xFinal and NULL should be passed for xFunc. ^To delete an existing
  3840         -** SQL function or aggregate, pass NULL for all three function callbacks.
         3914  +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
         3915  +** SQL function or aggregate, pass NULL poiners for all three function
         3916  +** callbacks.
         3917  +**
         3918  +** ^If the tenth parameter to sqlite3_create_function_v2() is not NULL,
         3919  +** then it is invoked when the function is deleted, either by being
         3920  +** overloaded or when the database connection closes.
         3921  +** ^When the destructure callback of the tenth parameter is invoked, it
         3922  +** is passed a single argument which is a copy of the pointer which was
         3923  +** the fifth parameter to sqlite3_create_function_v2().
  3841   3924   **
  3842   3925   ** ^It is permitted to register multiple implementations of the same
  3843   3926   ** functions with the same name but with either differing numbers of
  3844   3927   ** arguments or differing preferred text encodings.  ^SQLite will use
  3845   3928   ** the implementation that most closely matches the way in which the
  3846   3929   ** SQL function is used.  ^A function implementation with a non-negative
  3847   3930   ** nArg parameter is a better match than a function implementation with
................................................................................
  3849   3932   ** matches the database encoding is a better
  3850   3933   ** match than a function where the encoding is different.  
  3851   3934   ** ^A function where the encoding difference is between UTF16le and UTF16be
  3852   3935   ** is a closer match than a function where the encoding difference is
  3853   3936   ** between UTF8 and UTF16.
  3854   3937   **
  3855   3938   ** ^Built-in functions may be overloaded by new application-defined functions.
  3856         -** ^The first application-defined function with a given name overrides all
  3857         -** built-in functions in the same [database connection] with the same name.
  3858         -** ^Subsequent application-defined functions of the same name only override 
  3859         -** prior application-defined functions that are an exact match for the
  3860         -** number of parameters and preferred encoding.
  3861   3939   **
  3862   3940   ** ^An application-defined function is permitted to call other
  3863   3941   ** SQLite interfaces.  However, such calls must not
  3864   3942   ** close the database connection nor finalize or reset the prepared
  3865   3943   ** statement in which the function is running.
  3866   3944   */
  3867   3945   SQLITE_API int sqlite3_create_function(
................................................................................
  3879   3957     const void *zFunctionName,
  3880   3958     int nArg,
  3881   3959     int eTextRep,
  3882   3960     void *pApp,
  3883   3961     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  3884   3962     void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  3885   3963     void (*xFinal)(sqlite3_context*)
         3964  +);
         3965  +SQLITE_API int sqlite3_create_function_v2(
         3966  +  sqlite3 *db,
         3967  +  const char *zFunctionName,
         3968  +  int nArg,
         3969  +  int eTextRep,
         3970  +  void *pApp,
         3971  +  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
         3972  +  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
         3973  +  void (*xFinal)(sqlite3_context*),
         3974  +  void(*xDestroy)(void*)
  3886   3975   );
  3887   3976   
  3888   3977   /*
  3889   3978   ** CAPI3REF: Text Encodings
  3890   3979   **
  3891   3980   ** These constant define integer codes that represent the various
  3892   3981   ** text encodings supported by SQLite.
................................................................................
  3974   4063   SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
  3975   4064   SQLITE_API int sqlite3_value_type(sqlite3_value*);
  3976   4065   SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
  3977   4066   
  3978   4067   /*
  3979   4068   ** CAPI3REF: Obtain Aggregate Function Context
  3980   4069   **
  3981         -** Implementions of aggregate SQL functions use this
         4070  +** Implementations of aggregate SQL functions use this
  3982   4071   ** routine to allocate memory for storing their state.
  3983   4072   **
  3984   4073   ** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
  3985   4074   ** for a particular aggregate function, SQLite
  3986   4075   ** allocates N of memory, zeroes out that memory, and returns a pointer
  3987   4076   ** to the new memory. ^On second and subsequent calls to
  3988   4077   ** sqlite3_aggregate_context() for the same aggregate function instance,
................................................................................
  4226   4315   SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
  4227   4316   SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
  4228   4317   SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
  4229   4318   
  4230   4319   /*
  4231   4320   ** CAPI3REF: Define New Collating Sequences
  4232   4321   **
  4233         -** These functions are used to add new collation sequences to the
  4234         -** [database connection] specified as the first argument.
         4322  +** ^These functions add, remove, or modify a [collation] associated
         4323  +** with the [database connection] specified as the first argument.
  4235   4324   **
  4236         -** ^The name of the new collation sequence is specified as a UTF-8 string
         4325  +** ^The name of the collation is a UTF-8 string
  4237   4326   ** for sqlite3_create_collation() and sqlite3_create_collation_v2()
  4238         -** and a UTF-16 string for sqlite3_create_collation16(). ^In all cases
  4239         -** the name is passed as the second function argument.
  4240         -**
  4241         -** ^The third argument may be one of the constants [SQLITE_UTF8],
  4242         -** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied
  4243         -** routine expects to be passed pointers to strings encoded using UTF-8,
  4244         -** UTF-16 little-endian, or UTF-16 big-endian, respectively. ^The
  4245         -** third argument might also be [SQLITE_UTF16] to indicate that the routine
  4246         -** expects pointers to be UTF-16 strings in the native byte order, or the
  4247         -** argument can be [SQLITE_UTF16_ALIGNED] if the
  4248         -** the routine expects pointers to 16-bit word aligned strings
  4249         -** of UTF-16 in the native byte order.
  4250         -**
  4251         -** A pointer to the user supplied routine must be passed as the fifth
  4252         -** argument.  ^If it is NULL, this is the same as deleting the collation
  4253         -** sequence (so that SQLite cannot call it anymore).
  4254         -** ^Each time the application supplied function is invoked, it is passed
  4255         -** as its first parameter a copy of the void* passed as the fourth argument
  4256         -** to sqlite3_create_collation() or sqlite3_create_collation16().
  4257         -**
  4258         -** ^The remaining arguments to the application-supplied routine are two strings,
  4259         -** each represented by a (length, data) pair and encoded in the encoding
  4260         -** that was passed as the third argument when the collation sequence was
  4261         -** registered.  The application defined collation routine should
  4262         -** return negative, zero or positive if the first string is less than,
  4263         -** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
         4327  +** and a UTF-16 string in native byte order for sqlite3_create_collation16().
         4328  +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
         4329  +** considered to be the same name.
         4330  +**
         4331  +** ^(The third argument (eTextRep) must be one of the constants:
         4332  +** <ul>
         4333  +** <li> [SQLITE_UTF8],
         4334  +** <li> [SQLITE_UTF16LE],
         4335  +** <li> [SQLITE_UTF16BE],
         4336  +** <li> [SQLITE_UTF16], or
         4337  +** <li> [SQLITE_UTF16_ALIGNED].
         4338  +** </ul>)^
         4339  +** ^The eTextRep argument determines the encoding of strings passed
         4340  +** to the collating function callback, xCallback.
         4341  +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
         4342  +** force strings to be UTF16 with native byte order.
         4343  +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
         4344  +** on an even byte address.
         4345  +**
         4346  +** ^The fourth argument, pArg, is a application data pointer that is passed
         4347  +** through as the first argument to the collating function callback.
         4348  +**
         4349  +** ^The fifth argument, xCallback, is a pointer to the collating function.
         4350  +** ^Multiple collating functions can be registered using the same name but
         4351  +** with different eTextRep parameters and SQLite will use whichever
         4352  +** function requires the least amount of data transformation.
         4353  +** ^If the xCallback argument is NULL then the collating function is
         4354  +** deleted.  ^When all collating functions having the same name are deleted,
         4355  +** that collation is no longer usable.
         4356  +**
         4357  +** ^The collating function callback is invoked with a copy of the pArg 
         4358  +** application data pointer and with two strings in the encoding specified
         4359  +** by the eTextRep argument.  The collating function must return an
         4360  +** integer that is negative, zero, or positive
         4361  +** if the first string is less than, equal to, or greater than the second,
         4362  +** respectively.  A collating function must alway return the same answer
         4363  +** given the same inputs.  If two or more collating functions are registered
         4364  +** to the same collation name (using different eTextRep values) then all
         4365  +** must give an equivalent answer when invoked with equivalent strings.
         4366  +** The collating function must obey the following properties for all
         4367  +** strings A, B, and C:
         4368  +**
         4369  +** <ol>
         4370  +** <li> If A==B then B==A.
         4371  +** <li> If A==B and B==C then A==C.
         4372  +** <li> If A&lt;B THEN B&gt;A.
         4373  +** <li> If A&lt;B and B&lt;C then A&lt;C.
         4374  +** </ol>
         4375  +**
         4376  +** If a collating function fails any of the above constraints and that
         4377  +** collating function is  registered and used, then the behavior of SQLite
         4378  +** is undefined.
  4264   4379   **
  4265   4380   ** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
  4266         -** except that it takes an extra argument which is a destructor for
  4267         -** the collation.  ^The destructor is called when the collation is
  4268         -** destroyed and is passed a copy of the fourth parameter void* pointer
  4269         -** of the sqlite3_create_collation_v2().
  4270         -** ^Collations are destroyed when they are overridden by later calls to the
  4271         -** collation creation functions or when the [database connection] is closed
  4272         -** using [sqlite3_close()].
         4381  +** with the addition that the xDestroy callback is invoked on pArg when
         4382  +** the collating function is deleted.
         4383  +** ^Collating functions are deleted when they are overridden by later
         4384  +** calls to the collation creation functions or when the
         4385  +** [database connection] is closed using [sqlite3_close()].
  4273   4386   **
  4274   4387   ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
  4275   4388   */
  4276   4389   SQLITE_API int sqlite3_create_collation(
  4277   4390     sqlite3*, 
  4278   4391     const char *zName, 
  4279   4392     int eTextRep, 
  4280         -  void*,
         4393  +  void *pArg,
  4281   4394     int(*xCompare)(void*,int,const void*,int,const void*)
  4282   4395   );
  4283   4396   SQLITE_API int sqlite3_create_collation_v2(
  4284   4397     sqlite3*, 
  4285   4398     const char *zName, 
  4286   4399     int eTextRep, 
  4287         -  void*,
         4400  +  void *pArg,
  4288   4401     int(*xCompare)(void*,int,const void*,int,const void*),
  4289   4402     void(*xDestroy)(void*)
  4290   4403   );
  4291   4404   SQLITE_API int sqlite3_create_collation16(
  4292   4405     sqlite3*, 
  4293   4406     const void *zName,
  4294   4407     int eTextRep, 
  4295         -  void*,
         4408  +  void *pArg,
  4296   4409     int(*xCompare)(void*,int,const void*,int,const void*)
  4297   4410   );
  4298   4411   
  4299   4412   /*
  4300   4413   ** CAPI3REF: Collation Needed Callbacks
  4301   4414   **
  4302   4415   ** ^To avoid having to register all collation sequences before a database
................................................................................
  4377   4490     const char *zPassPhrase        /* Activation phrase */
  4378   4491   );
  4379   4492   #endif
  4380   4493   
  4381   4494   /*
  4382   4495   ** CAPI3REF: Suspend Execution For A Short Time
  4383   4496   **
  4384         -** ^The sqlite3_sleep() function causes the current thread to suspend execution
         4497  +** The sqlite3_sleep() function causes the current thread to suspend execution
  4385   4498   ** for at least a number of milliseconds specified in its parameter.
  4386   4499   **
  4387         -** ^If the operating system does not support sleep requests with
         4500  +** If the operating system does not support sleep requests with
  4388   4501   ** millisecond time resolution, then the time will be rounded up to
  4389         -** the nearest second. ^The number of milliseconds of sleep actually
         4502  +** the nearest second. The number of milliseconds of sleep actually
  4390   4503   ** requested from the operating system is returned.
  4391   4504   **
  4392   4505   ** ^SQLite implements this interface by calling the xSleep()
  4393         -** method of the default [sqlite3_vfs] object.
         4506  +** method of the default [sqlite3_vfs] object.  If the xSleep() method
         4507  +** of the default VFS is not implemented correctly, or not implemented at
         4508  +** all, then the behavior of sqlite3_sleep() may deviate from the description
         4509  +** in the previous paragraphs.
  4394   4510   */
  4395   4511   SQLITE_API int sqlite3_sleep(int);
  4396   4512   
  4397   4513   /*
  4398   4514   ** CAPI3REF: Name Of The Folder Holding Temporary Files
  4399   4515   **
  4400   4516   ** ^(If this global variable is made to point to a string which is
................................................................................
  4608   4724   **
  4609   4725   ** ^The sqlite3_release_memory() interface attempts to free N bytes
  4610   4726   ** of heap memory by deallocating non-essential memory allocations
  4611   4727   ** held by the database library.   Memory used to cache database
  4612   4728   ** pages to improve performance is an example of non-essential memory.
  4613   4729   ** ^sqlite3_release_memory() returns the number of bytes actually freed,
  4614   4730   ** which might be more or less than the amount requested.
         4731  +** ^The sqlite3_release_memory() routine is a no-op returning zero
         4732  +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
  4615   4733   */
  4616   4734   SQLITE_API int sqlite3_release_memory(int);
  4617   4735   
  4618   4736   /*
  4619   4737   ** CAPI3REF: Impose A Limit On Heap Size
  4620   4738   **
  4621         -** ^The sqlite3_soft_heap_limit() interface places a "soft" limit
  4622         -** on the amount of heap memory that may be allocated by SQLite.
  4623         -** ^If an internal allocation is requested that would exceed the
  4624         -** soft heap limit, [sqlite3_release_memory()] is invoked one or
  4625         -** more times to free up some space before the allocation is performed.
  4626         -**
  4627         -** ^The limit is called "soft" because if [sqlite3_release_memory()]
  4628         -** cannot free sufficient memory to prevent the limit from being exceeded,
  4629         -** the memory is allocated anyway and the current operation proceeds.
  4630         -**
  4631         -** ^A negative or zero value for N means that there is no soft heap limit and
  4632         -** [sqlite3_release_memory()] will only be called when memory is exhausted.
  4633         -** ^The default value for the soft heap limit is zero.
  4634         -**
  4635         -** ^(SQLite makes a best effort to honor the soft heap limit.
  4636         -** But if the soft heap limit cannot be honored, execution will
  4637         -** continue without error or notification.)^  This is why the limit is
  4638         -** called a "soft" limit.  It is advisory only.
  4639         -**
  4640         -** Prior to SQLite version 3.5.0, this routine only constrained the memory
  4641         -** allocated by a single thread - the same thread in which this routine
  4642         -** runs.  Beginning with SQLite version 3.5.0, the soft heap limit is
  4643         -** applied to all threads. The value specified for the soft heap limit
  4644         -** is an upper bound on the total memory allocation for all threads. In
  4645         -** version 3.5.0 there is no mechanism for limiting the heap usage for
  4646         -** individual threads.
  4647         -*/
  4648         -SQLITE_API void sqlite3_soft_heap_limit(int);
         4739  +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
         4740  +** soft limit on the amount of heap memory that may be allocated by SQLite.
         4741  +** ^SQLite strives to keep heap memory utilization below the soft heap
         4742  +** limit by reducing the number of pages held in the page cache
         4743  +** as heap memory usages approaches the limit.
         4744  +** ^The soft heap limit is "soft" because even though SQLite strives to stay
         4745  +** below the limit, it will exceed the limit rather than generate
         4746  +** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
         4747  +** is advisory only.
         4748  +**
         4749  +** ^The return value from sqlite3_soft_heap_limit64() is the size of
         4750  +** the soft heap limit prior to the call.  ^If the argument N is negative
         4751  +** then no change is made to the soft heap limit.  Hence, the current
         4752  +** size of the soft heap limit can be determined by invoking
         4753  +** sqlite3_soft_heap_limit64() with a negative argument.
         4754  +**
         4755  +** ^If the argument N is zero then the soft heap limit is disabled.
         4756  +**
         4757  +** ^(The soft heap limit is not enforced in the current implementation
         4758  +** if one or more of following conditions are true:
         4759  +**
         4760  +** <ul>
         4761  +** <li> The soft heap limit is set to zero.
         4762  +** <li> Memory accounting is disabled using a combination of the
         4763  +**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
         4764  +**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
         4765  +** <li> An alternative page cache implementation is specifed using
         4766  +**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
         4767  +** <li> The page cache allocates from its own memory pool supplied
         4768  +**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
         4769  +**      from the heap.
         4770  +** </ul>)^
         4771  +**
         4772  +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
         4773  +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
         4774  +** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
         4775  +** the soft heap limit is enforced on every memory allocation.  Without
         4776  +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
         4777  +** when memory is allocated by the page cache.  Testing suggests that because
         4778  +** the page cache is the predominate memory user in SQLite, most
         4779  +** applications will achieve adequate soft heap limit enforcement without
         4780  +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
         4781  +**
         4782  +** The circumstances under which SQLite will enforce the soft heap limit may
         4783  +** changes in future releases of SQLite.
         4784  +*/
         4785  +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
         4786  +
         4787  +/*
         4788  +** CAPI3REF: Deprecated Soft Heap Limit Interface
         4789  +** DEPRECATED
         4790  +**
         4791  +** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
         4792  +** interface.  This routine is provided for historical compatibility
         4793  +** only.  All new applications should use the
         4794  +** [sqlite3_soft_heap_limit64()] interface rather than this one.
         4795  +*/
         4796  +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
         4797  +
  4649   4798   
  4650   4799   /*
  4651   4800   ** CAPI3REF: Extract Metadata About A Column Of A Table
  4652   4801   **
  4653   4802   ** ^This routine returns metadata about a specific column of a specific
  4654   4803   ** database table accessible using the [database connection] handle
  4655   4804   ** passed as the first function argument.
................................................................................
  4765   4914   ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
  4766   4915   ** to turn extension loading on and call it with onoff==0 to turn
  4767   4916   ** it back off again.
  4768   4917   */
  4769   4918   SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
  4770   4919   
  4771   4920   /*
  4772         -** CAPI3REF: Automatically Load An Extensions
  4773         -**
  4774         -** ^This API can be invoked at program startup in order to register
  4775         -** one or more statically linked extensions that will be available
  4776         -** to all new [database connections].
  4777         -**
  4778         -** ^(This routine stores a pointer to the extension entry point
  4779         -** in an array that is obtained from [sqlite3_malloc()].  That memory
  4780         -** is deallocated by [sqlite3_reset_auto_extension()].)^
  4781         -**
  4782         -** ^This function registers an extension entry point that is
  4783         -** automatically invoked whenever a new [database connection]
  4784         -** is opened using [sqlite3_open()], [sqlite3_open16()],
  4785         -** or [sqlite3_open_v2()].
  4786         -** ^Duplicate extensions are detected so calling this routine
  4787         -** multiple times with the same extension is harmless.
  4788         -** ^Automatic extensions apply across all threads.
         4921  +** CAPI3REF: Automatically Load Statically Linked Extensions
         4922  +**
         4923  +** ^This interface causes the xEntryPoint() function to be invoked for
         4924  +** each new [database connection] that is created.  The idea here is that
         4925  +** xEntryPoint() is the entry point for a statically linked SQLite extension
         4926  +** that is to be automatically loaded into all new database connections.
         4927  +**
         4928  +** ^(Even though the function prototype shows that xEntryPoint() takes
         4929  +** no arguments and returns void, SQLite invokes xEntryPoint() with three
         4930  +** arguments and expects and integer result as if the signature of the
         4931  +** entry point where as follows:
         4932  +**
         4933  +** <blockquote><pre>
         4934  +** &nbsp;  int xEntryPoint(
         4935  +** &nbsp;    sqlite3 *db,
         4936  +** &nbsp;    const char **pzErrMsg,
         4937  +** &nbsp;    const struct sqlite3_api_routines *pThunk
         4938  +** &nbsp;  );
         4939  +** </pre></blockquote>)^
         4940  +**
         4941  +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
         4942  +** point to an appropriate error message (obtained from [sqlite3_mprintf()])
         4943  +** and return an appropriate [error code].  ^SQLite ensures that *pzErrMsg
         4944  +** is NULL before calling the xEntryPoint().  ^SQLite will invoke
         4945  +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns.  ^If any
         4946  +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
         4947  +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
         4948  +**
         4949  +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
         4950  +** on the list of automatic extensions is a harmless no-op. ^No entry point
         4951  +** will be called more than once for each database connection that is opened.
         4952  +**
         4953  +** See also: [sqlite3_reset_auto_extension()].
  4789   4954   */
  4790   4955   SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
  4791   4956   
  4792   4957   /*
  4793   4958   ** CAPI3REF: Reset Automatic Extension Loading
  4794   4959   **
  4795         -** ^(This function disables all previously registered automatic
  4796         -** extensions. It undoes the effect of all prior
  4797         -** [sqlite3_auto_extension()] calls.)^
  4798         -**
  4799         -** ^This function disables automatic extensions in all threads.
         4960  +** ^This interface disables all automatic extensions previously
         4961  +** registered using [sqlite3_auto_extension()].
  4800   4962   */
  4801   4963   SQLITE_API void sqlite3_reset_auto_extension(void);
  4802   4964   
  4803   4965   /*
  4804   4966   ** The interface to the virtual-table mechanism is currently considered
  4805   4967   ** to be experimental.  The interface might change in incompatible ways.
  4806   4968   ** If this is a problem for you, do not use the interface at this time.
................................................................................
  5431   5593   ** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
  5432   5594   ** Additionally, an instance of this structure can be used as an
  5433   5595   ** output variable when querying the system for the current mutex
  5434   5596   ** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
  5435   5597   **
  5436   5598   ** ^The xMutexInit method defined by this structure is invoked as
  5437   5599   ** part of system initialization by the sqlite3_initialize() function.
  5438         -** ^The xMutexInit routine is calle by SQLite exactly once for each
         5600  +** ^The xMutexInit routine is called by SQLite exactly once for each
  5439   5601   ** effective call to [sqlite3_initialize()].
  5440   5602   **
  5441   5603   ** ^The xMutexEnd method defined by this structure is invoked as
  5442   5604   ** part of system shutdown by the sqlite3_shutdown() function. The
  5443   5605   ** implementation of this method is expected to release all outstanding
  5444   5606   ** resources obtained by the mutex methods implementation, especially
  5445   5607   ** those obtained by the xMutexInit method.  ^The xMutexEnd()
................................................................................
  5464   5626   ** of a valid mutex handle. The implementations of the methods defined
  5465   5627   ** by this structure are not required to handle this case, the results
  5466   5628   ** of passing a NULL pointer instead of a valid mutex handle are undefined
  5467   5629   ** (i.e. it is acceptable to provide an implementation that segfaults if
  5468   5630   ** it is passed a NULL pointer).
  5469   5631   **
  5470   5632   ** The xMutexInit() method must be threadsafe.  ^It must be harmless to
  5471         -** invoke xMutexInit() mutiple times within the same process and without
         5633  +** invoke xMutexInit() multiple times within the same process and without
  5472   5634   ** intervening calls to xMutexEnd().  Second and subsequent calls to
  5473   5635   ** xMutexInit() must be no-ops.
  5474   5636   **
  5475   5637   ** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
  5476   5638   ** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
  5477   5639   ** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
  5478   5640   ** memory allocation for a fast or recursive mutex.
................................................................................
  5628   5790   #define SQLITE_TESTCTRL_PENDING_BYTE            11
  5629   5791   #define SQLITE_TESTCTRL_ASSERT                  12
  5630   5792   #define SQLITE_TESTCTRL_ALWAYS                  13
  5631   5793   #define SQLITE_TESTCTRL_RESERVE                 14
  5632   5794   #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
  5633   5795   #define SQLITE_TESTCTRL_ISKEYWORD               16
  5634   5796   #define SQLITE_TESTCTRL_PGHDRSZ                 17
  5635         -#define SQLITE_TESTCTRL_LAST                    17
         5797  +#define SQLITE_TESTCTRL_SCRATCHMALLOC           18
         5798  +#define SQLITE_TESTCTRL_LAST                    18
  5636   5799   
  5637   5800   /*
  5638   5801   ** CAPI3REF: SQLite Runtime Status
  5639   5802   **
  5640   5803   ** ^This interface is used to retrieve runtime status information
  5641         -** about the preformance of SQLite, and optionally to reset various
         5804  +** about the performance of SQLite, and optionally to reset various
  5642   5805   ** highwater marks.  ^The first argument is an integer code for
  5643   5806   ** the specific parameter to measure.  ^(Recognized integer codes
  5644   5807   ** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^
  5645   5808   ** ^The current value of the parameter is returned into *pCurrent.
  5646   5809   ** ^The highest recorded value is returned in *pHighwater.  ^If the
  5647   5810   ** resetFlag is true, then the highest record value is reset after
  5648   5811   ** *pHighwater is written.  ^(Some parameters do not record the highest
  5649   5812   ** value.  For those parameters
  5650   5813   ** nothing is written into *pHighwater and the resetFlag is ignored.)^
  5651   5814   ** ^(Other parameters record only the highwater mark and not the current
  5652   5815   ** value.  For these latter parameters nothing is written into *pCurrent.)^
  5653   5816   **
  5654         -** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
         5817  +** ^The sqlite3_status() routine returns SQLITE_OK on success and a
  5655   5818   ** non-zero [error code] on failure.
  5656   5819   **
  5657   5820   ** This routine is threadsafe but is not atomic.  This routine can be
  5658   5821   ** called while other threads are running the same or different SQLite
  5659   5822   ** interfaces.  However the values returned in *pCurrent and
  5660   5823   ** *pHighwater reflect the status of SQLite at different points in time
  5661   5824   ** and it is possible that another thread might change the parameter
................................................................................
  5697   5860   ** <dd>This parameter returns the number of pages used out of the
  5698   5861   ** [pagecache memory allocator] that was configured using 
  5699   5862   ** [SQLITE_CONFIG_PAGECACHE].  The
  5700   5863   ** value returned is in pages, not in bytes.</dd>)^
  5701   5864   **
  5702   5865   ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
  5703   5866   ** <dd>This parameter returns the number of bytes of page cache
  5704         -** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
         5867  +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
  5705   5868   ** buffer and where forced to overflow to [sqlite3_malloc()].  The
  5706   5869   ** returned value includes allocations that overflowed because they
  5707   5870   ** where too large (they were larger than the "sz" parameter to
  5708   5871   ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
  5709   5872   ** no space was left in the page cache.</dd>)^
  5710   5873   **
  5711   5874   ** ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
................................................................................
  5720   5883   ** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
  5721   5884   ** in bytes.  Since a single thread may only have one scratch allocation
  5722   5885   ** outstanding at time, this parameter also reports the number of threads
  5723   5886   ** using scratch memory at the same time.</dd>)^
  5724   5887   **
  5725   5888   ** ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
  5726   5889   ** <dd>This parameter returns the number of bytes of scratch memory
  5727         -** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
         5890  +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
  5728   5891   ** buffer and where forced to overflow to [sqlite3_malloc()].  The values
  5729   5892   ** returned include overflows because the requested allocation was too
  5730   5893   ** larger (that is, because the requested allocation was larger than the
  5731   5894   ** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
  5732   5895   ** slots were available.
  5733   5896   ** </dd>)^
  5734   5897   **
................................................................................
  5760   5923   ** CAPI3REF: Database Connection Status
  5761   5924   **
  5762   5925   ** ^This interface is used to retrieve runtime status information 
  5763   5926   ** about a single [database connection].  ^The first argument is the
  5764   5927   ** database connection object to be interrogated.  ^The second argument
  5765   5928   ** is an integer constant, taken from the set of
  5766   5929   ** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros, that
  5767         -** determiness the parameter to interrogate.  The set of 
         5930  +** determines the parameter to interrogate.  The set of 
  5768   5931   ** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros is likely
  5769   5932   ** to grow in future releases of SQLite.
  5770   5933   **
  5771   5934   ** ^The current value of the requested parameter is written into *pCur
  5772   5935   ** and the highest instantaneous value is written into *pHiwtr.  ^If
  5773   5936   ** the resetFlg is true, then the highest instantaneous value is
  5774   5937   ** reset back down to the current value.
         5938  +**
         5939  +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
         5940  +** non-zero [error code] on failure.
  5775   5941   **
  5776   5942   ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
  5777   5943   */
  5778   5944   SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
  5779   5945   
  5780   5946   /*
  5781   5947   ** CAPI3REF: Status Parameters for database connections
................................................................................
  5895   6061   
  5896   6062   /*
  5897   6063   ** CAPI3REF: Application Defined Page Cache.
  5898   6064   ** KEYWORDS: {page cache}
  5899   6065   **
  5900   6066   ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
  5901   6067   ** register an alternative page cache implementation by passing in an 
  5902         -** instance of the sqlite3_pcache_methods structure.)^ The majority of the 
  5903         -** heap memory used by SQLite is used by the page cache to cache data read 
  5904         -** from, or ready to be written to, the database file. By implementing a 
  5905         -** custom page cache using this API, an application can control more 
  5906         -** precisely the amount of memory consumed by SQLite, the way in which 
         6068  +** instance of the sqlite3_pcache_methods structure.)^
         6069  +** In many applications, most of the heap memory allocated by 
         6070  +** SQLite is used for the page cache.
         6071  +** By implementing a 
         6072  +** custom page cache using this API, an application can better control
         6073  +** the amount of memory consumed by SQLite, the way in which 
  5907   6074   ** that memory is allocated and released, and the policies used to 
  5908   6075   ** determine exactly which parts of a database file are cached and for 
  5909   6076   ** how long.
  5910   6077   **
         6078  +** The alternative page cache mechanism is an
         6079  +** extreme measure that is only needed by the most demanding applications.
         6080  +** The built-in page cache is recommended for most uses.
         6081  +**
  5911   6082   ** ^(The contents of the sqlite3_pcache_methods structure are copied to an
  5912   6083   ** internal buffer by SQLite within the call to [sqlite3_config].  Hence
  5913   6084   ** the application may discard the parameter after the call to
  5914   6085   ** [sqlite3_config()] returns.)^
  5915   6086   **
  5916         -** ^The xInit() method is called once for each call to [sqlite3_initialize()]
         6087  +** ^(The xInit() method is called once for each effective 
         6088  +** call to [sqlite3_initialize()])^
  5917   6089   ** (usually only once during the lifetime of the process). ^(The xInit()
  5918   6090   ** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^
  5919         -** ^The xInit() method can set up up global structures and/or any mutexes
         6091  +** The intent of the xInit() method is to set up global data structures 
  5920   6092   ** required by the custom page cache implementation. 
         6093  +** ^(If the xInit() method is NULL, then the 
         6094  +** built-in default page cache is used instead of the application defined
         6095  +** page cache.)^
  5921   6096   **
  5922         -** ^The xShutdown() method is called from within [sqlite3_shutdown()], 
  5923         -** if the application invokes this API. It can be used to clean up 
         6097  +** ^The xShutdown() method is called by [sqlite3_shutdown()].
         6098  +** It can be used to clean up 
  5924   6099   ** any outstanding resources before process shutdown, if required.
         6100  +** ^The xShutdown() method may be NULL.
  5925   6101   **
  5926         -** ^SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
  5927         -** the xInit method, so the xInit method need not be threadsafe.  ^The
         6102  +** ^SQLite automatically serializes calls to the xInit method,
         6103  +** so the xInit method need not be threadsafe.  ^The
  5928   6104   ** xShutdown method is only called from [sqlite3_shutdown()] so it does
  5929   6105   ** not need to be threadsafe either.  All other methods must be threadsafe
  5930   6106   ** in multithreaded applications.
  5931   6107   **
  5932   6108   ** ^SQLite will never invoke xInit() more than once without an intervening
  5933   6109   ** call to xShutdown().
  5934   6110   **
  5935         -** ^The xCreate() method is used to construct a new cache instance.  SQLite
  5936         -** will typically create one cache instance for each open database file,
         6111  +** ^SQLite invokes the xCreate() method to construct a new cache instance.
         6112  +** SQLite will typically create one cache instance for each open database file,
  5937   6113   ** though this is not guaranteed. ^The
  5938   6114   ** first parameter, szPage, is the size in bytes of the pages that must
  5939   6115   ** be allocated by the cache.  ^szPage will not be a power of two.  ^szPage
  5940   6116   ** will the page size of the database file that is to be cached plus an
  5941         -** increment (here called "R") of about 100 or 200.  ^SQLite will use the
         6117  +** increment (here called "R") of about 100 or 200.  SQLite will use the
  5942   6118   ** extra R bytes on each page to store metadata about the underlying
  5943   6119   ** database page on disk.  The value of R depends
  5944   6120   ** on the SQLite version, the target platform, and how SQLite was compiled.
  5945   6121   ** ^R is constant for a particular build of SQLite.  ^The second argument to
  5946   6122   ** xCreate(), bPurgeable, is true if the cache being created will
  5947   6123   ** be used to cache database pages of a file stored on disk, or
  5948         -** false if it is used for an in-memory database. ^The cache implementation
         6124  +** false if it is used for an in-memory database. The cache implementation
  5949   6125   ** does not have to do anything special based with the value of bPurgeable;
  5950   6126   ** it is purely advisory.  ^On a cache where bPurgeable is false, SQLite will
  5951   6127   ** never invoke xUnpin() except to deliberately delete a page.
  5952         -** ^In other words, a cache created with bPurgeable set to false will
         6128  +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
         6129  +** false will always have the "discard" flag set to true.  
         6130  +** ^Hence, a cache created with bPurgeable false will
  5953   6131   ** never contain any unpinned pages.
  5954   6132   **
  5955   6133   ** ^(The xCachesize() method may be called at any time by SQLite to set the
  5956   6134   ** suggested maximum cache-size (number of pages stored by) the cache
  5957   6135   ** instance passed as the first argument. This is the value configured using
  5958         -** the SQLite "[PRAGMA cache_size]" command.)^  ^As with the bPurgeable
         6136  +** the SQLite "[PRAGMA cache_size]" command.)^  As with the bPurgeable
  5959   6137   ** parameter, the implementation is not required to do anything with this
  5960   6138   ** value; it is advisory only.
  5961   6139   **
  5962         -** ^The xPagecount() method should return the number of pages currently
  5963         -** stored in the cache.
         6140  +** The xPagecount() method must return the number of pages currently
         6141  +** stored in the cache, both pinned and unpinned.
  5964   6142   ** 
  5965         -** ^The xFetch() method is used to fetch a page and return a pointer to it. 
  5966         -** ^A 'page', in this context, is a buffer of szPage bytes aligned at an
  5967         -** 8-byte boundary. ^The page to be fetched is determined by the key. ^The
  5968         -** mimimum key value is 1. After it has been retrieved using xFetch, the page 
         6143  +** The xFetch() method locates a page in the cache and returns a pointer to 
         6144  +** the page, or a NULL pointer.
         6145  +** A "page", in this context, means a buffer of szPage bytes aligned at an
         6146  +** 8-byte boundary. The page to be fetched is determined by the key. ^The
         6147  +** mimimum key value is 1.  After it has been retrieved using xFetch, the page 
  5969   6148   ** is considered to be "pinned".
  5970   6149   **
  5971         -** ^If the requested page is already in the page cache, then the page cache
         6150  +** If the requested page is already in the page cache, then the page cache
  5972   6151   ** implementation must return a pointer to the page buffer with its content
  5973         -** intact.  ^(If the requested page is not already in the cache, then the
  5974         -** behavior of the cache implementation is determined by the value of the
  5975         -** createFlag parameter passed to xFetch, according to the following table:
         6152  +** intact.  If the requested page is not already in the cache, then the
         6153  +** behavior of the cache implementation should use the value of the createFlag
         6154  +** parameter to help it determined what action to take:
  5976   6155   **
  5977   6156   ** <table border=1 width=85% align=center>
  5978   6157   ** <tr><th> createFlag <th> Behaviour when page is not already in cache
  5979   6158   ** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
  5980   6159   ** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
  5981   6160   **                 Otherwise return NULL.
  5982   6161   ** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
  5983   6162   **                 NULL if allocating a new page is effectively impossible.
  5984         -** </table>)^
         6163  +** </table>
  5985   6164   **
  5986         -** SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  If
  5987         -** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
         6165  +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
         6166  +** will only use a createFlag of 2 after a prior call with a createFlag of 1
         6167  +** failed.)^  In between the to xFetch() calls, SQLite may
  5988   6168   ** attempt to unpin one or more cache pages by spilling the content of
  5989         -** pinned pages to disk and synching the operating system disk cache. After
  5990         -** attempting to unpin pages, the xFetch() method will be invoked again with
  5991         -** a createFlag of 2.
         6169  +** pinned pages to disk and synching the operating system disk cache.
  5992   6170   **
  5993   6171   ** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
  5994         -** as its second argument. ^(If the third parameter, discard, is non-zero,
  5995         -** then the page should be evicted from the cache. In this case SQLite 
  5996         -** assumes that the next time the page is retrieved from the cache using
  5997         -** the xFetch() method, it will be zeroed.)^ ^If the discard parameter is
  5998         -** zero, then the page is considered to be unpinned. ^The cache implementation
         6172  +** as its second argument.  If the third parameter, discard, is non-zero,
         6173  +** then the page must be evicted from the cache.
         6174  +** ^If the discard parameter is
         6175  +** zero, then the page may be discarded or retained at the discretion of
         6176  +** page cache implementation. ^The page cache implementation
  5999   6177   ** may choose to evict unpinned pages at any time.
  6000   6178   **
  6001         -** ^(The cache is not required to perform any reference counting. A single 
         6179  +** The cache must not perform any reference counting. A single 
  6002   6180   ** call to xUnpin() unpins the page regardless of the number of prior calls 
  6003         -** to xFetch().)^
         6181  +** to xFetch().
  6004   6182   **
  6005         -** ^The xRekey() method is used to change the key value associated with the
  6006         -** page passed as the second argument from oldKey to newKey. ^If the cache
  6007         -** previously contains an entry associated with newKey, it should be
         6183  +** The xRekey() method is used to change the key value associated with the
         6184  +** page passed as the second argument. If the cache
         6185  +** previously contains an entry associated with newKey, it must be
  6008   6186   ** discarded. ^Any prior cache entry associated with newKey is guaranteed not
  6009   6187   ** to be pinned.
  6010   6188   **
  6011         -** ^When SQLite calls the xTruncate() method, the cache must discard all
         6189  +** When SQLite calls the xTruncate() method, the cache must discard all
  6012   6190   ** existing cache entries with page numbers (keys) greater than or equal
  6013         -** to the value of the iLimit parameter passed to xTruncate(). ^If any
         6191  +** to the value of the iLimit parameter passed to xTruncate(). If any
  6014   6192   ** of these pages are pinned, they are implicitly unpinned, meaning that
  6015   6193   ** they can be safely discarded.
  6016   6194   **
  6017   6195   ** ^The xDestroy() method is used to delete a cache allocated by xCreate().
  6018   6196   ** All resources associated with the specified cache should be freed. ^After
  6019   6197   ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
  6020   6198   ** handle invalid, and will not use it with any other sqlite3_pcache_methods
................................................................................
  6182   6360   ** is not a permanent error and does not affect the return value of
  6183   6361   ** sqlite3_backup_finish().
  6184   6362   **
  6185   6363   ** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
  6186   6364   **
  6187   6365   ** ^Each call to sqlite3_backup_step() sets two values inside
  6188   6366   ** the [sqlite3_backup] object: the number of pages still to be backed
  6189         -** up and the total number of pages in the source databae file.
         6367  +** up and the total number of pages in the source database file.
  6190   6368   ** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
  6191   6369   ** retrieve these two values, respectively.
  6192   6370   **
  6193   6371   ** ^The values returned by these functions are only updated by
  6194   6372   ** sqlite3_backup_step(). ^If the source database is modified during a backup
  6195   6373   ** operation, then the values are not updated to account for any extra
  6196   6374   ** pages that need to be updated or the size of the source database file
................................................................................
  6278   6456   ** the other connections to use as the blocking connection.
  6279   6457   **
  6280   6458   ** ^(There may be at most one unlock-notify callback registered by a 
  6281   6459   ** blocked connection. If sqlite3_unlock_notify() is called when the
  6282   6460   ** blocked connection already has a registered unlock-notify callback,
  6283   6461   ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
  6284   6462   ** called with a NULL pointer as its second argument, then any existing
  6285         -** unlock-notify callback is cancelled. ^The blocked connections 
         6463  +** unlock-notify callback is canceled. ^The blocked connections 
  6286   6464   ** unlock-notify callback may also be canceled by closing the blocked
  6287   6465   ** connection using [sqlite3_close()].
  6288   6466   **
  6289   6467   ** The unlock-notify callback is not reentrant. If an application invokes
  6290   6468   ** any sqlite3_xxx API functions from within an unlock-notify callback, a
  6291   6469   ** crash or deadlock may be the result.
  6292   6470   **
................................................................................
  6360   6538   
  6361   6539   
  6362   6540   /*
  6363   6541   ** CAPI3REF: String Comparison
  6364   6542   **
  6365   6543   ** ^The [sqlite3_strnicmp()] API allows applications and extensions to
  6366   6544   ** compare the contents of two buffers containing UTF-8 strings in a
  6367         -** case-indendent fashion, using the same definition of case independence 
         6545  +** case-independent fashion, using the same definition of case independence 
  6368   6546   ** that SQLite uses internally when comparing identifiers.
  6369   6547   */
  6370   6548   SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
  6371   6549   
  6372   6550   /*
  6373   6551   ** CAPI3REF: Error Logging Interface
  6374   6552   **
................................................................................
  6484   6662   #endif
  6485   6663   
  6486   6664   #if 0
  6487   6665   }  /* End of the 'extern "C"' block */
  6488   6666   #endif
  6489   6667   #endif
  6490   6668   
         6669  +/*
         6670  +** 2010 August 30
         6671  +**
         6672  +** The author disclaims copyright to this source code.  In place of
         6673  +** a legal notice, here is a blessing:
         6674  +**
         6675  +**    May you do good and not evil.
         6676  +**    May you find forgiveness for yourself and forgive others.
         6677  +**    May you share freely, never taking more than you give.
         6678  +**
         6679  +*************************************************************************
         6680  +*/
         6681  +
         6682  +#ifndef _SQLITE3RTREE_H_
         6683  +#define _SQLITE3RTREE_H_
         6684  +
         6685  +
         6686  +#if 0
         6687  +extern "C" {
         6688  +#endif
         6689  +
         6690  +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
         6691  +
         6692  +/*
         6693  +** Register a geometry callback named zGeom that can be used as part of an
         6694  +** R-Tree geometry query as follows:
         6695  +**
         6696  +**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
         6697  +*/
         6698  +SQLITE_API int sqlite3_rtree_geometry_callback(
         6699  +  sqlite3 *db,
         6700  +  const char *zGeom,
         6701  +  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
         6702  +  void *pContext
         6703  +);
         6704  +
         6705  +
         6706  +/*
         6707  +** A pointer to a structure of the following type is passed as the first
         6708  +** argument to callbacks registered using rtree_geometry_callback().
         6709  +*/
         6710  +struct sqlite3_rtree_geometry {
         6711  +  void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
         6712  +  int nParam;                     /* Size of array aParam[] */
         6713  +  double *aParam;                 /* Parameters passed to SQL geom function */
         6714  +  void *pUser;                    /* Callback implementation user data */
         6715  +  void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
         6716  +};
         6717  +
         6718  +
         6719  +#if 0
         6720  +}  /* end of the 'extern "C"' block */
         6721  +#endif
         6722  +
         6723  +#endif  /* ifndef _SQLITE3RTREE_H_ */
         6724  +
  6491   6725   
  6492   6726   /************** End of sqlite3.h *********************************************/
  6493   6727   /************** Continuing where we left off in sqliteInt.h ******************/
  6494   6728   /************** Include hash.h in the middle of sqliteInt.h ******************/
  6495   6729   /************** Begin file hash.h ********************************************/
  6496   6730   /*
  6497   6731   ** 2001 September 22
................................................................................
  7054   7288   typedef struct Column Column;
  7055   7289   typedef struct Db Db;
  7056   7290   typedef struct Schema Schema;
  7057   7291   typedef struct Expr Expr;
  7058   7292   typedef struct ExprList ExprList;
  7059   7293   typedef struct ExprSpan ExprSpan;
  7060   7294   typedef struct FKey FKey;
         7295  +typedef struct FuncDestructor FuncDestructor;
  7061   7296   typedef struct FuncDef FuncDef;
  7062   7297   typedef struct FuncDefHash FuncDefHash;
  7063   7298   typedef struct IdList IdList;
  7064   7299   typedef struct Index Index;
  7065   7300   typedef struct IndexSample IndexSample;
  7066   7301   typedef struct KeyClass KeyClass;
  7067   7302   typedef struct KeyInfo KeyInfo;
................................................................................
  7160   7395   
  7161   7396   /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
  7162   7397   ** following values.
  7163   7398   **
  7164   7399   ** NOTE:  These values must match the corresponding PAGER_ values in
  7165   7400   ** pager.h.
  7166   7401   */
  7167         -#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
         7402  +#define BTREE_OMIT_JOURNAL  1  /* Do not create or use a rollback journal */
  7168   7403   #define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
  7169         -#define BTREE_MEMORY        4  /* In-memory DB.  No argument */
  7170         -#define BTREE_READONLY      8  /* Open the database in read-only mode */
  7171         -#define BTREE_READWRITE    16  /* Open for both reading and writing */
  7172         -#define BTREE_CREATE       32  /* Create the database if it does not exist */
         7404  +#define BTREE_MEMORY        4  /* This is an in-memory DB */
         7405  +#define BTREE_SINGLE        8  /* The file contains at most 1 b-tree */
         7406  +#define BTREE_UNORDERED    16  /* Use of a hash implementation is OK */
  7173   7407   
  7174   7408   SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
  7175   7409   SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
  7176   7410   SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
  7177   7411   SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
  7178   7412   SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
  7179   7413   SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
................................................................................
  7201   7435   SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
  7202   7436   SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
  7203   7437   SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
  7204   7438   
  7205   7439   SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
  7206   7440   
  7207   7441   /* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
  7208         -** of the following flags:
         7442  +** of the flags shown below.
         7443  +**
         7444  +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
         7445  +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
         7446  +** is stored in the leaves.  (BTREE_INTKEY is used for SQL tables.)  With
         7447  +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
         7448  +** anywhere - the key is the content.  (BTREE_BLOBKEY is used for SQL
         7449  +** indices.)
  7209   7450   */
  7210   7451   #define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
  7211         -#define BTREE_ZERODATA   2    /* Table has keys only - no data */
  7212         -#define BTREE_LEAFDATA   4    /* Data stored in leaves only.  Implies INTKEY */
         7452  +#define BTREE_BLOBKEY    2    /* Table has keys only - no data */
  7213   7453   
  7214   7454   SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
  7215   7455   SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
  7216   7456   SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
  7217   7457   
  7218   7458   SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
  7219   7459   SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
................................................................................
  7826   8066   /*
  7827   8067   ** Allowed values for the flags parameter to sqlite3PagerOpen().
  7828   8068   **
  7829   8069   ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
  7830   8070   */
  7831   8071   #define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
  7832   8072   #define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
         8073  +#define PAGER_MEMORY        0x0004    /* In-memory database */
  7833   8074   
  7834   8075   /*
  7835   8076   ** Valid values for the second argument to sqlite3PagerLockingMode().
  7836   8077   */
  7837   8078   #define PAGER_LOCKINGMODE_QUERY      -1
  7838   8079   #define PAGER_LOCKINGMODE_NORMAL      0
  7839   8080   #define PAGER_LOCKINGMODE_EXCLUSIVE   1
................................................................................
  7866   8107     void(*)(DbPage*)
  7867   8108   );
  7868   8109   SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
  7869   8110   SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
  7870   8111   
  7871   8112   /* Functions used to configure a Pager object. */
  7872   8113   SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
  7873         -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int);
         8114  +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
  7874   8115   SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
  7875   8116   SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
  7876   8117   SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
  7877   8118   SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
  7878   8119   SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
  7879   8120   SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
  7880   8121   SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
................................................................................
  7893   8134   SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*);
  7894   8135   SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
  7895   8136   SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*);
  7896   8137   SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); 
  7897   8138   SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); 
  7898   8139   
  7899   8140   /* Functions used to manage pager transactions and savepoints. */
  7900         -SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*);
         8141  +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*);
  7901   8142   SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int);
  7902   8143   SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
  7903   8144   SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*);
  7904   8145   SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
  7905   8146   SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
  7906   8147   SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
  7907   8148   SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
................................................................................
  8460   8701   ** If this is a no-op implementation, implement everything as macros.
  8461   8702   */
  8462   8703   #define sqlite3_mutex_alloc(X)    ((sqlite3_mutex*)8)
  8463   8704   #define sqlite3_mutex_free(X)
  8464   8705   #define sqlite3_mutex_enter(X)
  8465   8706   #define sqlite3_mutex_try(X)      SQLITE_OK
  8466   8707   #define sqlite3_mutex_leave(X)
  8467         -#define sqlite3_mutex_held(X)     1
  8468         -#define sqlite3_mutex_notheld(X)  1
         8708  +#define sqlite3_mutex_held(X)     ((void)(X),1)
         8709  +#define sqlite3_mutex_notheld(X)  ((void)(X),1)
  8469   8710   #define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
  8470   8711   #define sqlite3MutexInit()        SQLITE_OK
  8471   8712   #define sqlite3MutexEnd()
  8472   8713   #endif /* defined(SQLITE_MUTEX_OMIT) */
  8473   8714   
  8474   8715   /************** End of mutex.h ***********************************************/
  8475   8716   /************** Continuing where we left off in sqliteInt.h ******************/
................................................................................
  8783   9024     void *pUserData;     /* User data parameter */
  8784   9025     FuncDef *pNext;      /* Next function with same name */
  8785   9026     void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
  8786   9027     void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
  8787   9028     void (*xFinalize)(sqlite3_context*);                /* Aggregate finalizer */
  8788   9029     char *zName;         /* SQL name of the function. */
  8789   9030     FuncDef *pHash;      /* Next with a different name but the same hash */
         9031  +  FuncDestructor *pDestructor;   /* Reference counted destructor function */
         9032  +};
         9033  +
         9034  +/*
         9035  +** This structure encapsulates a user-function destructor callback (as
         9036  +** configured using create_function_v2()) and a reference counter. When
         9037  +** create_function_v2() is called to create a function with a destructor,
         9038  +** a single object of this type is allocated. FuncDestructor.nRef is set to 
         9039  +** the number of FuncDef objects created (either 1 or 3, depending on whether
         9040  +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
         9041  +** member of each of the new FuncDef objects is set to point to the allocated
         9042  +** FuncDestructor.
         9043  +**
         9044  +** Thereafter, when one of the FuncDef objects is deleted, the reference
         9045  +** count on this object is decremented. When it reaches 0, the destructor
         9046  +** is invoked and the FuncDestructor structure freed.
         9047  +*/
         9048  +struct FuncDestructor {
         9049  +  int nRef;
         9050  +  void (*xDestroy)(void *);
         9051  +  void *pUserData;
  8790   9052   };
  8791   9053   
  8792   9054   /*
  8793   9055   ** Possible values for FuncDef.flags
  8794   9056   */
  8795   9057   #define SQLITE_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
  8796   9058   #define SQLITE_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
................................................................................
  8823   9085   **     function likeFunc. Argument pArg is cast to a (void *) and made
  8824   9086   **     available as the function user-data (sqlite3_user_data()). The
  8825   9087   **     FuncDef.flags variable is set to the value passed as the flags
  8826   9088   **     parameter.
  8827   9089   */
  8828   9090   #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
  8829   9091     {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
  8830         -   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
         9092  +   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
  8831   9093   #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
  8832   9094     {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
  8833         -   pArg, 0, xFunc, 0, 0, #zName, 0}
         9095  +   pArg, 0, xFunc, 0, 0, #zName, 0, 0}
  8834   9096   #define LIKEFUNC(zName, nArg, arg, flags) \
  8835         -  {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0}
         9097  +  {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
  8836   9098   #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
  8837   9099     {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
  8838         -   SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
         9100  +   SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
  8839   9101   
  8840   9102   /*
  8841   9103   ** All current savepoints are stored in a linked list starting at
  8842   9104   ** sqlite3.pSavepoint. The first element in the list is the most recently
  8843   9105   ** opened savepoint. Savepoints are added to the list by the vdbe
  8844   9106   ** OP_Savepoint instruction.
  8845   9107   */
................................................................................
  9051   9313   struct Table {
  9052   9314     char *zName;         /* Name of the table or view */
  9053   9315     int iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
  9054   9316     int nCol;            /* Number of columns in this table */
  9055   9317     Column *aCol;        /* Information about each column */
  9056   9318     Index *pIndex;       /* List of SQL indexes on this table. */
  9057   9319     int tnum;            /* Root BTree node for this table (see note above) */
         9320  +  unsigned nRowEst;    /* Estimated rows in table - from sqlite_stat1 table */
  9058   9321     Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
  9059   9322     u16 nRef;            /* Number of pointers to this Table */
  9060   9323     u8 tabFlags;         /* Mask of TF_* values */
  9061   9324     u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  9062   9325     FKey *pFKey;         /* Linked list of all foreign keys in this table */
  9063   9326     char *zColAff;       /* String defining the affinity of each column */
  9064   9327   #ifndef SQLITE_OMIT_CHECK
................................................................................
  9181   9444   /*
  9182   9445   ** An instance of the following structure is passed as the first
  9183   9446   ** argument to sqlite3VdbeKeyCompare and is used to control the 
  9184   9447   ** comparison of the two index keys.
  9185   9448   */
  9186   9449   struct KeyInfo {
  9187   9450     sqlite3 *db;        /* The database connection */
  9188         -  u8 enc;             /* Text encoding - one of the TEXT_Utf* values */
         9451  +  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  9189   9452     u16 nField;         /* Number of entries in aColl[] */
  9190         -  u8 *aSortOrder;     /* If defined an aSortOrder[i] is true, sort DESC */
         9453  +  u8 *aSortOrder;     /* Sort order for each column.  May be NULL */
  9191   9454     CollSeq *aColl[1];  /* Collating sequence for each term of the key */
  9192   9455   };
  9193   9456   
  9194   9457   /*
  9195   9458   ** An instance of the following structure holds information about a
  9196   9459   ** single index record that has already been parsed out into individual
  9197   9460   ** values.
................................................................................
 10305  10568   # define sqlite3Tolower(x)   tolower((unsigned char)(x))
 10306  10569   #endif
 10307  10570   
 10308  10571   /*
 10309  10572   ** Internal function prototypes
 10310  10573   */
 10311  10574   SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
 10312         -SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8);
 10313  10575   SQLITE_PRIVATE int sqlite3Strlen30(const char*);
 10314  10576   #define sqlite3StrNICmp sqlite3_strnicmp
 10315  10577   
 10316  10578   SQLITE_PRIVATE int sqlite3MallocInit(void);
 10317  10579   SQLITE_PRIVATE void sqlite3MallocEnd(void);
 10318  10580   SQLITE_PRIVATE void *sqlite3Malloc(int);
 10319  10581   SQLITE_PRIVATE void *sqlite3MallocZero(int);
................................................................................
 10329  10591   SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
 10330  10592   SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
 10331  10593   SQLITE_PRIVATE void sqlite3ScratchFree(void*);
 10332  10594   SQLITE_PRIVATE void *sqlite3PageMalloc(int);
 10333  10595   SQLITE_PRIVATE void sqlite3PageFree(void*);
 10334  10596   SQLITE_PRIVATE void sqlite3MemSetDefault(void);
 10335  10597   SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
 10336         -SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
        10598  +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
 10337  10599   
 10338  10600   /*
 10339  10601   ** On systems with ample stack space and that support alloca(), make
 10340  10602   ** use of alloca() to obtain space for large automatic objects.  By default,
 10341  10603   ** obtain space from malloc().
 10342  10604   **
 10343  10605   ** The alloca() routine never returns NULL.  This will cause code paths
................................................................................
 10500  10762   SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
 10501  10763   SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
 10502  10764   SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
 10503  10765   SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
 10504  10766   SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
 10505  10767   SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
 10506  10768   SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
 10507         -SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse*,int,int);
 10508  10769   SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
 10509  10770   SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
 10510  10771   SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
 10511  10772   SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
 10512  10773   SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*);
 10513  10774   SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
 10514  10775   SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
................................................................................
 10620  10881   # define sqlite3AuthRead(a,b,c,d)
 10621  10882   # define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
 10622  10883   # define sqlite3AuthContextPush(a,b,c)
 10623  10884   # define sqlite3AuthContextPop(a)  ((void)(a))
 10624  10885   #endif
 10625  10886   SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
 10626  10887   SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
 10627         -SQLITE_PRIVATE int sqlite3BtreeFactory(sqlite3 *db, const char *zFilename,
 10628         -                       int omitJournal, int nCache, int flags, Btree **ppBtree);
 10629  10888   SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
 10630  10889   SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*);
 10631  10890   SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
 10632  10891   SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
 10633  10892   SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
 10634  10893   SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
 10635         -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*);
        10894  +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
 10636  10895   SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
 10637         -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *, int);
 10638  10896   SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
 10639  10897   SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
 10640  10898   SQLITE_PRIVATE int sqlite3Utf8Read(const u8*, const u8**);
 10641  10899   
 10642  10900   /*
 10643  10901   ** Routines to read and write variable-length integers.  These used to
 10644  10902   ** be defined locally, but now we use the varint routines in the util.c
................................................................................
 10676  10934   
 10677  10935   
 10678  10936   SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
 10679  10937   SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
 10680  10938   SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
 10681  10939   SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
 10682  10940   SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
 10683         -SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*);
        10941  +SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
 10684  10942   SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...);
 10685  10943   SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
 10686  10944   SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
 10687  10945   SQLITE_PRIVATE const char *sqlite3ErrStr(int);
 10688  10946   SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
 10689  10947   SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
 10690  10948   SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
................................................................................
 10747  11005   SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
 10748  11006   SQLITE_PRIVATE void sqlite3SchemaFree(void *);
 10749  11007   SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
 10750  11008   SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
 10751  11009   SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
 10752  11010   SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
 10753  11011     void (*)(sqlite3_context*,int,sqlite3_value **),
 10754         -  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
        11012  +  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
        11013  +  FuncDestructor *pDestructor
        11014  +);
 10755  11015   SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
 10756  11016   SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
 10757  11017   
 10758  11018   SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
 10759  11019   SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
 10760  11020   SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
 10761  11021   SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
................................................................................
 11667  11927     Bool rowidIsValid;    /* True if lastRowid is valid */
 11668  11928     Bool atFirst;         /* True if pointing to first entry */
 11669  11929     Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
 11670  11930     Bool nullRow;         /* True if pointing to a row with no data */
 11671  11931     Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
 11672  11932     Bool isTable;         /* True if a table requiring integer keys */
 11673  11933     Bool isIndex;         /* True if an index containing keys only - no data */
        11934  +  Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
 11674  11935     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
 11675  11936     Btree *pBt;           /* Separate file holding temporary table */
 11676  11937     int pseudoTableReg;   /* Register holding pseudotable content. */
 11677  11938     KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
 11678  11939     int nField;           /* Number of fields in the header */
 11679  11940     i64 seqCount;         /* Sequence counter */
 11680  11941     sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
................................................................................
 11761  12022     double r;           /* Real value */
 11762  12023     sqlite3 *db;        /* The associated database connection */
 11763  12024     char *z;            /* String or BLOB value */
 11764  12025     int n;              /* Number of characters in string value, excluding '\0' */
 11765  12026     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
 11766  12027     u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
 11767  12028     u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
        12029  +#ifdef SQLITE_DEBUG
        12030  +  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
        12031  +  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
        12032  +#endif
 11768  12033     void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
 11769  12034     char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
 11770  12035   };
 11771  12036   
 11772  12037   /* One or more of the following flags are set to indicate the validOK
 11773  12038   ** representations of the value stored in the Mem struct.
 11774  12039   **
................................................................................
 11787  12052   #define MEM_Null      0x0001   /* Value is NULL */
 11788  12053   #define MEM_Str       0x0002   /* Value is a string */
 11789  12054   #define MEM_Int       0x0004   /* Value is an integer */
 11790  12055   #define MEM_Real      0x0008   /* Value is a real number */
 11791  12056   #define MEM_Blob      0x0010   /* Value is a BLOB */
 11792  12057   #define MEM_RowSet    0x0020   /* Value is a RowSet object */
 11793  12058   #define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
        12059  +#define MEM_Invalid   0x0080   /* Value is undefined */
 11794  12060   #define MEM_TypeMask  0x00ff   /* Mask of type bits */
 11795  12061   
 11796  12062   /* Whenever Mem contains a valid string or blob representation, one of
 11797  12063   ** the following flags must be set to determine the memory management
 11798  12064   ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
 11799  12065   ** string is \000 or \u0000 terminated
 11800  12066   */
 11801  12067   #define MEM_Term      0x0200   /* String rep is nul terminated */
 11802  12068   #define MEM_Dyn       0x0400   /* Need to call sqliteFree() on Mem.z */
 11803  12069   #define MEM_Static    0x0800   /* Mem.z points to a static string */
 11804  12070   #define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
 11805  12071   #define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
 11806  12072   #define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
 11807         -
 11808  12073   #ifdef SQLITE_OMIT_INCRBLOB
 11809  12074     #undef MEM_Zero
 11810  12075     #define MEM_Zero 0x0000
 11811  12076   #endif
 11812         -
 11813  12077   
 11814  12078   /*
 11815  12079   ** Clear any existing type flags from a Mem and replace them with f
 11816  12080   */
 11817  12081   #define MemSetTypeFlag(p, f) \
 11818  12082      ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
 11819  12083   
        12084  +/*
        12085  +** Return true if a memory cell is not marked as invalid.  This macro
        12086  +** is for use inside assert() statements only.
        12087  +*/
        12088  +#ifdef SQLITE_DEBUG
        12089  +#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
        12090  +#endif
        12091  +
 11820  12092   
 11821  12093   /* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
 11822  12094   ** additional information about auxiliary information bound to arguments
 11823  12095   ** of the function.  This is used to implement the sqlite3_get_auxdata()
 11824  12096   ** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
 11825  12097   ** that can be associated with a constant argument to a function.  This
 11826  12098   ** allows functions such as "regexp" to compile their constant regular
................................................................................
 12000  12272   SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
 12001  12273   SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
 12002  12274   SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
 12003  12275   SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
 12004  12276   SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
 12005  12277   SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
 12006  12278   SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
        12279  +
        12280  +#ifdef SQLITE_DEBUG
        12281  +SQLITE_PRIVATE void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*);
        12282  +#endif
 12007  12283   
 12008  12284   #ifndef SQLITE_OMIT_FOREIGN_KEY
 12009  12285   SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
 12010  12286   #else
 12011  12287   # define sqlite3VdbeCheckFk(p,i) 0
 12012  12288   #endif
 12013  12289   
................................................................................
 12357  12633       cnt++;
 12358  12634     }while( nextC );
 12359  12635   end_getDigits:
 12360  12636     va_end(ap);
 12361  12637     return cnt;
 12362  12638   }
 12363  12639   
 12364         -/*
 12365         -** Read text from z[] and convert into a floating point number.  Return
 12366         -** the number of digits converted.
 12367         -*/
 12368         -#define getValue sqlite3AtoF
 12369         -
 12370  12640   /*
 12371  12641   ** Parse a timezone extension on the end of a date-time.
 12372  12642   ** The extension is of the form:
 12373  12643   **
 12374  12644   **        (+/-)HH:MM
 12375  12645   **
 12376  12646   ** Or the "zulu" notation:
................................................................................
 12564  12834   ** as there is a year and date.
 12565  12835   */
 12566  12836   static int parseDateOrTime(
 12567  12837     sqlite3_context *context, 
 12568  12838     const char *zDate, 
 12569  12839     DateTime *p
 12570  12840   ){
 12571         -  int isRealNum;    /* Return from sqlite3IsNumber().  Not used */
        12841  +  double r;
 12572  12842     if( parseYyyyMmDd(zDate,p)==0 ){
 12573  12843       return 0;
 12574  12844     }else if( parseHhMmSs(zDate, p)==0 ){
 12575  12845       return 0;
 12576  12846     }else if( sqlite3StrICmp(zDate,"now")==0){
 12577  12847       setDateTimeToCurrent(context, p);
 12578  12848       return 0;
 12579         -  }else if( sqlite3IsNumber(zDate, &isRealNum, SQLITE_UTF8) ){
 12580         -    double r;
 12581         -    getValue(zDate, &r);
        12849  +  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
 12582  12850       p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
 12583  12851       p->validJD = 1;
 12584  12852       return 0;
 12585  12853     }
 12586  12854     return 1;
 12587  12855   }
 12588  12856   
................................................................................
 12795  13063         /*
 12796  13064         **    weekday N
 12797  13065         **
 12798  13066         ** Move the date to the same time on the next occurrence of
 12799  13067         ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
 12800  13068         ** date is already on the appropriate weekday, this is a no-op.
 12801  13069         */
 12802         -      if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
 12803         -                 && (n=(int)r)==r && n>=0 && r<7 ){
        13070  +      if( strncmp(z, "weekday ", 8)==0
        13071  +               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
        13072  +               && (n=(int)r)==r && n>=0 && r<7 ){
 12804  13073           sqlite3_int64 Z;
 12805  13074           computeYMD_HMS(p);
 12806  13075           p->validTZ = 0;
 12807  13076           p->validJD = 0;
 12808  13077           computeJD(p);
 12809  13078           Z = ((p->iJD + 129600000)/86400000) % 7;
 12810  13079           if( Z>n ) Z -= 7;
................................................................................
 12851  13120       case '4':
 12852  13121       case '5':
 12853  13122       case '6':
 12854  13123       case '7':
 12855  13124       case '8':
 12856  13125       case '9': {
 12857  13126         double rRounder;
 12858         -      n = getValue(z, &r);
 12859         -      assert( n>=1 );
        13127  +      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
        13128  +      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
        13129  +        rc = 1;
        13130  +        break;
        13131  +      }
 12860  13132         if( z[n]==':' ){
 12861  13133           /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
 12862  13134           ** specified number of hours, minutes, seconds, and fractional seconds
 12863  13135           ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
 12864  13136           ** omitted.
 12865  13137           */
 12866  13138           const char *z2 = z;
................................................................................
 13506  13778     return pVfs->xRandomness(pVfs, nByte, zBufOut);
 13507  13779   }
 13508  13780   SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
 13509  13781     return pVfs->xSleep(pVfs, nMicro);
 13510  13782   }
 13511  13783   SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
 13512  13784     int rc;
        13785  +  /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
        13786  +  ** method to get the current date and time if that method is available
        13787  +  ** (if iVersion is 2 or greater and the function pointer is not NULL) and
        13788  +  ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
        13789  +  ** unavailable.
        13790  +  */
 13513  13791     if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
 13514  13792       rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
 13515  13793     }else{
 13516  13794       double r;
 13517  13795       rc = pVfs->xCurrentTime(pVfs, &r);
 13518  13796       *pTimeOut = (sqlite3_int64)(r*86400000.0);
 13519  13797     }
................................................................................
 13889  14167   ** redirected to xMalloc.  Similarly, we know that nByte>0 becauses
 13890  14168   ** cases where nByte<=0 will have been intercepted by higher-level
 13891  14169   ** routines and redirected to xFree.
 13892  14170   */
 13893  14171   static void *sqlite3MemRealloc(void *pPrior, int nByte){
 13894  14172     sqlite3_int64 *p = (sqlite3_int64*)pPrior;
 13895  14173     assert( pPrior!=0 && nByte>0 );
 13896         -  nByte = ROUND8(nByte);
        14174  +  assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
 13897  14175     p--;
 13898  14176     p = realloc(p, nByte+8 );
 13899  14177     if( p ){
 13900  14178       p[0] = nByte;
 13901  14179       p++;
 13902  14180     }else{
 13903  14181       testcase( sqlite3GlobalConfig.xLog!=0 );
................................................................................
 14295  14573   ** much more likely to break and we are much more liking to find
 14296  14574   ** the error.
 14297  14575   */
 14298  14576   static void *sqlite3MemRealloc(void *pPrior, int nByte){
 14299  14577     struct MemBlockHdr *pOldHdr;
 14300  14578     void *pNew;
 14301  14579     assert( mem.disallow==0 );
        14580  +  assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
 14302  14581     pOldHdr = sqlite3MemsysGetHeader(pPrior);
 14303  14582     pNew = sqlite3MemMalloc(nByte);
 14304  14583     if( pNew ){
 14305  14584       memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
 14306  14585       if( nByte>pOldHdr->iSize ){
 14307  14586         randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
 14308  14587       }
................................................................................
 14329  14608     sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
 14330  14609   }
 14331  14610   
 14332  14611   /*
 14333  14612   ** Set the "type" of an allocation.
 14334  14613   */
 14335  14614   SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
 14336         -  if( p ){
        14615  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
 14337  14616       struct MemBlockHdr *pHdr;
 14338  14617       pHdr = sqlite3MemsysGetHeader(p);
 14339  14618       assert( pHdr->iForeGuard==FOREGUARD );
 14340  14619       pHdr->eType = eType;
 14341  14620     }
 14342  14621   }
 14343  14622   
................................................................................
 14348  14627   ** This routine is designed for use within an assert() statement, to
 14349  14628   ** verify the type of an allocation.  For example:
 14350  14629   **
 14351  14630   **     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
 14352  14631   */
 14353  14632   SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
 14354  14633     int rc = 1;
 14355         -  if( p ){
        14634  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
 14356  14635       struct MemBlockHdr *pHdr;
 14357  14636       pHdr = sqlite3MemsysGetHeader(p);
 14358  14637       assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
 14359  14638       if( (pHdr->eType&eType)==0 ){
 14360  14639         rc = 0;
 14361  14640       }
 14362  14641     }
................................................................................
 14370  14649   ** This routine is designed for use within an assert() statement, to
 14371  14650   ** verify the type of an allocation.  For example:
 14372  14651   **
 14373  14652   **     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
 14374  14653   */
 14375  14654   SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
 14376  14655     int rc = 1;
 14377         -  if( p ){
        14656  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
 14378  14657       struct MemBlockHdr *pHdr;
 14379  14658       pHdr = sqlite3MemsysGetHeader(p);
 14380  14659       assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
 14381  14660       if( (pHdr->eType&eType)!=0 ){
 14382  14661         rc = 0;
 14383  14662       }
 14384  14663     }
................................................................................
 15564  15843   ** (an allocation larger than 0x40000000) was requested and this
 15565  15844   ** routine should return 0 without freeing pPrior.
 15566  15845   */
 15567  15846   static void *memsys5Realloc(void *pPrior, int nBytes){
 15568  15847     int nOld;
 15569  15848     void *p;
 15570  15849     assert( pPrior!=0 );
 15571         -  assert( (nBytes&(nBytes-1))==0 );
        15850  +  assert( (nBytes&(nBytes-1))==0 );  /* EV: R-46199-30249 */
 15572  15851     assert( nBytes>=0 );
 15573  15852     if( nBytes==0 ){
 15574  15853       return 0;
 15575  15854     }
 15576  15855     nOld = memsys5Size(pPrior);
 15577  15856     if( nBytes<=nOld ){
 15578  15857       return pPrior;
................................................................................
 16622  16901       }
 16623  16902     }
 16624  16903   #else
 16625  16904     /* Use the built-in recursive mutexes if they are available.
 16626  16905     */
 16627  16906     pthread_mutex_lock(&p->mutex);
 16628  16907   #if SQLITE_MUTEX_NREF
        16908  +  assert( p->nRef>0 || p->owner==0 );
 16629  16909     p->owner = pthread_self();
 16630  16910     p->nRef++;
 16631  16911   #endif
 16632  16912   #endif
 16633  16913   
 16634  16914   #ifdef SQLITE_DEBUG
 16635  16915     if( p->trace ){
................................................................................
 16694  16974   ** is undefined if the mutex is not currently entered or
 16695  16975   ** is not currently allocated.  SQLite will never do either.
 16696  16976   */
 16697  16977   static void pthreadMutexLeave(sqlite3_mutex *p){
 16698  16978     assert( pthreadMutexHeld(p) );
 16699  16979   #if SQLITE_MUTEX_NREF
 16700  16980     p->nRef--;
        16981  +  if( p->nRef==0 ) p->owner = 0;
 16701  16982   #endif
 16702  16983     assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
 16703  16984   
 16704  16985   #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
 16705  16986     if( p->nRef==0 ){
 16706  16987       pthread_mutex_unlock(&p->mutex);
 16707  16988     }
................................................................................
 16958  17239   /*
 16959  17240   ** This routine deallocates a previously
 16960  17241   ** allocated mutex.  SQLite is careful to deallocate every
 16961  17242   ** mutex that it allocates.
 16962  17243   */
 16963  17244   static void winMutexFree(sqlite3_mutex *p){
 16964  17245     assert( p );
 16965         -  assert( p->nRef==0 );
        17246  +  assert( p->nRef==0 && p->owner==0 );
 16966  17247     assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
 16967  17248     DeleteCriticalSection(&p->mutex);
 16968  17249     sqlite3_free(p);
 16969  17250   }
 16970  17251   
 16971  17252   /*
 16972  17253   ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
................................................................................
 16982  17263   static void winMutexEnter(sqlite3_mutex *p){
 16983  17264   #ifdef SQLITE_DEBUG
 16984  17265     DWORD tid = GetCurrentThreadId(); 
 16985  17266     assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
 16986  17267   #endif
 16987  17268     EnterCriticalSection(&p->mutex);
 16988  17269   #ifdef SQLITE_DEBUG
        17270  +  assert( p->nRef>0 || p->owner==0 );
 16989  17271     p->owner = tid; 
 16990  17272     p->nRef++;
 16991  17273     if( p->trace ){
 16992  17274       printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
 16993  17275     }
 16994  17276   #endif
 16995  17277   }
................................................................................
 17035  17317   */
 17036  17318   static void winMutexLeave(sqlite3_mutex *p){
 17037  17319   #ifndef NDEBUG
 17038  17320     DWORD tid = GetCurrentThreadId();
 17039  17321     assert( p->nRef>0 );
 17040  17322     assert( p->owner==tid );
 17041  17323     p->nRef--;
        17324  +  if( p->nRef==0 ) p->owner = 0;
 17042  17325     assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
 17043  17326   #endif
 17044  17327     LeaveCriticalSection(&p->mutex);
 17045  17328   #ifdef SQLITE_DEBUG
 17046  17329     if( p->trace ){
 17047  17330       printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
 17048  17331     }
................................................................................
 17084  17367   **    May you share freely, never taking more than you give.
 17085  17368   **
 17086  17369   *************************************************************************
 17087  17370   **
 17088  17371   ** Memory allocation functions used throughout sqlite.
 17089  17372   */
 17090  17373   
        17374  +/*
        17375  +** Attempt to release up to n bytes of non-essential memory currently
        17376  +** held by SQLite. An example of non-essential memory is memory used to
        17377  +** cache database pages that are not currently in use.
        17378  +*/
        17379  +SQLITE_API int sqlite3_release_memory(int n){
        17380  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
        17381  +  return sqlite3PcacheReleaseMemory(n);
        17382  +#else
        17383  +  /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine
        17384  +  ** is a no-op returning zero if SQLite is not compiled with
        17385  +  ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
        17386  +  UNUSED_PARAMETER(n);
        17387  +  return 0;
        17388  +#endif
        17389  +}
        17390  +
        17391  +/*
        17392  +** An instance of the following object records the location of
        17393  +** each unused scratch buffer.
        17394  +*/
        17395  +typedef struct ScratchFreeslot {
        17396  +  struct ScratchFreeslot *pNext;   /* Next unused scratch buffer */
        17397  +} ScratchFreeslot;
        17398  +
        17399  +/*
        17400  +** State information local to the memory allocation subsystem.
        17401  +*/
        17402  +static SQLITE_WSD struct Mem0Global {
        17403  +  sqlite3_mutex *mutex;         /* Mutex to serialize access */
        17404  +
        17405  +  /*
        17406  +  ** The alarm callback and its arguments.  The mem0.mutex lock will
        17407  +  ** be held while the callback is running.  Recursive calls into
        17408  +  ** the memory subsystem are allowed, but no new callbacks will be
        17409  +  ** issued.
        17410  +  */
        17411  +  sqlite3_int64 alarmThreshold;
        17412  +  void (*alarmCallback)(void*, sqlite3_int64,int);
        17413  +  void *alarmArg;
        17414  +
        17415  +  /*
        17416  +  ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
        17417  +  ** (so that a range test can be used to determine if an allocation
        17418  +  ** being freed came from pScratch) and a pointer to the list of
        17419  +  ** unused scratch allocations.
        17420  +  */
        17421  +  void *pScratchEnd;
        17422  +  ScratchFreeslot *pScratchFree;
        17423  +  u32 nScratchFree;
        17424  +
        17425  +  /*
        17426  +  ** True if heap is nearly "full" where "full" is defined by the
        17427  +  ** sqlite3_soft_heap_limit() setting.
        17428  +  */
        17429  +  int nearlyFull;
        17430  +} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
        17431  +
        17432  +#define mem0 GLOBAL(struct Mem0Global, mem0)
        17433  +
 17091  17434   /*
 17092  17435   ** This routine runs when the memory allocator sees that the
 17093  17436   ** total memory allocation is about to exceed the soft heap
 17094  17437   ** limit.
 17095  17438   */
 17096  17439   static void softHeapLimitEnforcer(
 17097  17440     void *NotUsed, 
................................................................................
 17098  17441     sqlite3_int64 NotUsed2,
 17099  17442     int allocSize
 17100  17443   ){
 17101  17444     UNUSED_PARAMETER2(NotUsed, NotUsed2);
 17102  17445     sqlite3_release_memory(allocSize);
 17103  17446   }
 17104  17447   
        17448  +/*
        17449  +** Change the alarm callback
        17450  +*/
        17451  +static int sqlite3MemoryAlarm(
        17452  +  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
        17453  +  void *pArg,
        17454  +  sqlite3_int64 iThreshold
        17455  +){
        17456  +  int nUsed;
        17457  +  sqlite3_mutex_enter(mem0.mutex);
        17458  +  mem0.alarmCallback = xCallback;
        17459  +  mem0.alarmArg = pArg;
        17460  +  mem0.alarmThreshold = iThreshold;
        17461  +  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
        17462  +  mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
        17463  +  sqlite3_mutex_leave(mem0.mutex);
        17464  +  return SQLITE_OK;
        17465  +}
        17466  +
        17467  +#ifndef SQLITE_OMIT_DEPRECATED
        17468  +/*
        17469  +** Deprecated external interface.  Internal/core SQLite code
        17470  +** should call sqlite3MemoryAlarm.
        17471  +*/
        17472  +SQLITE_API int sqlite3_memory_alarm(
        17473  +  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
        17474  +  void *pArg,
        17475  +  sqlite3_int64 iThreshold
        17476  +){
        17477  +  return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
        17478  +}
        17479  +#endif
        17480  +
 17105  17481   /*
 17106  17482   ** Set the soft heap-size limit for the library. Passing a zero or 
 17107  17483   ** negative value indicates no limit.
 17108  17484   */
 17109         -SQLITE_API void sqlite3_soft_heap_limit(int n){
 17110         -  sqlite3_uint64 iLimit;
 17111         -  int overage;
 17112         -  if( n<0 ){
 17113         -    iLimit = 0;
 17114         -  }else{
 17115         -    iLimit = n;
 17116         -  }
        17485  +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
        17486  +  sqlite3_int64 priorLimit;
        17487  +  sqlite3_int64 excess;
 17117  17488   #ifndef SQLITE_OMIT_AUTOINIT
 17118  17489     sqlite3_initialize();
 17119  17490   #endif
 17120         -  if( iLimit>0 ){
 17121         -    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit);
        17491  +  sqlite3_mutex_enter(mem0.mutex);
        17492  +  priorLimit = mem0.alarmThreshold;
        17493  +  sqlite3_mutex_leave(mem0.mutex);
        17494  +  if( n<0 ) return priorLimit;
        17495  +  if( n>0 ){
        17496  +    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
 17122  17497     }else{
 17123  17498       sqlite3MemoryAlarm(0, 0, 0);
 17124  17499     }
 17125         -  overage = (int)(sqlite3_memory_used() - (i64)n);
 17126         -  if( overage>0 ){
 17127         -    sqlite3_release_memory(overage);
 17128         -  }
 17129         -}
 17130         -
 17131         -/*
 17132         -** Attempt to release up to n bytes of non-essential memory currently
 17133         -** held by SQLite. An example of non-essential memory is memory used to
 17134         -** cache database pages that are not currently in use.
 17135         -*/
 17136         -SQLITE_API int sqlite3_release_memory(int n){
 17137         -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 17138         -  int nRet = 0;
 17139         -  nRet += sqlite3PcacheReleaseMemory(n-nRet);
 17140         -  return nRet;
 17141         -#else
 17142         -  UNUSED_PARAMETER(n);
 17143         -  return SQLITE_OK;
 17144         -#endif
 17145         -}
 17146         -
 17147         -/*
 17148         -** State information local to the memory allocation subsystem.
 17149         -*/
 17150         -static SQLITE_WSD struct Mem0Global {
 17151         -  /* Number of free pages for scratch and page-cache memory */
 17152         -  u32 nScratchFree;
 17153         -  u32 nPageFree;
 17154         -
 17155         -  sqlite3_mutex *mutex;         /* Mutex to serialize access */
 17156         -
 17157         -  /*
 17158         -  ** The alarm callback and its arguments.  The mem0.mutex lock will
 17159         -  ** be held while the callback is running.  Recursive calls into
 17160         -  ** the memory subsystem are allowed, but no new callbacks will be
 17161         -  ** issued.
 17162         -  */
 17163         -  sqlite3_int64 alarmThreshold;
 17164         -  void (*alarmCallback)(void*, sqlite3_int64,int);
 17165         -  void *alarmArg;
 17166         -
 17167         -  /*
 17168         -  ** Pointers to the end of sqlite3GlobalConfig.pScratch and
 17169         -  ** sqlite3GlobalConfig.pPage to a block of memory that records
 17170         -  ** which pages are available.
 17171         -  */
 17172         -  u32 *aScratchFree;
 17173         -  u32 *aPageFree;
 17174         -} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
 17175         -
 17176         -#define mem0 GLOBAL(struct Mem0Global, mem0)
        17500  +  excess = sqlite3_memory_used() - n;
        17501  +  if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
        17502  +  return priorLimit;
        17503  +}
        17504  +SQLITE_API void sqlite3_soft_heap_limit(int n){
        17505  +  if( n<0 ) n = 0;
        17506  +  sqlite3_soft_heap_limit64(n);
        17507  +}
 17177  17508   
 17178  17509   /*
 17179  17510   ** Initialize the memory allocation subsystem.
 17180  17511   */
 17181  17512   SQLITE_PRIVATE int sqlite3MallocInit(void){
 17182  17513     if( sqlite3GlobalConfig.m.xMalloc==0 ){
 17183  17514       sqlite3MemSetDefault();
 17184  17515     }
 17185  17516     memset(&mem0, 0, sizeof(mem0));
 17186  17517     if( sqlite3GlobalConfig.bCoreMutex ){
 17187  17518       mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
 17188  17519     }
 17189  17520     if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
 17190         -      && sqlite3GlobalConfig.nScratch>=0 ){
 17191         -    int i;
 17192         -    sqlite3GlobalConfig.szScratch = ROUNDDOWN8(sqlite3GlobalConfig.szScratch-4);
 17193         -    mem0.aScratchFree = (u32*)&((char*)sqlite3GlobalConfig.pScratch)
 17194         -                  [sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch];
 17195         -    for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; }
 17196         -    mem0.nScratchFree = sqlite3GlobalConfig.nScratch;
        17521  +      && sqlite3GlobalConfig.nScratch>0 ){
        17522  +    int i, n, sz;
        17523  +    ScratchFreeslot *pSlot;
        17524  +    sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
        17525  +    sqlite3GlobalConfig.szScratch = sz;
        17526  +    pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
        17527  +    n = sqlite3GlobalConfig.nScratch;
        17528  +    mem0.pScratchFree = pSlot;
        17529  +    mem0.nScratchFree = n;
        17530  +    for(i=0; i<n-1; i++){
        17531  +      pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
        17532  +      pSlot = pSlot->pNext;
        17533  +    }
        17534  +    pSlot->pNext = 0;
        17535  +    mem0.pScratchEnd = (void*)&pSlot[1];
 17197  17536     }else{
        17537  +    mem0.pScratchEnd = 0;
 17198  17538       sqlite3GlobalConfig.pScratch = 0;
 17199  17539       sqlite3GlobalConfig.szScratch = 0;
        17540  +    sqlite3GlobalConfig.nScratch = 0;
 17200  17541     }
 17201         -  if( sqlite3GlobalConfig.pPage && sqlite3GlobalConfig.szPage>=512
 17202         -      && sqlite3GlobalConfig.nPage>=1 ){
 17203         -    int i;
 17204         -    int overhead;
 17205         -    int sz = ROUNDDOWN8(sqlite3GlobalConfig.szPage);
 17206         -    int n = sqlite3GlobalConfig.nPage;
 17207         -    overhead = (4*n + sz - 1)/sz;
 17208         -    sqlite3GlobalConfig.nPage -= overhead;
 17209         -    mem0.aPageFree = (u32*)&((char*)sqlite3GlobalConfig.pPage)
 17210         -                  [sqlite3GlobalConfig.szPage*sqlite3GlobalConfig.nPage];
 17211         -    for(i=0; i<sqlite3GlobalConfig.nPage; i++){ mem0.aPageFree[i] = i; }
 17212         -    mem0.nPageFree = sqlite3GlobalConfig.nPage;
 17213         -  }else{
        17542  +  if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
        17543  +      || sqlite3GlobalConfig.nPage<1 ){
 17214  17544       sqlite3GlobalConfig.pPage = 0;
 17215  17545       sqlite3GlobalConfig.szPage = 0;
        17546  +    sqlite3GlobalConfig.nPage = 0;
 17216  17547     }
 17217  17548     return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
 17218  17549   }
        17550  +
        17551  +/*
        17552  +** Return true if the heap is currently under memory pressure - in other
        17553  +** words if the amount of heap used is close to the limit set by
        17554  +** sqlite3_soft_heap_limit().
        17555  +*/
        17556  +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
        17557  +  return mem0.nearlyFull;
        17558  +}
 17219  17559   
 17220  17560   /*
 17221  17561   ** Deinitialize the memory allocation subsystem.
 17222  17562   */
 17223  17563   SQLITE_PRIVATE void sqlite3MallocEnd(void){
 17224  17564     if( sqlite3GlobalConfig.m.xShutdown ){
 17225  17565       sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
................................................................................
 17247  17587     int n, mx;
 17248  17588     sqlite3_int64 res;
 17249  17589     sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
 17250  17590     res = (sqlite3_int64)mx;  /* Work around bug in Borland C. Ticket #3216 */
 17251  17591     return res;
 17252  17592   }
 17253  17593   
 17254         -/*
 17255         -** Change the alarm callback
 17256         -*/
 17257         -SQLITE_PRIVATE int sqlite3MemoryAlarm(
 17258         -  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
 17259         -  void *pArg,
 17260         -  sqlite3_int64 iThreshold
 17261         -){
 17262         -  sqlite3_mutex_enter(mem0.mutex);
 17263         -  mem0.alarmCallback = xCallback;
 17264         -  mem0.alarmArg = pArg;
 17265         -  mem0.alarmThreshold = iThreshold;
 17266         -  sqlite3_mutex_leave(mem0.mutex);
 17267         -  return SQLITE_OK;
 17268         -}
 17269         -
 17270         -#ifndef SQLITE_OMIT_DEPRECATED
 17271         -/*
 17272         -** Deprecated external interface.  Internal/core SQLite code
 17273         -** should call sqlite3MemoryAlarm.
 17274         -*/
 17275         -SQLITE_API int sqlite3_memory_alarm(
 17276         -  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
 17277         -  void *pArg,
 17278         -  sqlite3_int64 iThreshold
 17279         -){
 17280         -  return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
 17281         -}
 17282         -#endif
 17283         -
 17284  17594   /*
 17285  17595   ** Trigger the alarm 
 17286  17596   */
 17287  17597   static void sqlite3MallocAlarm(int nByte){
 17288  17598     void (*xCallback)(void*,sqlite3_int64,int);
 17289  17599     sqlite3_int64 nowUsed;
 17290  17600     void *pArg;
................................................................................
 17309  17619     void *p;
 17310  17620     assert( sqlite3_mutex_held(mem0.mutex) );
 17311  17621     nFull = sqlite3GlobalConfig.m.xRoundup(n);
 17312  17622     sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
 17313  17623     if( mem0.alarmCallback!=0 ){
 17314  17624       int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
 17315  17625       if( nUsed+nFull >= mem0.alarmThreshold ){
        17626  +      mem0.nearlyFull = 1;
 17316  17627         sqlite3MallocAlarm(nFull);
        17628  +    }else{
        17629  +      mem0.nearlyFull = 0;
 17317  17630       }
 17318  17631     }
 17319  17632     p = sqlite3GlobalConfig.m.xMalloc(nFull);
        17633  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 17320  17634     if( p==0 && mem0.alarmCallback ){
 17321  17635       sqlite3MallocAlarm(nFull);
 17322  17636       p = sqlite3GlobalConfig.m.xMalloc(nFull);
 17323  17637     }
        17638  +#endif
 17324  17639     if( p ){
 17325  17640       nFull = sqlite3MallocSize(p);
 17326  17641       sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
 17327  17642       sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
 17328  17643     }
 17329  17644     *pp = p;
 17330  17645     return nFull;
................................................................................
 17332  17647   
 17333  17648   /*
 17334  17649   ** Allocate memory.  This routine is like sqlite3_malloc() except that it
 17335  17650   ** assumes the memory subsystem has already been initialized.
 17336  17651   */
 17337  17652   SQLITE_PRIVATE void *sqlite3Malloc(int n){
 17338  17653     void *p;
 17339         -  if( n<=0 || n>=0x7fffff00 ){
        17654  +  if( n<=0               /* IMP: R-65312-04917 */ 
        17655  +   || n>=0x7fffff00
        17656  +  ){
 17340  17657       /* A memory allocation of a number of bytes which is near the maximum
 17341  17658       ** signed integer value might cause an integer overflow inside of the
 17342  17659       ** xMalloc().  Hence we limit the maximum size to 0x7fffff00, giving
 17343  17660       ** 255 bytes of overhead.  SQLite itself will never use anything near
 17344  17661       ** this amount.  The only way to reach the limit is with sqlite3_malloc() */
 17345  17662       p = 0;
 17346  17663     }else if( sqlite3GlobalConfig.bMemstat ){
 17347  17664       sqlite3_mutex_enter(mem0.mutex);
 17348  17665       mallocWithAlarm(n, &p);
 17349  17666       sqlite3_mutex_leave(mem0.mutex);
 17350  17667     }else{
 17351  17668       p = sqlite3GlobalConfig.m.xMalloc(n);
 17352  17669     }
        17670  +  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
 17353  17671     return p;
 17354  17672   }
 17355  17673   
 17356  17674   /*
 17357  17675   ** This version of the memory allocation is for use by the application.
 17358  17676   ** First make sure the memory subsystem is initialized, then do the
 17359  17677   ** allocation.
................................................................................
 17383  17701   ** routine is intended to get memory to old large transient data
 17384  17702   ** structures that would not normally fit on the stack of an
 17385  17703   ** embedded processor.
 17386  17704   */
 17387  17705   SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
 17388  17706     void *p;
 17389  17707     assert( n>0 );
        17708  +
        17709  +  sqlite3_mutex_enter(mem0.mutex);
        17710  +  if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
        17711  +    p = mem0.pScratchFree;
        17712  +    mem0.pScratchFree = mem0.pScratchFree->pNext;
        17713  +    mem0.nScratchFree--;
        17714  +    sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
        17715  +    sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
        17716  +    sqlite3_mutex_leave(mem0.mutex);
        17717  +  }else{
        17718  +    if( sqlite3GlobalConfig.bMemstat ){
        17719  +      sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
        17720  +      n = mallocWithAlarm(n, &p);
        17721  +      if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
        17722  +      sqlite3_mutex_leave(mem0.mutex);
        17723  +    }else{
        17724  +      sqlite3_mutex_leave(mem0.mutex);
        17725  +      p = sqlite3GlobalConfig.m.xMalloc(n);
        17726  +    }
        17727  +    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
        17728  +  }
        17729  +  assert( sqlite3_mutex_notheld(mem0.mutex) );
        17730  +
 17390  17731   
 17391  17732   #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
 17392         -  /* Verify that no more than two scratch allocation per thread
 17393         -  ** is outstanding at one time.  (This is only checked in the
        17733  +  /* Verify that no more than two scratch allocations per thread
        17734  +  ** are outstanding at one time.  (This is only checked in the
 17394  17735     ** single-threaded case since checking in the multi-threaded case
 17395  17736     ** would be much more complicated.) */
 17396  17737     assert( scratchAllocOut<=1 );
 17397         -#endif
 17398         -
 17399         -  if( sqlite3GlobalConfig.szScratch<n ){
 17400         -    goto scratch_overflow;
 17401         -  }else{  
 17402         -    sqlite3_mutex_enter(mem0.mutex);
 17403         -    if( mem0.nScratchFree==0 ){
 17404         -      sqlite3_mutex_leave(mem0.mutex);
 17405         -      goto scratch_overflow;
 17406         -    }else{
 17407         -      int i;
 17408         -      i = mem0.aScratchFree[--mem0.nScratchFree];
 17409         -      i *= sqlite3GlobalConfig.szScratch;
 17410         -      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
 17411         -      sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
 17412         -      sqlite3_mutex_leave(mem0.mutex);
 17413         -      p = (void*)&((char*)sqlite3GlobalConfig.pScratch)[i];
 17414         -      assert(  (((u8*)p - (u8*)0) & 7)==0 );
 17415         -    }
 17416         -  }
 17417         -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
 17418         -  scratchAllocOut = p!=0;
        17738  +  if( p ) scratchAllocOut++;
 17419  17739   #endif
 17420  17740   
 17421  17741     return p;
 17422         -
 17423         -scratch_overflow:
 17424         -  if( sqlite3GlobalConfig.bMemstat ){
 17425         -    sqlite3_mutex_enter(mem0.mutex);
 17426         -    sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
 17427         -    n = mallocWithAlarm(n, &p);
 17428         -    if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
 17429         -    sqlite3_mutex_leave(mem0.mutex);
 17430         -  }else{
 17431         -    p = sqlite3GlobalConfig.m.xMalloc(n);
 17432         -  }
 17433         -  sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
 17434         -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
 17435         -  scratchAllocOut = p!=0;
 17436         -#endif
 17437         -  return p;    
 17438  17742   }
 17439  17743   SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
 17440  17744     if( p ){
 17441         -    if( sqlite3GlobalConfig.pScratch==0
 17442         -           || p<sqlite3GlobalConfig.pScratch
 17443         -           || p>=(void*)mem0.aScratchFree ){
        17745  +
        17746  +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
        17747  +    /* Verify that no more than two scratch allocation per thread
        17748  +    ** is outstanding at one time.  (This is only checked in the
        17749  +    ** single-threaded case since checking in the multi-threaded case
        17750  +    ** would be much more complicated.) */
        17751  +    assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
        17752  +    scratchAllocOut--;
        17753  +#endif
        17754  +
        17755  +    if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
        17756  +      /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
        17757  +      ScratchFreeslot *pSlot;
        17758  +      pSlot = (ScratchFreeslot*)p;
        17759  +      sqlite3_mutex_enter(mem0.mutex);
        17760  +      pSlot->pNext = mem0.pScratchFree;
        17761  +      mem0.pScratchFree = pSlot;
        17762  +      mem0.nScratchFree++;
        17763  +      assert( mem0.nScratchFree<=sqlite3GlobalConfig.nScratch );
        17764  +      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
        17765  +      sqlite3_mutex_leave(mem0.mutex);
        17766  +    }else{
        17767  +      /* Release memory back to the heap */
 17444  17768         assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
 17445  17769         assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
 17446  17770         sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
 17447  17771         if( sqlite3GlobalConfig.bMemstat ){
 17448  17772           int iSize = sqlite3MallocSize(p);
 17449  17773           sqlite3_mutex_enter(mem0.mutex);
 17450  17774           sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
................................................................................
 17451  17775           sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
 17452  17776           sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
 17453  17777           sqlite3GlobalConfig.m.xFree(p);
 17454  17778           sqlite3_mutex_leave(mem0.mutex);
 17455  17779         }else{
 17456  17780           sqlite3GlobalConfig.m.xFree(p);
 17457  17781         }
 17458         -    }else{
 17459         -      int i;
 17460         -      i = (int)((u8*)p - (u8*)sqlite3GlobalConfig.pScratch);
 17461         -      i /= sqlite3GlobalConfig.szScratch;
 17462         -      assert( i>=0 && i<sqlite3GlobalConfig.nScratch );
 17463         -      sqlite3_mutex_enter(mem0.mutex);
 17464         -      assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch );
 17465         -      mem0.aScratchFree[mem0.nScratchFree++] = i;
 17466         -      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
 17467         -      sqlite3_mutex_leave(mem0.mutex);
 17468         -
 17469         -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
 17470         -    /* Verify that no more than two scratch allocation per thread
 17471         -    ** is outstanding at one time.  (This is only checked in the
 17472         -    ** single-threaded case since checking in the multi-threaded case
 17473         -    ** would be much more complicated.) */
 17474         -    assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
 17475         -    scratchAllocOut = 0;
 17476         -#endif
 17477         -
 17478  17782       }
 17479  17783     }
 17480  17784   }
 17481  17785   
 17482  17786   /*
 17483  17787   ** TRUE if p is a lookaside memory allocation from db
 17484  17788   */
................................................................................
 17511  17815     }
 17512  17816   }
 17513  17817   
 17514  17818   /*
 17515  17819   ** Free memory previously obtained from sqlite3Malloc().
 17516  17820   */
 17517  17821   SQLITE_API void sqlite3_free(void *p){
 17518         -  if( p==0 ) return;
        17822  +  if( p==0 ) return;  /* IMP: R-49053-54554 */
 17519  17823     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
 17520  17824     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 17521  17825     if( sqlite3GlobalConfig.bMemstat ){
 17522  17826       sqlite3_mutex_enter(mem0.mutex);
 17523  17827       sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
 17524  17828       sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
 17525  17829       sqlite3GlobalConfig.m.xFree(p);
................................................................................
 17558  17862   /*
 17559  17863   ** Change the size of an existing memory allocation
 17560  17864   */
 17561  17865   SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
 17562  17866     int nOld, nNew;
 17563  17867     void *pNew;
 17564  17868     if( pOld==0 ){
 17565         -    return sqlite3Malloc(nBytes);
        17869  +    return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
 17566  17870     }
 17567  17871     if( nBytes<=0 ){
 17568         -    sqlite3_free(pOld);
        17872  +    sqlite3_free(pOld); /* IMP: R-31593-10574 */
 17569  17873       return 0;
 17570  17874     }
 17571  17875     if( nBytes>=0x7fffff00 ){
 17572  17876       /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
 17573  17877       return 0;
 17574  17878     }
 17575  17879     nOld = sqlite3MallocSize(pOld);
        17880  +  /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second
        17881  +  ** argument to xRealloc is always a value returned by a prior call to
        17882  +  ** xRoundup. */
 17576  17883     nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
 17577  17884     if( nOld==nNew ){
 17578  17885       pNew = pOld;
 17579  17886     }else if( sqlite3GlobalConfig.bMemstat ){
 17580  17887       sqlite3_mutex_enter(mem0.mutex);
 17581  17888       sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
 17582  17889       if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
................................................................................
 17594  17901         nNew = sqlite3MallocSize(pNew);
 17595  17902         sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
 17596  17903       }
 17597  17904       sqlite3_mutex_leave(mem0.mutex);
 17598  17905     }else{
 17599  17906       pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
 17600  17907     }
        17908  +  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
 17601  17909     return pNew;
 17602  17910   }
 17603  17911   
 17604  17912   /*
 17605  17913   ** The public interface to sqlite3Realloc.  Make sure that the memory
 17606  17914   ** subsystem is initialized prior to invoking sqliteRealloc.
 17607  17915   */
................................................................................
 19757  20065   
 19758  20066   /* Convenient short-hand */
 19759  20067   #define UpperToLower sqlite3UpperToLower
 19760  20068   
 19761  20069   /*
 19762  20070   ** Some systems have stricmp().  Others have strcasecmp().  Because
 19763  20071   ** there is no consistency, we will define our own.
        20072  +**
        20073  +** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows
        20074  +** applications and extensions to compare the contents of two buffers
        20075  +** containing UTF-8 strings in a case-independent fashion, using the same
        20076  +** definition of case independence that SQLite uses internally when
        20077  +** comparing identifiers.
 19764  20078   */
 19765  20079   SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
 19766  20080     register unsigned char *a, *b;
 19767  20081     a = (unsigned char *)zLeft;
 19768  20082     b = (unsigned char *)zRight;
 19769  20083     while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
 19770  20084     return UpperToLower[*a] - UpperToLower[*b];
................................................................................
 19774  20088     a = (unsigned char *)zLeft;
 19775  20089     b = (unsigned char *)zRight;
 19776  20090     while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
 19777  20091     return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
 19778  20092   }
 19779  20093   
 19780  20094   /*
 19781         -** Return TRUE if z is a pure numeric string.  Return FALSE and leave
 19782         -** *realnum unchanged if the string contains any character which is not
 19783         -** part of a number.
        20095  +** The string z[] is an text representation of a real number.
        20096  +** Convert this string to a double and write it into *pResult.
 19784  20097   **
 19785         -** If the string is pure numeric, set *realnum to TRUE if the string
 19786         -** contains the '.' character or an "E+000" style exponentiation suffix.
 19787         -** Otherwise set *realnum to FALSE.  Note that just becaue *realnum is
 19788         -** false does not mean that the number can be successfully converted into
 19789         -** an integer - it might be too big.
        20098  +** The string z[] is length bytes in length (bytes, not characters) and
        20099  +** uses the encoding enc.  The string is not necessarily zero-terminated.
 19790  20100   **
 19791         -** An empty string is considered non-numeric.
        20101  +** Return TRUE if the result is a valid real number (or integer) and FALSE
        20102  +** if the string is empty or contains extraneous text.  Valid numbers
        20103  +** are in one of these formats:
        20104  +**
        20105  +**    [+-]digits[E[+-]digits]
        20106  +**    [+-]digits.[digits][E[+-]digits]
        20107  +**    [+-].digits[E[+-]digits]
        20108  +**
        20109  +** Leading and trailing whitespace is ignored for the purpose of determining
        20110  +** validity.
        20111  +**
        20112  +** If some prefix of the input string is a valid number, this routine
        20113  +** returns FALSE but it still converts the prefix and writes the result
        20114  +** into *pResult.
 19792  20115   */
 19793         -SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
        20116  +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
        20117  +#ifndef SQLITE_OMIT_FLOATING_POINT
 19794  20118     int incr = (enc==SQLITE_UTF8?1:2);
 19795         -  if( enc==SQLITE_UTF16BE ) z++;
 19796         -  if( *z=='-' || *z=='+' ) z += incr;
 19797         -  if( !sqlite3Isdigit(*z) ){
 19798         -    return 0;
 19799         -  }
 19800         -  z += incr;
 19801         -  *realnum = 0;
 19802         -  while( sqlite3Isdigit(*z) ){ z += incr; }
 19803         -#ifndef SQLITE_OMIT_FLOATING_POINT
 19804         -  if( *z=='.' ){
 19805         -    z += incr;
 19806         -    if( !sqlite3Isdigit(*z) ) return 0;
 19807         -    while( sqlite3Isdigit(*z) ){ z += incr; }
 19808         -    *realnum = 1;
 19809         -  }
 19810         -  if( *z=='e' || *z=='E' ){
 19811         -    z += incr;
 19812         -    if( *z=='+' || *z=='-' ) z += incr;
 19813         -    if( !sqlite3Isdigit(*z) ) return 0;
 19814         -    while( sqlite3Isdigit(*z) ){ z += incr; }
 19815         -    *realnum = 1;
 19816         -  }
 19817         -#endif
 19818         -  return *z==0;
 19819         -}
 19820         -
 19821         -/*
 19822         -** The string z[] is an ASCII representation of a real number.
 19823         -** Convert this string to a double.
 19824         -**
 19825         -** This routine assumes that z[] really is a valid number.  If it
 19826         -** is not, the result is undefined.
 19827         -**
 19828         -** This routine is used instead of the library atof() function because
 19829         -** the library atof() might want to use "," as the decimal point instead
 19830         -** of "." depending on how locale is set.  But that would cause problems
 19831         -** for SQL.  So this routine always uses "." regardless of locale.
 19832         -*/
 19833         -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){
 19834         -#ifndef SQLITE_OMIT_FLOATING_POINT
 19835         -  const char *zBegin = z;
        20119  +  const char *zEnd = z + length;
 19836  20120     /* sign * significand * (10 ^ (esign * exponent)) */
 19837         -  int sign = 1;   /* sign of significand */
 19838         -  i64 s = 0;      /* significand */
 19839         -  int d = 0;      /* adjust exponent for shifting decimal point */
 19840         -  int esign = 1;  /* sign of exponent */
 19841         -  int e = 0;      /* exponent */
        20121  +  int sign = 1;    /* sign of significand */
        20122  +  i64 s = 0;       /* significand */
        20123  +  int d = 0;       /* adjust exponent for shifting decimal point */
        20124  +  int esign = 1;   /* sign of exponent */
        20125  +  int e = 0;       /* exponent */
        20126  +  int eValid = 1;  /* True exponent is either not used or is well-formed */
 19842  20127     double result;
 19843  20128     int nDigits = 0;
 19844  20129   
        20130  +  *pResult = 0.0;   /* Default return value, in case of an error */
        20131  +
        20132  +  if( enc==SQLITE_UTF16BE ) z++;
        20133  +
 19845  20134     /* skip leading spaces */
 19846         -  while( sqlite3Isspace(*z) ) z++;
        20135  +  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
        20136  +  if( z>=zEnd ) return 0;
        20137  +
 19847  20138     /* get sign of significand */
 19848  20139     if( *z=='-' ){
 19849  20140       sign = -1;
 19850         -    z++;
        20141  +    z+=incr;
 19851  20142     }else if( *z=='+' ){
 19852         -    z++;
        20143  +    z+=incr;
 19853  20144     }
        20145  +
 19854  20146     /* skip leading zeroes */
 19855         -  while( z[0]=='0' ) z++, nDigits++;
        20147  +  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
 19856  20148   
 19857  20149     /* copy max significant digits to significand */
 19858         -  while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
        20150  +  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
 19859  20151       s = s*10 + (*z - '0');
 19860         -    z++, nDigits++;
        20152  +    z+=incr, nDigits++;
 19861  20153     }
        20154  +
 19862  20155     /* skip non-significant significand digits
 19863  20156     ** (increase exponent by d to shift decimal left) */
 19864         -  while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;
        20157  +  while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
        20158  +  if( z>=zEnd ) goto do_atof_calc;
 19865  20159   
 19866  20160     /* if decimal point is present */
 19867  20161     if( *z=='.' ){
 19868         -    z++;
        20162  +    z+=incr;
 19869  20163       /* copy digits from after decimal to significand
 19870  20164       ** (decrease exponent by d to shift decimal right) */
 19871         -    while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
        20165  +    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
 19872  20166         s = s*10 + (*z - '0');
 19873         -      z++, nDigits++, d--;
        20167  +      z+=incr, nDigits++, d--;
 19874  20168       }
 19875  20169       /* skip non-significant digits */
 19876         -    while( sqlite3Isdigit(*z) ) z++, nDigits++;
        20170  +    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
 19877  20171     }
        20172  +  if( z>=zEnd ) goto do_atof_calc;
 19878  20173   
 19879  20174     /* if exponent is present */
 19880  20175     if( *z=='e' || *z=='E' ){
 19881         -    z++;
        20176  +    z+=incr;
        20177  +    eValid = 0;
        20178  +    if( z>=zEnd ) goto do_atof_calc;
 19882  20179       /* get sign of exponent */
 19883  20180       if( *z=='-' ){
 19884  20181         esign = -1;
 19885         -      z++;
        20182  +      z+=incr;
 19886  20183       }else if( *z=='+' ){
 19887         -      z++;
        20184  +      z+=incr;
 19888  20185       }
 19889  20186       /* copy digits to exponent */
 19890         -    while( sqlite3Isdigit(*z) ){
        20187  +    while( z<zEnd && sqlite3Isdigit(*z) ){
 19891  20188         e = e*10 + (*z - '0');
 19892         -      z++;
        20189  +      z+=incr;
        20190  +      eValid = 1;
 19893  20191       }
 19894  20192     }
 19895  20193   
        20194  +  /* skip trailing spaces */
        20195  +  if( nDigits && eValid ){
        20196  +    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
        20197  +  }
        20198  +
        20199  +do_atof_calc:
 19896  20200     /* adjust exponent by d, and update sign */
 19897  20201     e = (e*esign) + d;
 19898  20202     if( e<0 ) {
 19899  20203       esign = -1;
 19900  20204       e *= -1;
 19901  20205     } else {
 19902  20206       esign = 1;
................................................................................
 19947  20251         result = (double)s;
 19948  20252       }
 19949  20253     }
 19950  20254   
 19951  20255     /* store the result */
 19952  20256     *pResult = result;
 19953  20257   
 19954         -  /* return number of characters used */
 19955         -  return (int)(z - zBegin);
        20258  +  /* return true if number and no extra non-whitespace chracters after */
        20259  +  return z>=zEnd && nDigits>0 && eValid;
 19956  20260   #else
 19957         -  return sqlite3Atoi64(z, pResult);
        20261  +  return !sqlite3Atoi64(z, pResult, length, enc);
 19958  20262   #endif /* SQLITE_OMIT_FLOATING_POINT */
 19959  20263   }
 19960  20264   
 19961  20265   /*
 19962  20266   ** Compare the 19-character string zNum against the text representation
 19963  20267   ** value 2^63:  9223372036854775808.  Return negative, zero, or positive
 19964  20268   ** if zNum is less than, equal to, or greater than the string.
        20269  +** Note that zNum must contain exactly 19 characters.
 19965  20270   **
 19966  20271   ** Unlike memcmp() this routine is guaranteed to return the difference
 19967  20272   ** in the values of the last digit if the only difference is in the
 19968  20273   ** last digit.  So, for example,
 19969  20274   **
 19970         -**      compare2pow63("9223372036854775800")
        20275  +**      compare2pow63("9223372036854775800", 1)
 19971  20276   **
 19972  20277   ** will return -8.
 19973  20278   */
 19974         -static int compare2pow63(const char *zNum){
 19975         -  int c;
 19976         -  c = memcmp(zNum,"922337203685477580",18)*10;
        20279  +static int compare2pow63(const char *zNum, int incr){
        20280  +  int c = 0;
        20281  +  int i;
        20282  +                    /* 012345678901234567 */
        20283  +  const char *pow63 = "922337203685477580";
        20284  +  for(i=0; c==0 && i<18; i++){
        20285  +    c = (zNum[i*incr]-pow63[i])*10;
        20286  +  }
 19977  20287     if( c==0 ){
 19978         -    c = zNum[18] - '8';
        20288  +    c = zNum[18*incr] - '8';
 19979  20289       testcase( c==(-1) );
 19980  20290       testcase( c==0 );
 19981  20291       testcase( c==(+1) );
 19982  20292     }
 19983  20293     return c;
 19984  20294   }
 19985  20295   
 19986  20296   
 19987  20297   /*
 19988         -** Return TRUE if zNum is a 64-bit signed integer and write
 19989         -** the value of the integer into *pNum.  If zNum is not an integer
 19990         -** or is an integer that is too large to be expressed with 64 bits,
 19991         -** then return false.
        20298  +** Convert zNum to a 64-bit signed integer and write
        20299  +** the value of the integer into *pNum.
        20300  +** If zNum is exactly 9223372036854665808, return 2.
        20301  +** This is a special case as the context will determine
        20302  +** if it is too big (used as a negative).
        20303  +** If zNum is not an integer or is an integer that 
        20304  +** is too large to be expressed with 64 bits,
        20305  +** then return 1.  Otherwise return 0.
 19992  20306   **
 19993         -** When this routine was originally written it dealt with only
 19994         -** 32-bit numbers.  At that time, it was much faster than the
 19995         -** atoi() library routine in RedHat 7.2.
        20307  +** length is the number of bytes in the string (bytes, not characters).
        20308  +** The string is not necessarily zero-terminated.  The encoding is
        20309  +** given by enc.
 19996  20310   */
 19997         -SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum){
        20311  +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
        20312  +  int incr = (enc==SQLITE_UTF8?1:2);
 19998  20313     i64 v = 0;
 19999         -  int neg;
 20000         -  int i, c;
        20314  +  int neg = 0; /* assume positive */
        20315  +  int i;
        20316  +  int c = 0;
 20001  20317     const char *zStart;
 20002         -  while( sqlite3Isspace(*zNum) ) zNum++;
        20318  +  const char *zEnd = zNum + length;
        20319  +  if( enc==SQLITE_UTF16BE ) zNum++;
        20320  +  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
        20321  +  if( zNum>=zEnd ) goto do_atoi_calc;
 20003  20322     if( *zNum=='-' ){
 20004  20323       neg = 1;
 20005         -    zNum++;
        20324  +    zNum+=incr;
 20006  20325     }else if( *zNum=='+' ){
 20007         -    neg = 0;
 20008         -    zNum++;
 20009         -  }else{
 20010         -    neg = 0;
        20326  +    zNum+=incr;
 20011  20327     }
        20328  +do_atoi_calc:
 20012  20329     zStart = zNum;
 20013         -  while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */
 20014         -  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
        20330  +  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
        20331  +  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
 20015  20332       v = v*10 + c - '0';
 20016  20333     }
 20017  20334     *pNum = neg ? -v : v;
 20018  20335     testcase( i==18 );
 20019  20336     testcase( i==19 );
 20020  20337     testcase( i==20 );
 20021         -  if( c!=0 || (i==0 && zStart==zNum) || i>19 ){
        20338  +  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
 20022  20339       /* zNum is empty or contains non-numeric text or is longer
 20023         -    ** than 19 digits (thus guaranting that it is too large) */
 20024         -    return 0;
 20025         -  }else if( i<19 ){
        20340  +    ** than 19 digits (thus guaranteeing that it is too large) */
        20341  +    return 1;
        20342  +  }else if( i<19*incr ){
 20026  20343       /* Less than 19 digits, so we know that it fits in 64 bits */
 20027         -    return 1;
        20344  +    return 0;
 20028  20345     }else{
 20029  20346       /* 19-digit numbers must be no larger than 9223372036854775807 if positive
 20030  20347       ** or 9223372036854775808 if negative.  Note that 9223372036854665808
 20031         -    ** is 2^63. */
 20032         -    return compare2pow63(zNum)<neg;
 20033         -  }
 20034         -}
 20035         -
 20036         -/*
 20037         -** The string zNum represents an unsigned integer.  The zNum string
 20038         -** consists of one or more digit characters and is terminated by
 20039         -** a zero character.  Any stray characters in zNum result in undefined
 20040         -** behavior.
 20041         -**
 20042         -** If the unsigned integer that zNum represents will fit in a
 20043         -** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
 20044         -**
 20045         -** If the negFlag parameter is true, that means that zNum really represents
 20046         -** a negative number.  (The leading "-" is omitted from zNum.)  This
 20047         -** parameter is needed to determine a boundary case.  A string
 20048         -** of "9223373036854775808" returns false if negFlag is false or true
 20049         -** if negFlag is true.
 20050         -**
 20051         -** Leading zeros are ignored.
 20052         -*/
 20053         -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
 20054         -  int i;
 20055         -  int neg = 0;
 20056         -
 20057         -  assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */
 20058         -
 20059         -  if( negFlag ) neg = 1-neg;
 20060         -  while( *zNum=='0' ){
 20061         -    zNum++;   /* Skip leading zeros.  Ticket #2454 */
 20062         -  }
 20063         -  for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
 20064         -  testcase( i==18 );
 20065         -  testcase( i==19 );
 20066         -  testcase( i==20 );
 20067         -  if( i<19 ){
 20068         -    /* Guaranteed to fit if less than 19 digits */
 20069         -    return 1;
 20070         -  }else if( i>19 ){
 20071         -    /* Guaranteed to be too big if greater than 19 digits */
 20072         -    return 0;
 20073         -  }else{
 20074         -    /* Compare against 2^63. */
 20075         -    return compare2pow63(zNum)<neg;
        20348  +    ** is 2^63. Return 1 if to large */
        20349  +    c=compare2pow63(zNum, incr);
        20350  +    if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
        20351  +    return c<neg ? 0 : 1;
 20076  20352     }
 20077  20353   }
 20078  20354   
 20079  20355   /*
 20080  20356   ** If zNum represents an integer that will fit in 32-bits, then set
 20081  20357   ** *pValue to that integer and return true.  Otherwise return false.
 20082  20358   **
................................................................................
 22607  22883     unsigned char eFileLock;            /* The type of lock held on this fd */
 22608  22884     int lastErrno;                      /* The unix errno from last I/O error */
 22609  22885     void *lockingContext;               /* Locking style specific state */
 22610  22886     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
 22611  22887     int fileFlags;                      /* Miscellanous flags */
 22612  22888     const char *zPath;                  /* Name of the file */
 22613  22889     unixShm *pShm;                      /* Shared memory segment information */
        22890  +  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
 22614  22891   #if SQLITE_ENABLE_LOCKING_STYLE
 22615  22892     int openFlags;                      /* The flags specified at open() */
 22616  22893   #endif
 22617  22894   #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
 22618  22895     unsigned fsFlags;                   /* cached details from statfs() */
 22619  22896   #endif
 22620  22897   #if OS_VXWORKS
................................................................................
 25365  25642     while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
 25366  25643       amt -= wrote;
 25367  25644       offset += wrote;
 25368  25645       pBuf = &((char*)pBuf)[wrote];
 25369  25646     }
 25370  25647     SimulateIOError(( wrote=(-1), amt=1 ));
 25371  25648     SimulateDiskfullError(( wrote=0, amt=1 ));
        25649  +
 25372  25650     if( amt>0 ){
 25373  25651       if( wrote<0 ){
 25374  25652         /* lastErrno set by seekAndWrite */
 25375  25653         return SQLITE_IOERR_WRITE;
 25376  25654       }else{
 25377  25655         pFile->lastErrno = 0; /* not a system error */
 25378  25656         return SQLITE_FULL;
 25379  25657       }
 25380  25658     }
        25659  +
 25381  25660     return SQLITE_OK;
 25382  25661   }
 25383  25662   
 25384  25663   #ifdef SQLITE_TEST
 25385  25664   /*
 25386  25665   ** Count the number of fullsyncs and normal syncs.  This is used to test
 25387  25666   ** that syncs and fullsyncs are occurring at the right times.
................................................................................
 25575  25854     return rc;
 25576  25855   }
 25577  25856   
 25578  25857   /*
 25579  25858   ** Truncate an open file to a specified size
 25580  25859   */
 25581  25860   static int unixTruncate(sqlite3_file *id, i64 nByte){
        25861  +  unixFile *pFile = (unixFile *)id;
 25582  25862     int rc;
 25583         -  assert( id );
        25863  +  assert( pFile );
 25584  25864     SimulateIOError( return SQLITE_IOERR_TRUNCATE );
 25585         -  rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
        25865  +
        25866  +  /* If the user has configured a chunk-size for this file, truncate the
        25867  +  ** file so that it consists of an integer number of chunks (i.e. the
        25868  +  ** actual file size after the operation may be larger than the requested
        25869  +  ** size).
        25870  +  */
        25871  +  if( pFile->szChunk ){
        25872  +    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
        25873  +  }
        25874  +
        25875  +  rc = ftruncate(pFile->h, (off_t)nByte);
 25586  25876     if( rc ){
 25587         -    ((unixFile*)id)->lastErrno = errno;
        25877  +    pFile->lastErrno = errno;
 25588  25878       return SQLITE_IOERR_TRUNCATE;
 25589  25879     }else{
 25590  25880   #ifndef NDEBUG
 25591  25881       /* If we are doing a normal write to a database file (as opposed to
 25592  25882       ** doing a hot-journal rollback or a write to some file other than a
 25593  25883       ** normal database file) and we truncate the file to zero length,
 25594  25884       ** that effectively updates the change counter.  This might happen
 25595  25885       ** when restoring a database using the backup API from a zero-length
 25596  25886       ** source.
 25597  25887       */
 25598         -    if( ((unixFile*)id)->inNormalWrite && nByte==0 ){
 25599         -      ((unixFile*)id)->transCntrChng = 1;
        25888  +    if( pFile->inNormalWrite && nByte==0 ){
        25889  +      pFile->transCntrChng = 1;
 25600  25890       }
 25601  25891   #endif
 25602  25892   
 25603  25893       return SQLITE_OK;
 25604  25894     }
 25605  25895   }
 25606  25896   
................................................................................
 25635  25925   /*
 25636  25926   ** Handler for proxy-locking file-control verbs.  Defined below in the
 25637  25927   ** proxying locking division.
 25638  25928   */
 25639  25929   static int proxyFileControl(sqlite3_file*,int,void*);
 25640  25930   #endif
 25641  25931   
        25932  +/* 
        25933  +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
        25934  +** file-control operation.
        25935  +**
        25936  +** If the user has configured a chunk-size for this file, it could be
        25937  +** that the file needs to be extended at this point. Otherwise, the
        25938  +** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix.
        25939  +*/
        25940  +static int fcntlSizeHint(unixFile *pFile, i64 nByte){
        25941  +  if( pFile->szChunk ){
        25942  +    i64 nSize;                    /* Required file size */
        25943  +    struct stat buf;              /* Used to hold return values of fstat() */
        25944  +   
        25945  +    if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
        25946  +
        25947  +    nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
        25948  +    if( nSize>(i64)buf.st_size ){
        25949  +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
        25950  +      if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){
        25951  +        return SQLITE_IOERR_WRITE;
        25952  +      }
        25953  +#else
        25954  +      /* If the OS does not have posix_fallocate(), fake it. First use
        25955  +      ** ftruncate() to set the file size, then write a single byte to
        25956  +      ** the last byte in each block within the extended region. This
        25957  +      ** is the same technique used by glibc to implement posix_fallocate()
        25958  +      ** on systems that do not have a real fallocate() system call.
        25959  +      */
        25960  +      int nBlk = buf.st_blksize;  /* File-system block size */
        25961  +      i64 iWrite;                 /* Next offset to write to */
        25962  +      int nWrite;                 /* Return value from seekAndWrite() */
        25963  +
        25964  +      if( ftruncate(pFile->h, nSize) ){
        25965  +        pFile->lastErrno = errno;
        25966  +        return SQLITE_IOERR_TRUNCATE;
        25967  +      }
        25968  +      iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
        25969  +      do {
        25970  +        nWrite = seekAndWrite(pFile, iWrite, "", 1);
        25971  +        iWrite += nBlk;
        25972  +      } while( nWrite==1 && iWrite<nSize );
        25973  +      if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
        25974  +#endif
        25975  +    }
        25976  +  }
        25977  +
        25978  +  return SQLITE_OK;
        25979  +}
 25642  25980   
 25643  25981   /*
 25644  25982   ** Information and control of an open file handle.
 25645  25983   */
 25646  25984   static int unixFileControl(sqlite3_file *id, int op, void *pArg){
 25647  25985     switch( op ){
 25648  25986       case SQLITE_FCNTL_LOCKSTATE: {
 25649  25987         *(int*)pArg = ((unixFile*)id)->eFileLock;
 25650  25988         return SQLITE_OK;
 25651  25989       }
 25652  25990       case SQLITE_LAST_ERRNO: {
 25653  25991         *(int*)pArg = ((unixFile*)id)->lastErrno;
 25654  25992         return SQLITE_OK;
        25993  +    }
        25994  +    case SQLITE_FCNTL_CHUNK_SIZE: {
        25995  +      ((unixFile*)id)->szChunk = *(int *)pArg;
        25996  +      return SQLITE_OK;
 25655  25997       }
 25656  25998       case SQLITE_FCNTL_SIZE_HINT: {
 25657         -#if 0 /* No performance advantage seen on Linux */
 25658         -      sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
 25659         -      unixFile *pFile = (unixFile*)id;
 25660         -      ftruncate(pFile->h, szFile);
 25661         -#endif
 25662         -      return SQLITE_OK;
        25999  +      return fcntlSizeHint((unixFile *)id, *(i64 *)pArg);
 25663  26000       }
 25664  26001   #ifndef NDEBUG
 25665  26002       /* The pager calls this method to signal that it has done
 25666  26003       ** a rollback and that the database is therefore unchanged and
 25667  26004       ** it hence it is OK for the transaction change counter to be
 25668  26005       ** unchanged.
 25669  26006       */
................................................................................
 26100  26437       if( !apNew ){
 26101  26438         rc = SQLITE_IOERR_NOMEM;
 26102  26439         goto shmpage_out;
 26103  26440       }
 26104  26441       pShmNode->apRegion = apNew;
 26105  26442       while(pShmNode->nRegion<=iRegion){
 26106  26443         void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
 26107         -          MAP_SHARED, pShmNode->h, iRegion*szRegion
        26444  +          MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
 26108  26445         );
 26109  26446         if( pMem==MAP_FAILED ){
 26110  26447           rc = SQLITE_IOERR;
 26111  26448           goto shmpage_out;
 26112  26449         }
 26113  26450         pShmNode->apRegion[pShmNode->nRegion] = pMem;
 26114  26451         pShmNode->nRegion++;
................................................................................
 26617  26954   
 26618  26955     assert( pNew->pInode==NULL );
 26619  26956   
 26620  26957     /* Parameter isDelete is only used on vxworks. Express this explicitly 
 26621  26958     ** here to prevent compiler warnings about unused parameters.
 26622  26959     */
 26623  26960     UNUSED_PARAMETER(isDelete);
        26961  +
        26962  +  /* Usually the path zFilename should not be a relative pathname. The
        26963  +  ** exception is when opening the proxy "conch" file in builds that
        26964  +  ** include the special Apple locking styles.
        26965  +  */
        26966  +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
        26967  +  assert( zFilename==0 || zFilename[0]=='/' 
        26968  +    || pVfs->pAppData==(void*)&autolockIoFinder );
        26969  +#else
        26970  +  assert( zFilename==0 || zFilename[0]=='/' );
        26971  +#endif
 26624  26972   
 26625  26973     OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
 26626  26974     pNew->h = h;
 26627  26975     pNew->dirfd = dirfd;
 26628  26976     pNew->fileFlags = 0;
 26629         -  assert( zFilename==0 || zFilename[0]=='/' );  /* Never a relative pathname */
 26630  26977     pNew->zPath = zFilename;
 26631  26978   
 26632  26979   #if OS_VXWORKS
 26633  26980     pNew->pId = vxworksFindFileId(zFilename);
 26634  26981     if( pNew->pId==0 ){
 26635  26982       noLock = 1;
 26636  26983       rc = SQLITE_NOMEM;
................................................................................
 27923  28270   ** bytes of writable memory.
 27924  28271   */
 27925  28272   static int proxyGetHostID(unsigned char *pHostID, int *pError){
 27926  28273     struct timespec timeout = {1, 0}; /* 1 sec timeout */
 27927  28274     
 27928  28275     assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
 27929  28276     memset(pHostID, 0, PROXY_HOSTIDLEN);
        28277  +#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
        28278  +               && __MAC_OS_X_VERSION_MIN_REQUIRED<1050
 27930  28279     if( gethostuuid(pHostID, &timeout) ){
 27931  28280       int err = errno;
 27932  28281       if( pError ){
 27933  28282         *pError = err;
 27934  28283       }
 27935  28284       return SQLITE_IOERR;
 27936  28285     }
        28286  +#endif
 27937  28287   #ifdef SQLITE_TEST
 27938  28288     /* simulate multiple hosts by creating unique hostid file paths */
 27939  28289     if( sqlite3_hostid_num != 0){
 27940  28290       pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF));
 27941  28291     }
 27942  28292   #endif
 27943  28293     
................................................................................
 28520  28870       pCtx->pOldMethod = pFile->pMethod;
 28521  28871       pFile->pMethod = &proxyIoMethods;
 28522  28872     }else{
 28523  28873       if( pCtx->conchFile ){ 
 28524  28874         pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
 28525  28875         sqlite3_free(pCtx->conchFile);
 28526  28876       }
 28527         -    sqlite3_free(pCtx->lockProxyPath);
        28877  +    sqlite3DbFree(0, pCtx->lockProxyPath);
 28528  28878       sqlite3_free(pCtx->conchFilePath); 
 28529  28879       sqlite3_free(pCtx);
 28530  28880     }
 28531  28881     OSTRACE(("TRANSPROXY  %d %s\n", pFile->h,
 28532  28882              (rc==SQLITE_OK ? "ok" : "failed")));
 28533  28883     return rc;
 28534  28884   }
................................................................................
 28711  29061           rc = proxyReleaseConch(pFile);
 28712  29062           if( rc ) return rc;
 28713  29063         }
 28714  29064         rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
 28715  29065         if( rc ) return rc;
 28716  29066         sqlite3_free(conchFile);
 28717  29067       }
 28718         -    sqlite3_free(pCtx->lockProxyPath);
        29068  +    sqlite3DbFree(0, pCtx->lockProxyPath);
 28719  29069       sqlite3_free(pCtx->conchFilePath);
 28720         -    sqlite3_free(pCtx->dbPath);
        29070  +    sqlite3DbFree(0, pCtx->dbPath);
 28721  29071       /* restore the original locking context and pMethod then close it */
 28722  29072       pFile->lockingContext = pCtx->oldLockingContext;
 28723  29073       pFile->pMethod = pCtx->pOldMethod;
 28724  29074       sqlite3_free(pCtx);
 28725  29075       return pFile->pMethod->xClose(id);
 28726  29076     }
 28727  29077     return SQLITE_OK;
................................................................................
 29159  29509     HANDLE h;               /* Handle for accessing the file */
 29160  29510     unsigned char locktype; /* Type of lock currently held on this file */
 29161  29511     short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
 29162  29512     DWORD lastErrno;        /* The Windows errno from the last I/O error */
 29163  29513     DWORD sectorSize;       /* Sector size of the device file is on */
 29164  29514     winShm *pShm;           /* Instance of shared memory on this file */
 29165  29515     const char *zPath;      /* Full pathname of this file */
        29516  +  int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
 29166  29517   #if SQLITE_OS_WINCE
 29167  29518     WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
 29168  29519     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
 29169  29520     HANDLE hShared;         /* Shared memory segment used for locking */
 29170  29521     winceLock local;        /* Locks obtained by this instance of winFile */
 29171  29522     winceLock *shared;      /* Global shared lock memory for the file  */
 29172  29523   #endif
................................................................................
 29669  30020   *****************************************************************************/
 29670  30021   #endif /* SQLITE_OS_WINCE */
 29671  30022   
 29672  30023   /*****************************************************************************
 29673  30024   ** The next group of routines implement the I/O methods specified
 29674  30025   ** by the sqlite3_io_methods object.
 29675  30026   ******************************************************************************/
        30027  +
        30028  +/*
        30029  +** Some microsoft compilers lack this definition.
        30030  +*/
        30031  +#ifndef INVALID_SET_FILE_POINTER
        30032  +# define INVALID_SET_FILE_POINTER ((DWORD)-1)
        30033  +#endif
        30034  +
        30035  +/*
        30036  +** Move the current position of the file handle passed as the first 
        30037  +** argument to offset iOffset within the file. If successful, return 0. 
        30038  +** Otherwise, set pFile->lastErrno and return non-zero.
        30039  +*/
        30040  +static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
        30041  +  LONG upperBits;                 /* Most sig. 32 bits of new offset */
        30042  +  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
        30043  +  DWORD dwRet;                    /* Value returned by SetFilePointer() */
        30044  +
        30045  +  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
        30046  +  lowerBits = (LONG)(iOffset & 0xffffffff);
        30047  +
        30048  +  /* API oddity: If successful, SetFilePointer() returns a dword 
        30049  +  ** containing the lower 32-bits of the new file-offset. Or, if it fails,
        30050  +  ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, 
        30051  +  ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
        30052  +  ** whether an error has actually occured, it is also necessary to call 
        30053  +  ** GetLastError().
        30054  +  */
        30055  +  dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
        30056  +  if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
        30057  +    pFile->lastErrno = GetLastError();
        30058  +    return 1;
        30059  +  }
        30060  +
        30061  +  return 0;
        30062  +}
 29676  30063   
 29677  30064   /*
 29678  30065   ** Close a file.
 29679  30066   **
 29680  30067   ** It is reported that an attempt to close a handle might sometimes
 29681  30068   ** fail.  This is a very unreasonable result, but windows is notorious
 29682  30069   ** for being unreasonable so I do not doubt that it might happen.  If
................................................................................
 29712  30099     }
 29713  30100   #endif
 29714  30101     OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
 29715  30102     OpenCounter(-1);
 29716  30103     return rc ? SQLITE_OK : SQLITE_IOERR;
 29717  30104   }
 29718  30105   
 29719         -/*
 29720         -** Some microsoft compilers lack this definition.
 29721         -*/
 29722         -#ifndef INVALID_SET_FILE_POINTER
 29723         -# define INVALID_SET_FILE_POINTER ((DWORD)-1)
 29724         -#endif
 29725         -
 29726  30106   /*
 29727  30107   ** Read data from a file into a buffer.  Return SQLITE_OK if all
 29728  30108   ** bytes were read successfully and SQLITE_IOERR if anything goes
 29729  30109   ** wrong.
 29730  30110   */
 29731  30111   static int winRead(
 29732  30112     sqlite3_file *id,          /* File to read from */
 29733  30113     void *pBuf,                /* Write content into this buffer */
 29734  30114     int amt,                   /* Number of bytes to read */
 29735  30115     sqlite3_int64 offset       /* Begin reading at this offset */
 29736  30116   ){
 29737         -  LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
 29738         -  LONG lowerBits = (LONG)(offset & 0xffffffff);
 29739         -  DWORD rc;
 29740         -  winFile *pFile = (winFile*)id;
 29741         -  DWORD error;
 29742         -  DWORD got;
        30117  +  winFile *pFile = (winFile*)id;  /* file handle */
        30118  +  DWORD nRead;                    /* Number of bytes actually read from file */
 29743  30119   
 29744  30120     assert( id!=0 );
 29745  30121     SimulateIOError(return SQLITE_IOERR_READ);
 29746  30122     OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
 29747         -  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
 29748         -  if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
 29749         -    pFile->lastErrno = error;
        30123  +
        30124  +  if( seekWinFile(pFile, offset) ){
 29750  30125       return SQLITE_FULL;
 29751  30126     }
 29752         -  if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
        30127  +  if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
 29753  30128       pFile->lastErrno = GetLastError();
 29754  30129       return SQLITE_IOERR_READ;
 29755  30130     }
 29756         -  if( got==(DWORD)amt ){
 29757         -    return SQLITE_OK;
 29758         -  }else{
        30131  +  if( nRead<(DWORD)amt ){
 29759  30132       /* Unread parts of the buffer must be zero-filled */
 29760         -    memset(&((char*)pBuf)[got], 0, amt-got);
        30133  +    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
 29761  30134       return SQLITE_IOERR_SHORT_READ;
 29762  30135     }
        30136  +
        30137  +  return SQLITE_OK;
 29763  30138   }
 29764  30139   
 29765  30140   /*
 29766  30141   ** Write data from a buffer into a file.  Return SQLITE_OK on success
 29767  30142   ** or some other error code on failure.
 29768  30143   */
 29769  30144   static int winWrite(
 29770         -  sqlite3_file *id,         /* File to write into */
 29771         -  const void *pBuf,         /* The bytes to be written */
 29772         -  int amt,                  /* Number of bytes to write */
 29773         -  sqlite3_int64 offset      /* Offset into the file to begin writing at */
        30145  +  sqlite3_file *id,               /* File to write into */
        30146  +  const void *pBuf,               /* The bytes to be written */
        30147  +  int amt,                        /* Number of bytes to write */
        30148  +  sqlite3_int64 offset            /* Offset into the file to begin writing at */
 29774  30149   ){
 29775         -  LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
 29776         -  LONG lowerBits = (LONG)(offset & 0xffffffff);
 29777         -  DWORD rc;
 29778         -  winFile *pFile = (winFile*)id;
 29779         -  DWORD error;
 29780         -  DWORD wrote = 0;
        30150  +  int rc;                         /* True if error has occured, else false */
        30151  +  winFile *pFile = (winFile*)id;  /* File handle */
 29781  30152   
 29782         -  assert( id!=0 );
        30153  +  assert( amt>0 );
        30154  +  assert( pFile );
 29783  30155     SimulateIOError(return SQLITE_IOERR_WRITE);
 29784  30156     SimulateDiskfullError(return SQLITE_FULL);
        30157  +
 29785  30158     OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
 29786         -  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
 29787         -  if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
 29788         -    pFile->lastErrno = error;
 29789         -    if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
 29790         -      return SQLITE_FULL;
 29791         -    }else{
 29792         -      return SQLITE_IOERR_WRITE;
        30159  +
        30160  +  rc = seekWinFile(pFile, offset);
        30161  +  if( rc==0 ){
        30162  +    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
        30163  +    int nRem = amt;               /* Number of bytes yet to be written */
        30164  +    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
        30165  +
        30166  +    while( nRem>0 && WriteFile(pFile->h, aRem, nRem, &nWrite, 0) && nWrite>0 ){
        30167  +      aRem += nWrite;
        30168  +      nRem -= nWrite;
        30169  +    }
        30170  +    if( nRem>0 ){
        30171  +      pFile->lastErrno = GetLastError();
        30172  +      rc = 1;
 29793  30173       }
 29794  30174     }
 29795         -  assert( amt>0 );
 29796         -  while(
 29797         -     amt>0
 29798         -     && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
 29799         -     && wrote>0
 29800         -  ){
 29801         -    amt -= wrote;
 29802         -    pBuf = &((char*)pBuf)[wrote];
 29803         -  }
 29804         -  if( !rc || amt>(int)wrote ){
 29805         -    pFile->lastErrno = GetLastError();
        30175  +
        30176  +  if( rc ){
 29806  30177       if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
 29807  30178         return SQLITE_FULL;
 29808         -    }else{
 29809         -      return SQLITE_IOERR_WRITE;
 29810  30179       }
        30180  +    return SQLITE_IOERR_WRITE;
 29811  30181     }
 29812  30182     return SQLITE_OK;
 29813  30183   }
 29814  30184   
 29815  30185   /*
 29816  30186   ** Truncate an open file to a specified size
 29817  30187   */
 29818  30188   static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
 29819         -  LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
 29820         -  LONG lowerBits = (LONG)(nByte & 0xffffffff);
 29821         -  DWORD dwRet;
 29822         -  winFile *pFile = (winFile*)id;
 29823         -  DWORD error;
 29824         -  int rc = SQLITE_OK;
        30189  +  winFile *pFile = (winFile*)id;  /* File handle object */
        30190  +  int rc = SQLITE_OK;             /* Return code for this function */
 29825  30191   
 29826         -  assert( id!=0 );
        30192  +  assert( pFile );
        30193  +
 29827  30194     OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
 29828  30195     SimulateIOError(return SQLITE_IOERR_TRUNCATE);
 29829         -  dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
 29830         -  if( dwRet==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
 29831         -    pFile->lastErrno = error;
        30196  +
        30197  +  /* If the user has configured a chunk-size for this file, truncate the
        30198  +  ** file so that it consists of an integer number of chunks (i.e. the
        30199  +  ** actual file size after the operation may be larger than the requested
        30200  +  ** size).
        30201  +  */
        30202  +  if( pFile->szChunk ){
        30203  +    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
        30204  +  }
        30205  +
        30206  +  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
        30207  +  if( seekWinFile(pFile, nByte) ){
 29832  30208       rc = SQLITE_IOERR_TRUNCATE;
 29833         -  /* SetEndOfFile will fail if nByte is negative */
 29834         -  }else if( !SetEndOfFile(pFile->h) ){
        30209  +  }else if( 0==SetEndOfFile(pFile->h) ){
 29835  30210       pFile->lastErrno = GetLastError();
 29836  30211       rc = SQLITE_IOERR_TRUNCATE;
 29837  30212     }
 29838         -  OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc==SQLITE_OK ? "ok" : "failed"));
        30213  +
        30214  +  OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
 29839  30215     return rc;
 29840  30216   }
 29841  30217   
 29842  30218   #ifdef SQLITE_TEST
 29843  30219   /*
 29844  30220   ** Count the number of fullsyncs and normal syncs.  This is used to test
 29845  30221   ** that syncs and fullsyncs are occuring at the right times.
................................................................................
 30195  30571       case SQLITE_FCNTL_LOCKSTATE: {
 30196  30572         *(int*)pArg = ((winFile*)id)->locktype;
 30197  30573         return SQLITE_OK;
 30198  30574       }
 30199  30575       case SQLITE_LAST_ERRNO: {
 30200  30576         *(int*)pArg = (int)((winFile*)id)->lastErrno;
 30201  30577         return SQLITE_OK;
        30578  +    }
        30579  +    case SQLITE_FCNTL_CHUNK_SIZE: {
        30580  +      ((winFile*)id)->szChunk = *(int *)pArg;
        30581  +      return SQLITE_OK;
 30202  30582       }
 30203  30583       case SQLITE_FCNTL_SIZE_HINT: {
 30204  30584         sqlite3_int64 sz = *(sqlite3_int64*)pArg;
 30205  30585         SimulateIOErrorBenign(1);
 30206  30586         winTruncate(id, sz);
 30207  30587         SimulateIOErrorBenign(0);
 30208  30588         return SQLITE_OK;
................................................................................
 30232  30612   static int winDeviceCharacteristics(sqlite3_file *id){
 30233  30613     UNUSED_PARAMETER(id);
 30234  30614     return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
 30235  30615   }
 30236  30616   
 30237  30617   #ifndef SQLITE_OMIT_WAL
 30238  30618   
        30619  +/* 
        30620  +** Windows will only let you create file view mappings
        30621  +** on allocation size granularity boundaries.
        30622  +** During sqlite3_os_init() we do a GetSystemInfo()
        30623  +** to get the granularity size.
        30624  +*/
        30625  +SYSTEM_INFO winSysInfo;
        30626  +
 30239  30627   /*
 30240  30628   ** Helper functions to obtain and relinquish the global mutex. The
 30241  30629   ** global mutex is used to protect the winLockInfo objects used by 
 30242  30630   ** this file, all of which may be shared by multiple threads.
 30243  30631   **
 30244  30632   ** Function winShmMutexHeld() is used to assert() that the global mutex 
 30245  30633   ** is held when required. This function is only used as part of assert() 
................................................................................
 30400  30788   **
 30401  30789   ** This is not a VFS shared-memory method; it is a utility function called
 30402  30790   ** by VFS shared-memory methods.
 30403  30791   */
 30404  30792   static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
 30405  30793     winShmNode **pp;
 30406  30794     winShmNode *p;
        30795  +  BOOL bRc;
 30407  30796     assert( winShmMutexHeld() );
 30408  30797     pp = &winShmNodeList;
 30409  30798     while( (p = *pp)!=0 ){
 30410  30799       if( p->nRef==0 ){
 30411  30800         int i;
 30412  30801         if( p->mutex ) sqlite3_mutex_free(p->mutex);
 30413  30802         for(i=0; i<p->nRegion; i++){
 30414         -        UnmapViewOfFile(p->aRegion[i].pMap);
 30415         -        CloseHandle(p->aRegion[i].hMap);
        30803  +        bRc = UnmapViewOfFile(p->aRegion[i].pMap);
        30804  +        OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
        30805  +                 (int)GetCurrentProcessId(), i,
        30806  +                 bRc ? "ok" : "failed"));
        30807  +        bRc = CloseHandle(p->aRegion[i].hMap);
        30808  +        OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
        30809  +                 (int)GetCurrentProcessId(), i,
        30810  +                 bRc ? "ok" : "failed"));
 30416  30811         }
 30417  30812         if( p->hFile.h != INVALID_HANDLE_VALUE ){
 30418  30813           SimulateIOErrorBenign(1);
 30419  30814           winClose((sqlite3_file *)&p->hFile);
 30420  30815           SimulateIOErrorBenign(0);
 30421  30816         }
 30422  30817         if( deleteFlag ){
................................................................................
 30485  30880       winShmNodeList = pShmNode;
 30486  30881   
 30487  30882       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
 30488  30883       if( pShmNode->mutex==0 ){
 30489  30884         rc = SQLITE_NOMEM;
 30490  30885         goto shm_open_err;
 30491  30886       }
        30887  +
 30492  30888       rc = winOpen(pDbFd->pVfs,
 30493  30889                    pShmNode->zFilename,             /* Name of the file (UTF-8) */
 30494  30890                    (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
 30495         -                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
        30891  +                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
 30496  30892                    0);
 30497  30893       if( SQLITE_OK!=rc ){
 30498  30894         rc = SQLITE_CANTOPEN_BKPT;
 30499  30895         goto shm_open_err;
 30500  30896       }
 30501  30897   
 30502  30898       /* Check to see if another process is holding the dead-man switch.
................................................................................
 30796  31192       while( pShmNode->nRegion<=iRegion ){
 30797  31193         HANDLE hMap;                /* file-mapping handle */
 30798  31194         void *pMap = 0;             /* Mapped memory region */
 30799  31195        
 30800  31196         hMap = CreateFileMapping(pShmNode->hFile.h, 
 30801  31197             NULL, PAGE_READWRITE, 0, nByte, NULL
 30802  31198         );
        31199  +      OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
        31200  +               (int)GetCurrentProcessId(), pShmNode->nRegion, nByte,
        31201  +               hMap ? "ok" : "failed"));
 30803  31202         if( hMap ){
        31203  +        int iOffset = pShmNode->nRegion*szRegion;
        31204  +        int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
 30804  31205           pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
 30805         -            0, 0, nByte
        31206  +            0, iOffset - iOffsetShift, szRegion + iOffsetShift
 30806  31207           );
        31208  +        OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
        31209  +                 (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
        31210  +                 pMap ? "ok" : "failed"));
 30807  31211         }
 30808  31212         if( !pMap ){
 30809  31213           pShmNode->lastErrno = GetLastError();
 30810  31214           rc = SQLITE_IOERR;
 30811  31215           if( hMap ) CloseHandle(hMap);
 30812  31216           goto shmpage_out;
 30813  31217         }
................................................................................
 30816  31220         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
 30817  31221         pShmNode->nRegion++;
 30818  31222       }
 30819  31223     }
 30820  31224   
 30821  31225   shmpage_out:
 30822  31226     if( pShmNode->nRegion>iRegion ){
        31227  +    int iOffset = iRegion*szRegion;
        31228  +    int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
 30823  31229       char *p = (char *)pShmNode->aRegion[iRegion].pMap;
 30824         -    *pp = (void *)&p[iRegion*szRegion];
        31230  +    *pp = (void *)&p[iOffsetShift];
 30825  31231     }else{
 30826  31232       *pp = 0;
 30827  31233     }
 30828  31234     sqlite3_mutex_leave(pShmNode->mutex);
 30829  31235     return rc;
 30830  31236   }
 30831  31237   
................................................................................
 31044  31450     DWORD dwShareMode;
 31045  31451     DWORD dwCreationDisposition;
 31046  31452     DWORD dwFlagsAndAttributes = 0;
 31047  31453   #if SQLITE_OS_WINCE
 31048  31454     int isTemp = 0;
 31049  31455   #endif
 31050  31456     winFile *pFile = (winFile*)id;
 31051         -  void *zConverted;                 /* Filename in OS encoding */
 31052         -  const char *zUtf8Name = zName;    /* Filename in UTF-8 encoding */
 31053         -  char zTmpname[MAX_PATH+1];        /* Buffer used to create temp filename */
        31457  +  void *zConverted;              /* Filename in OS encoding */
        31458  +  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
        31459  +
        31460  +  /* If argument zPath is a NULL pointer, this function is required to open
        31461  +  ** a temporary file. Use this buffer to store the file name in.
        31462  +  */
        31463  +  char zTmpname[MAX_PATH+1];     /* Buffer used to create temp filename */
        31464  +
        31465  +  int rc = SQLITE_OK;            /* Function Return Code */
        31466  +#if !defined(NDEBUG) || SQLITE_OS_WINCE
        31467  +  int eType = flags&0xFFFFFF00;  /* Type of file to open */
        31468  +#endif
        31469  +
        31470  +  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
        31471  +  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
        31472  +  int isCreate     = (flags & SQLITE_OPEN_CREATE);
        31473  +#ifndef NDEBUG
        31474  +  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
        31475  +#endif
        31476  +  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
        31477  +
        31478  +#ifndef NDEBUG
        31479  +  int isOpenJournal = (isCreate && (
        31480  +        eType==SQLITE_OPEN_MASTER_JOURNAL 
        31481  +     || eType==SQLITE_OPEN_MAIN_JOURNAL 
        31482  +     || eType==SQLITE_OPEN_WAL
        31483  +  ));
        31484  +#endif
        31485  +
        31486  +  /* Check the following statements are true: 
        31487  +  **
        31488  +  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
        31489  +  **   (b) if CREATE is set, then READWRITE must also be set, and
        31490  +  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
        31491  +  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
        31492  +  */
        31493  +  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
        31494  +  assert(isCreate==0 || isReadWrite);
        31495  +  assert(isExclusive==0 || isCreate);
        31496  +  assert(isDelete==0 || isCreate);
        31497  +
        31498  +  /* The main DB, main journal, WAL file and master journal are never 
        31499  +  ** automatically deleted. Nor are they ever temporary files.  */
        31500  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
        31501  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
        31502  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
        31503  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
        31504  +
        31505  +  /* Assert that the upper layer has set one of the "file-type" flags. */
        31506  +  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
        31507  +       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
        31508  +       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
        31509  +       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
        31510  +  );
 31054  31511   
 31055  31512     assert( id!=0 );
 31056  31513     UNUSED_PARAMETER(pVfs);
 31057  31514   
 31058  31515     pFile->h = INVALID_HANDLE_VALUE;
 31059  31516   
 31060  31517     /* If the second argument to this function is NULL, generate a 
 31061  31518     ** temporary file name to use 
 31062  31519     */
 31063  31520     if( !zUtf8Name ){
 31064         -    int rc = getTempname(MAX_PATH+1, zTmpname);
        31521  +    assert(isDelete && !isOpenJournal);
        31522  +    rc = getTempname(MAX_PATH+1, zTmpname);
 31065  31523       if( rc!=SQLITE_OK ){
 31066  31524         return rc;
 31067  31525       }
 31068  31526       zUtf8Name = zTmpname;
 31069  31527     }
 31070  31528   
 31071  31529     /* Convert the filename to the system encoding. */
 31072  31530     zConverted = convertUtf8Filename(zUtf8Name);
 31073  31531     if( zConverted==0 ){
 31074  31532       return SQLITE_NOMEM;
 31075  31533     }
 31076  31534   
 31077         -  if( flags & SQLITE_OPEN_READWRITE ){
        31535  +  if( isReadWrite ){
 31078  31536       dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
 31079  31537     }else{
 31080  31538       dwDesiredAccess = GENERIC_READ;
 31081  31539     }
        31540  +
 31082  31541     /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 
 31083  31542     ** created. SQLite doesn't use it to indicate "exclusive access" 
 31084  31543     ** as it is usually understood.
 31085  31544     */
 31086         -  assert(!(flags & SQLITE_OPEN_EXCLUSIVE) || (flags & SQLITE_OPEN_CREATE));
 31087         -  if( flags & SQLITE_OPEN_EXCLUSIVE ){
        31545  +  if( isExclusive ){
 31088  31546       /* Creates a new file, only if it does not already exist. */
 31089  31547       /* If the file exists, it fails. */
 31090  31548       dwCreationDisposition = CREATE_NEW;
 31091         -  }else if( flags & SQLITE_OPEN_CREATE ){
        31549  +  }else if( isCreate ){
 31092  31550       /* Open existing file, or create if it doesn't exist */
 31093  31551       dwCreationDisposition = OPEN_ALWAYS;
 31094  31552     }else{
 31095  31553       /* Opens a file, only if it exists. */
 31096  31554       dwCreationDisposition = OPEN_EXISTING;
 31097  31555     }
        31556  +
 31098  31557     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
 31099         -  if( flags & SQLITE_OPEN_DELETEONCLOSE ){
        31558  +
        31559  +  if( isDelete ){
 31100  31560   #if SQLITE_OS_WINCE
 31101  31561       dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
 31102  31562       isTemp = 1;
 31103  31563   #else
 31104  31564       dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
 31105  31565                                  | FILE_ATTRIBUTE_HIDDEN
 31106  31566                                  | FILE_FLAG_DELETE_ON_CLOSE;
................................................................................
 31109  31569       dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
 31110  31570     }
 31111  31571     /* Reports from the internet are that performance is always
 31112  31572     ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
 31113  31573   #if SQLITE_OS_WINCE
 31114  31574     dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
 31115  31575   #endif
        31576  +
 31116  31577     if( isNT() ){
 31117  31578       h = CreateFileW((WCHAR*)zConverted,
 31118  31579          dwDesiredAccess,
 31119  31580          dwShareMode,
 31120  31581          NULL,
 31121  31582          dwCreationDisposition,
 31122  31583          dwFlagsAndAttributes,
................................................................................
 31134  31595          NULL,
 31135  31596          dwCreationDisposition,
 31136  31597          dwFlagsAndAttributes,
 31137  31598          NULL
 31138  31599       );
 31139  31600   #endif
 31140  31601     }
        31602  +
 31141  31603     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
 31142  31604              h, zName, dwDesiredAccess, 
 31143  31605              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
        31606  +
 31144  31607     if( h==INVALID_HANDLE_VALUE ){
 31145  31608       pFile->lastErrno = GetLastError();
 31146  31609       free(zConverted);
 31147         -    if( flags & SQLITE_OPEN_READWRITE ){
        31610  +    if( isReadWrite ){
 31148  31611         return winOpen(pVfs, zName, id, 
 31149         -             ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
        31612  +             ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
 31150  31613       }else{
 31151  31614         return SQLITE_CANTOPEN_BKPT;
 31152  31615       }
 31153  31616     }
        31617  +
 31154  31618     if( pOutFlags ){
 31155         -    if( flags & SQLITE_OPEN_READWRITE ){
        31619  +    if( isReadWrite ){
 31156  31620         *pOutFlags = SQLITE_OPEN_READWRITE;
 31157  31621       }else{
 31158  31622         *pOutFlags = SQLITE_OPEN_READONLY;
 31159  31623       }
 31160  31624     }
        31625  +
 31161  31626     memset(pFile, 0, sizeof(*pFile));
 31162  31627     pFile->pMethod = &winIoMethod;
 31163  31628     pFile->h = h;
 31164  31629     pFile->lastErrno = NO_ERROR;
 31165  31630     pFile->pVfs = pVfs;
 31166  31631     pFile->pShm = 0;
 31167  31632     pFile->zPath = zName;
 31168  31633     pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
        31634  +
 31169  31635   #if SQLITE_OS_WINCE
 31170         -  if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
 31171         -               (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
        31636  +  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
 31172  31637          && !winceCreateLock(zName, pFile)
 31173  31638     ){
 31174  31639       CloseHandle(h);
 31175  31640       free(zConverted);
 31176  31641       return SQLITE_CANTOPEN_BKPT;
 31177  31642     }
 31178  31643     if( isTemp ){
 31179  31644       pFile->zDeleteOnClose = zConverted;
 31180  31645     }else
 31181  31646   #endif
 31182  31647     {
 31183  31648       free(zConverted);
 31184  31649     }
        31650  +
 31185  31651     OpenCounter(+1);
 31186         -  return SQLITE_OK;
        31652  +  return rc;
 31187  31653   }
 31188  31654   
 31189  31655   /*
 31190  31656   ** Delete the named file.
 31191  31657   **
 31192  31658   ** Note that windows does not allow a file to be deleted if some other
 31193  31659   ** process has it open.  Sometimes a virus scanner or indexing program
................................................................................
 31697  32163       winDlClose,          /* xDlClose */
 31698  32164       winRandomness,       /* xRandomness */
 31699  32165       winSleep,            /* xSleep */
 31700  32166       winCurrentTime,      /* xCurrentTime */
 31701  32167       winGetLastError,     /* xGetLastError */
 31702  32168       winCurrentTimeInt64, /* xCurrentTimeInt64 */
 31703  32169     };
        32170  +
        32171  +#ifndef SQLITE_OMIT_WAL
        32172  +  /* get memory map allocation granularity */
        32173  +  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
        32174  +  GetSystemInfo(&winSysInfo);
        32175  +  assert(winSysInfo.dwAllocationGranularity > 0);
        32176  +#endif
 31704  32177   
 31705  32178     sqlite3_vfs_register(&winVfs, 1);
 31706  32179     return SQLITE_OK; 
 31707  32180   }
 31708  32181   SQLITE_API int sqlite3_os_end(void){ 
 31709  32182     return SQLITE_OK;
 31710  32183   }
................................................................................
 31747  32220   ** sometimes grow into tens of thousands or larger.  The size of the
 31748  32221   ** Bitvec object is the number of pages in the database file at the
 31749  32222   ** start of a transaction, and is thus usually less than a few thousand,
 31750  32223   ** but can be as large as 2 billion for a really big database.
 31751  32224   */
 31752  32225   
 31753  32226   /* Size of the Bitvec structure in bytes. */
 31754         -#define BITVEC_SZ        (sizeof(void*)*128)  /* 512 on 32bit.  1024 on 64bit */
        32227  +#define BITVEC_SZ        512
 31755  32228   
 31756  32229   /* Round the union size down to the nearest pointer boundary, since that's how 
 31757  32230   ** it will be aligned within the Bitvec struct. */
 31758  32231   #define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
 31759  32232   
 31760  32233   /* Type of the array "element" for the bitmap representation. 
 31761  32234   ** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
................................................................................
 32262  32735   /*************************************************** General Interfaces ******
 32263  32736   **
 32264  32737   ** Initialize and shutdown the page cache subsystem. Neither of these 
 32265  32738   ** functions are threadsafe.
 32266  32739   */
 32267  32740   SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
 32268  32741     if( sqlite3GlobalConfig.pcache.xInit==0 ){
        32742  +    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
        32743  +    ** built-in default page cache is used instead of the application defined
        32744  +    ** page cache. */
 32269  32745       sqlite3PCacheSetDefault();
 32270  32746     }
 32271  32747     return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg);
 32272  32748   }
 32273  32749   SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
 32274  32750     if( sqlite3GlobalConfig.pcache.xShutdown ){
        32751  +    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
 32275  32752       sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg);
 32276  32753     }
 32277  32754   }
 32278  32755   
 32279  32756   /*
 32280  32757   ** Return the size in bytes of a PCache object.
 32281  32758   */
................................................................................
 32728  33205   */
 32729  33206   
 32730  33207   
 32731  33208   typedef struct PCache1 PCache1;
 32732  33209   typedef struct PgHdr1 PgHdr1;
 32733  33210   typedef struct PgFreeslot PgFreeslot;
 32734  33211   
 32735         -/* Pointers to structures of this type are cast and returned as 
 32736         -** opaque sqlite3_pcache* handles
        33212  +/* Each page cache is an instance of the following object.  Every
        33213  +** open database file (including each in-memory database and each
        33214  +** temporary or transient database) has a single page cache which
        33215  +** is an instance of this object.
        33216  +**
        33217  +** Pointers to structures of this type are cast and returned as 
        33218  +** opaque sqlite3_pcache* handles.
 32737  33219   */
 32738  33220   struct PCache1 {
 32739  33221     /* Cache configuration parameters. Page size (szPage) and the purgeable
 32740  33222     ** flag (bPurgeable) are set when the cache is created. nMax may be 
 32741  33223     ** modified at any time by a call to the pcache1CacheSize() method.
 32742  33224     ** The global mutex must be held when accessing nMax.
 32743  33225     */
................................................................................
 32789  33271     int nMaxPage;                       /* Sum of nMaxPage for purgeable caches */
 32790  33272     int nMinPage;                       /* Sum of nMinPage for purgeable caches */
 32791  33273     int nCurrentPage;                   /* Number of purgeable pages allocated */
 32792  33274     PgHdr1 *pLruHead, *pLruTail;        /* LRU list of unpinned pages */
 32793  33275   
 32794  33276     /* Variables related to SQLITE_CONFIG_PAGECACHE settings. */
 32795  33277     int szSlot;                         /* Size of each free slot */
        33278  +  int nSlot;                          /* The number of pcache slots */
        33279  +  int nFreeSlot;                      /* Number of unused pcache slots */
        33280  +  int nReserve;                       /* Try to keep nFreeSlot above this */
 32796  33281     void *pStart, *pEnd;                /* Bounds of pagecache malloc range */
 32797  33282     PgFreeslot *pFree;                  /* Free page blocks */
 32798  33283     int isInit;                         /* True if initialized */
 32799  33284   } pcache1_g;
 32800  33285   
 32801  33286   /*
 32802  33287   ** All code in this file should access the global structure above via the
................................................................................
 32836  33321   ** enough to contain 'n' buffers of 'sz' bytes each.
 32837  33322   */
 32838  33323   SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
 32839  33324     if( pcache1.isInit ){
 32840  33325       PgFreeslot *p;
 32841  33326       sz = ROUNDDOWN8(sz);
 32842  33327       pcache1.szSlot = sz;
        33328  +    pcache1.nSlot = pcache1.nFreeSlot = n;
        33329  +    pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
 32843  33330       pcache1.pStart = pBuf;
 32844  33331       pcache1.pFree = 0;
 32845  33332       while( n-- ){
 32846  33333         p = (PgFreeslot*)pBuf;
 32847  33334         p->pNext = pcache1.pFree;
 32848  33335         pcache1.pFree = p;
 32849  33336         pBuf = (void*)&((char*)pBuf)[sz];
................................................................................
 32862  33349     void *p;
 32863  33350     assert( sqlite3_mutex_held(pcache1.mutex) );
 32864  33351     sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
 32865  33352     if( nByte<=pcache1.szSlot && pcache1.pFree ){
 32866  33353       assert( pcache1.isInit );
 32867  33354       p = (PgHdr1 *)pcache1.pFree;
 32868  33355       pcache1.pFree = pcache1.pFree->pNext;
        33356  +    pcache1.nFreeSlot--;
        33357  +    assert( pcache1.nFreeSlot>=0 );
 32869  33358       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
 32870  33359     }else{
 32871  33360   
 32872  33361       /* Allocate a new buffer using sqlite3Malloc. Before doing so, exit the
 32873  33362       ** global pcache mutex and unlock the pager-cache object pCache. This is 
 32874  33363       ** so that if the attempt to allocate a new buffer causes the the 
 32875  33364       ** configured soft-heap-limit to be breached, it will be possible to
................................................................................
 32895  33384     if( p==0 ) return;
 32896  33385     if( p>=pcache1.pStart && p<pcache1.pEnd ){
 32897  33386       PgFreeslot *pSlot;
 32898  33387       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
 32899  33388       pSlot = (PgFreeslot*)p;
 32900  33389       pSlot->pNext = pcache1.pFree;
 32901  33390       pcache1.pFree = pSlot;
        33391  +    pcache1.nFreeSlot++;
        33392  +    assert( pcache1.nFreeSlot<=pcache1.nSlot );
 32902  33393     }else{
 32903  33394       int iSize;
 32904  33395       assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
 32905  33396       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
 32906  33397       iSize = sqlite3MallocSize(p);
 32907  33398       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
 32908  33399       sqlite3_free(p);
 32909  33400     }
 32910  33401   }
 32911  33402   
        33403  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
        33404  +/*
        33405  +** Return the size of a pcache allocation
        33406  +*/
        33407  +static int pcache1MemSize(void *p){
        33408  +  assert( sqlite3_mutex_held(pcache1.mutex) );
        33409  +  if( p>=pcache1.pStart && p<pcache1.pEnd ){
        33410  +    return pcache1.szSlot;
        33411  +  }else{
        33412  +    int iSize;
        33413  +    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
        33414  +    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
        33415  +    iSize = sqlite3MallocSize(p);
        33416  +    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
        33417  +    return iSize;
        33418  +  }
        33419  +}
        33420  +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
        33421  +
 32912  33422   /*
 32913  33423   ** Allocate a new page object initially associated with cache pCache.
 32914  33424   */
 32915  33425   static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
 32916  33426     int nByte = sizeof(PgHdr1) + pCache->szPage;
 32917  33427     void *pPg = pcache1Alloc(nByte);
 32918  33428     PgHdr1 *p;
................................................................................
 32961  33471   */
 32962  33472   SQLITE_PRIVATE void sqlite3PageFree(void *p){
 32963  33473     pcache1EnterMutex();
 32964  33474     pcache1Free(p);
 32965  33475     pcache1LeaveMutex();
 32966  33476   }
 32967  33477   
        33478  +
        33479  +/*
        33480  +** Return true if it desirable to avoid allocating a new page cache
        33481  +** entry.
        33482  +**
        33483  +** If memory was allocated specifically to the page cache using
        33484  +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
        33485  +** it is desirable to avoid allocating a new page cache entry because
        33486  +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
        33487  +** for all page cache needs and we should not need to spill the
        33488  +** allocation onto the heap.
        33489  +**
        33490  +** Or, the heap is used for all page cache memory put the heap is
        33491  +** under memory pressure, then again it is desirable to avoid
        33492  +** allocating a new page cache entry in order to avoid stressing
        33493  +** the heap even further.
        33494  +*/
        33495  +static int pcache1UnderMemoryPressure(PCache1 *pCache){
        33496  +  assert( sqlite3_mutex_held(pcache1.mutex) );
        33497  +  if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){
        33498  +    return pcache1.nFreeSlot<pcache1.nReserve;
        33499  +  }else{
        33500  +    return sqlite3HeapNearlyFull();
        33501  +  }
        33502  +}
        33503  +
 32968  33504   /******************************************************************************/
 32969  33505   /******** General Implementation Functions ************************************/
 32970  33506   
 32971  33507   /*
 32972  33508   ** This function is used to resize the hash table used by the cache passed
 32973  33509   ** as the first argument.
 32974  33510   **
................................................................................
 33202  33738   **
 33203  33739   **   1. Regardless of the value of createFlag, the cache is searched for a 
 33204  33740   **      copy of the requested page. If one is found, it is returned.
 33205  33741   **
 33206  33742   **   2. If createFlag==0 and the page is not already in the cache, NULL is
 33207  33743   **      returned.
 33208  33744   **
 33209         -**   3. If createFlag is 1, and the page is not already in the cache,
 33210         -**      and if either of the following are true, return NULL:
        33745  +**   3. If createFlag is 1, and the page is not already in the cache, then
        33746  +**      return NULL (do not allocate a new page) if any of the following
        33747  +**      conditions are true:
 33211  33748   **
 33212  33749   **       (a) the number of pages pinned by the cache is greater than
 33213  33750   **           PCache1.nMax, or
        33751  +**
 33214  33752   **       (b) the number of pages pinned by the cache is greater than
 33215  33753   **           the sum of nMax for all purgeable caches, less the sum of 
 33216         -**           nMin for all other purgeable caches. 
        33754  +**           nMin for all other purgeable caches, or
 33217  33755   **
 33218  33756   **   4. If none of the first three conditions apply and the cache is marked
 33219  33757   **      as purgeable, and if one of the following is true:
 33220  33758   **
 33221  33759   **       (a) The number of pages allocated for the cache is already 
 33222  33760   **           PCache1.nMax, or
 33223  33761   **
 33224  33762   **       (b) The number of pages allocated for all purgeable caches is
 33225  33763   **           already equal to or greater than the sum of nMax for all
 33226  33764   **           purgeable caches,
        33765  +**
        33766  +**       (c) The system is under memory pressure and wants to avoid
        33767  +**           unnecessary pages cache entry allocations
 33227  33768   **
 33228  33769   **      then attempt to recycle a page from the LRU list. If it is the right
 33229  33770   **      size, return the recycled buffer. Otherwise, free the buffer and
 33230  33771   **      proceed to step 5. 
 33231  33772   **
 33232  33773   **   5. Otherwise, allocate and return a new page buffer.
 33233  33774   */
................................................................................
 33252  33793     }
 33253  33794   
 33254  33795     /* Step 3 of header comment. */
 33255  33796     nPinned = pCache->nPage - pCache->nRecyclable;
 33256  33797     if( createFlag==1 && (
 33257  33798           nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
 33258  33799        || nPinned>=(pCache->nMax * 9 / 10)
        33800  +     || pcache1UnderMemoryPressure(pCache)
 33259  33801     )){
 33260  33802       goto fetch_out;
 33261  33803     }
 33262  33804   
 33263  33805     if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
 33264  33806       goto fetch_out;
 33265  33807     }
 33266  33808   
 33267  33809     /* Step 4. Try to recycle a page buffer if appropriate. */
 33268  33810     if( pCache->bPurgeable && pcache1.pLruTail && (
 33269         -     (pCache->nPage+1>=pCache->nMax) || pcache1.nCurrentPage>=pcache1.nMaxPage
        33811  +         (pCache->nPage+1>=pCache->nMax)
        33812  +      || pcache1.nCurrentPage>=pcache1.nMaxPage
        33813  +      || pcache1UnderMemoryPressure(pCache)
 33270  33814     )){
 33271  33815       pPage = pcache1.pLruTail;
 33272  33816       pcache1RemoveFromHash(pPage);
 33273  33817       pcache1PinPage(pPage);
 33274  33818       if( pPage->pCache->szPage!=pCache->szPage ){
 33275  33819         pcache1FreePage(pPage);
 33276  33820         pPage = 0;
................................................................................
 33405  33949   /*
 33406  33950   ** Implementation of the sqlite3_pcache.xDestroy method. 
 33407  33951   **
 33408  33952   ** Destroy a cache allocated using pcache1Create().
 33409  33953   */
 33410  33954   static void pcache1Destroy(sqlite3_pcache *p){
 33411  33955     PCache1 *pCache = (PCache1 *)p;
        33956  +  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
 33412  33957     pcache1EnterMutex();
 33413  33958     pcache1TruncateUnsafe(pCache, 0);
 33414  33959     pcache1.nMaxPage -= pCache->nMax;
 33415  33960     pcache1.nMinPage -= pCache->nMin;
 33416  33961     pcache1EnforceMaxPage();
 33417  33962     pcache1LeaveMutex();
 33418  33963     sqlite3_free(pCache->apHash);
................................................................................
 33452  33997   ** of bytes of memory released.
 33453  33998   */
 33454  33999   SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
 33455  34000     int nFree = 0;
 33456  34001     if( pcache1.pStart==0 ){
 33457  34002       PgHdr1 *p;
 33458  34003       pcache1EnterMutex();
 33459         -    while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
 33460         -      nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
        34004  +    while( (nReq<0 || nFree<nReq) && ((p=pcache1.pLruTail)!=0) ){
        34005  +      nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
 33461  34006         pcache1PinPage(p);
 33462  34007         pcache1RemoveFromHash(p);
 33463  34008         pcache1FreePage(p);
 33464  34009       }
 33465  34010       pcache1LeaveMutex();
 33466  34011     }
 33467  34012     return nFree;
................................................................................
 33962  34507   
 33963  34508   #ifdef SQLITE_OMIT_WAL
 33964  34509   # define sqlite3WalOpen(x,y,z)                 0
 33965  34510   # define sqlite3WalClose(w,x,y,z)              0
 33966  34511   # define sqlite3WalBeginReadTransaction(y,z)   0
 33967  34512   # define sqlite3WalEndReadTransaction(z)
 33968  34513   # define sqlite3WalRead(v,w,x,y,z)             0
 33969         -# define sqlite3WalDbsize(y,z)
        34514  +# define sqlite3WalDbsize(y)                   0
 33970  34515   # define sqlite3WalBeginWriteTransaction(y)    0
 33971  34516   # define sqlite3WalEndWriteTransaction(x)      0
 33972  34517   # define sqlite3WalUndo(x,y,z)                 0
 33973  34518   # define sqlite3WalSavepoint(y,z)
 33974  34519   # define sqlite3WalSavepointUndo(y,z)          0
 33975  34520   # define sqlite3WalFrames(u,v,w,x,y,z)         0
 33976  34521   # define sqlite3WalCheckpoint(u,v,w,x)         0
................................................................................
 33998  34543   */
 33999  34544   SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
 34000  34545   SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
 34001  34546   
 34002  34547   /* Read a page from the write-ahead log, if it is present. */
 34003  34548   SQLITE_PRIVATE int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
 34004  34549   
 34005         -/* Return the size of the database as it existed at the beginning
 34006         -** of the snapshot */
 34007         -SQLITE_PRIVATE void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno);
        34550  +/* If the WAL is not empty, return the size of the database. */
        34551  +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
 34008  34552   
 34009  34553   /* Obtain or release the WRITER lock. */
 34010  34554   SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
 34011  34555   SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
 34012  34556   
 34013  34557   /* Undo any frames written (but not committed) to the log */
 34014  34558   SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
................................................................................
 34046  34590   
 34047  34591   #endif /* ifndef SQLITE_OMIT_WAL */
 34048  34592   #endif /* _WAL_H_ */
 34049  34593   
 34050  34594   /************** End of wal.h *************************************************/
 34051  34595   /************** Continuing where we left off in pager.c **********************/
 34052  34596   
 34053         -/*
 34054         -******************** NOTES ON THE DESIGN OF THE PAGER ************************
        34597  +
        34598  +/******************* NOTES ON THE DESIGN OF THE PAGER ************************
        34599  +**
        34600  +** This comment block describes invariants that hold when using a rollback
        34601  +** journal.  These invariants do not apply for journal_mode=WAL,
        34602  +** journal_mode=MEMORY, or journal_mode=OFF.
 34055  34603   **
 34056  34604   ** Within this comment block, a page is deemed to have been synced
 34057  34605   ** automatically as soon as it is written when PRAGMA synchronous=OFF.
 34058  34606   ** Otherwise, the page is not synced until the xSync method of the VFS
 34059  34607   ** is called successfully on the file containing the page.
 34060  34608   **
 34061  34609   ** Definition:  A page of the database file is said to be "overwriteable" if
................................................................................
 34081  34629   ** 
 34082  34630   ** (2) The content of a page written into the rollback journal exactly matches
 34083  34631   **     both the content in the database when the rollback journal was written
 34084  34632   **     and the content in the database at the beginning of the current
 34085  34633   **     transaction.
 34086  34634   ** 
 34087  34635   ** (3) Writes to the database file are an integer multiple of the page size
 34088         -**     in length and are aligned to a page boundary.
        34636  +**     in length and are aligned on a page boundary.
 34089  34637   ** 
 34090  34638   ** (4) Reads from the database file are either aligned on a page boundary and
 34091  34639   **     an integer multiple of the page size in length or are taken from the
 34092  34640   **     first 100 bytes of the database file.
 34093  34641   ** 
 34094  34642   ** (5) All writes to the database file are synced prior to the rollback journal
 34095  34643   **     being deleted, truncated, or zeroed.
................................................................................
 34112  34660   **     is called to restore the database file to the same size it was at
 34113  34661   **     the beginning of the transaction.  (In some VFSes, the xTruncate
 34114  34662   **     method is a no-op, but that does not change the fact the SQLite will
 34115  34663   **     invoke it.)
 34116  34664   ** 
 34117  34665   ** (9) Whenever the database file is modified, at least one bit in the range
 34118  34666   **     of bytes from 24 through 39 inclusive will be changed prior to releasing
 34119         -**     the EXCLUSIVE lock.
        34667  +**     the EXCLUSIVE lock, thus signaling other connections on the same
        34668  +**     database to flush their caches.
 34120  34669   **
 34121  34670   ** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
 34122  34671   **      than one billion transactions.
 34123  34672   **
 34124  34673   ** (11) A database file is well-formed at the beginning and at the conclusion
 34125  34674   **      of every transaction.
 34126  34675   **
 34127  34676   ** (12) An EXCLUSIVE lock is held on the database file when writing to
 34128  34677   **      the database file.
 34129  34678   **
 34130  34679   ** (13) A SHARED lock is held on the database file while reading any
 34131  34680   **      content out of the database file.
 34132         -*/
        34681  +**
        34682  +******************************************************************************/
 34133  34683   
 34134  34684   /*
 34135  34685   ** Macros for troubleshooting.  Normally turned off
 34136  34686   */
 34137  34687   #if 0
 34138  34688   int sqlite3PagerTrace=1;  /* True to enable tracing */
 34139  34689   #define sqlite3DebugPrintf printf
................................................................................
 34150  34700   ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
 34151  34701   ** struct as its argument.
 34152  34702   */
 34153  34703   #define PAGERID(p) ((int)(p->fd))
 34154  34704   #define FILEHANDLEID(fd) ((int)fd)
 34155  34705   
 34156  34706   /*
 34157         -** The page cache as a whole is always in one of the following
 34158         -** states:
 34159         -**
 34160         -**   PAGER_UNLOCK        The page cache is not currently reading or 
 34161         -**                       writing the database file.  There is no
 34162         -**                       data held in memory.  This is the initial
 34163         -**                       state.
 34164         -**
 34165         -**   PAGER_SHARED        The page cache is reading the database.
 34166         -**                       Writing is not permitted.  There can be
 34167         -**                       multiple readers accessing the same database
 34168         -**                       file at the same time.
 34169         -**
 34170         -**   PAGER_RESERVED      This process has reserved the database for writing
 34171         -**                       but has not yet made any changes.  Only one process
 34172         -**                       at a time can reserve the database.  The original
 34173         -**                       database file has not been modified so other
 34174         -**                       processes may still be reading the on-disk
 34175         -**                       database file.
 34176         -**
 34177         -**   PAGER_EXCLUSIVE     The page cache is writing the database.
 34178         -**                       Access is exclusive.  No other processes or
 34179         -**                       threads can be reading or writing while one
 34180         -**                       process is writing.
 34181         -**
 34182         -**   PAGER_SYNCED        The pager moves to this state from PAGER_EXCLUSIVE
 34183         -**                       after all dirty pages have been written to the
 34184         -**                       database file and the file has been synced to
 34185         -**                       disk. All that remains to do is to remove or
 34186         -**                       truncate the journal file and the transaction 
 34187         -**                       will be committed.
 34188         -**
 34189         -** The page cache comes up in PAGER_UNLOCK.  The first time a
 34190         -** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED.
 34191         -** After all pages have been released using sqlite_page_unref(),
 34192         -** the state transitions back to PAGER_UNLOCK.  The first time
 34193         -** that sqlite3PagerWrite() is called, the state transitions to
 34194         -** PAGER_RESERVED.  (Note that sqlite3PagerWrite() can only be
 34195         -** called on an outstanding page which means that the pager must
 34196         -** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
 34197         -** PAGER_RESERVED means that there is an open rollback journal.
 34198         -** The transition to PAGER_EXCLUSIVE occurs before any changes
 34199         -** are made to the database file, though writes to the rollback
 34200         -** journal occurs with just PAGER_RESERVED.  After an sqlite3PagerRollback()
 34201         -** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED,
 34202         -** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode.
 34203         -*/
 34204         -#define PAGER_UNLOCK      0
 34205         -#define PAGER_SHARED      1   /* same as SHARED_LOCK */
 34206         -#define PAGER_RESERVED    2   /* same as RESERVED_LOCK */
 34207         -#define PAGER_EXCLUSIVE   4   /* same as EXCLUSIVE_LOCK */
 34208         -#define PAGER_SYNCED      5
        34707  +** The Pager.eState variable stores the current 'state' of a pager. A
        34708  +** pager may be in any one of the seven states shown in the following
        34709  +** state diagram.
        34710  +**
        34711  +**                            OPEN <------+------+
        34712  +**                              |         |      |
        34713  +**                              V         |      |
        34714  +**               +---------> READER-------+      |
        34715  +**               |              |                |
        34716  +**               |              V                |
        34717  +**               |<-------WRITER_LOCKED------> ERROR
        34718  +**               |              |                ^  
        34719  +**               |              V                |
        34720  +**               |<------WRITER_CACHEMOD-------->|
        34721  +**               |              |                |
        34722  +**               |              V                |
        34723  +**               |<-------WRITER_DBMOD---------->|
        34724  +**               |              |                |
        34725  +**               |              V                |
        34726  +**               +<------WRITER_FINISHED-------->+
        34727  +**
        34728  +**
        34729  +** List of state transitions and the C [function] that performs each:
        34730  +** 
        34731  +**   OPEN              -> READER              [sqlite3PagerSharedLock]
        34732  +**   READER            -> OPEN                [pager_unlock]
        34733  +**
        34734  +**   READER            -> WRITER_LOCKED       [sqlite3PagerBegin]
        34735  +**   WRITER_LOCKED     -> WRITER_CACHEMOD     [pager_open_journal]
        34736  +**   WRITER_CACHEMOD   -> WRITER_DBMOD        [syncJournal]
        34737  +**   WRITER_DBMOD      -> WRITER_FINISHED     [sqlite3PagerCommitPhaseOne]
        34738  +**   WRITER_***        -> READER              [pager_end_transaction]
        34739  +**
        34740  +**   WRITER_***        -> ERROR               [pager_error]
        34741  +**   ERROR             -> OPEN                [pager_unlock]
        34742  +** 
        34743  +**
        34744  +**  OPEN:
        34745  +**
        34746  +**    The pager starts up in this state. Nothing is guaranteed in this
        34747  +**    state - the file may or may not be locked and the database size is
        34748  +**    unknown. The database may not be read or written.
        34749  +**
        34750  +**    * No read or write transaction is active.
        34751  +**    * Any lock, or no lock at all, may be held on the database file.
        34752  +**    * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
        34753  +**
        34754  +**  READER:
        34755  +**
        34756  +**    In this state all the requirements for reading the database in 
        34757  +**    rollback (non-WAL) mode are met. Unless the pager is (or recently
        34758  +**    was) in exclusive-locking mode, a user-level read transaction is 
        34759  +**    open. The database size is known in this state.
        34760  +**
        34761  +**    A connection running with locking_mode=normal enters this state when
        34762  +**    it opens a read-transaction on the database and returns to state
        34763  +**    OPEN after the read-transaction is completed. However a connection
        34764  +**    running in locking_mode=exclusive (including temp databases) remains in
        34765  +**    this state even after the read-transaction is closed. The only way
        34766  +**    a locking_mode=exclusive connection can transition from READER to OPEN
        34767  +**    is via the ERROR state (see below).
        34768  +** 
        34769  +**    * A read transaction may be active (but a write-transaction cannot).
        34770  +**    * A SHARED or greater lock is held on the database file.
        34771  +**    * The dbSize variable may be trusted (even if a user-level read 
        34772  +**      transaction is not active). The dbOrigSize and dbFileSize variables
        34773  +**      may not be trusted at this point.
        34774  +**    * If the database is a WAL database, then the WAL connection is open.
        34775  +**    * Even if a read-transaction is not open, it is guaranteed that 
        34776  +**      there is no hot-journal in the file-system.
        34777  +**
        34778  +**  WRITER_LOCKED:
        34779  +**
        34780  +**    The pager moves to this state from READER when a write-transaction
        34781  +**    is first opened on the database. In WRITER_LOCKED state, all locks 
        34782  +**    required to start a write-transaction are held, but no actual 
        34783  +**    modifications to the cache or database have taken place.
        34784  +**
        34785  +**    In rollback mode, a RESERVED or (if the transaction was opened with 
        34786  +**    BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
        34787  +**    moving to this state, but the journal file is not written to or opened 
        34788  +**    to in this state. If the transaction is committed or rolled back while 
        34789  +**    in WRITER_LOCKED state, all that is required is to unlock the database 
        34790  +**    file.
        34791  +**
        34792  +**    IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
        34793  +**    If the connection is running with locking_mode=exclusive, an attempt
        34794  +**    is made to obtain an EXCLUSIVE lock on the database file.
        34795  +**
        34796  +**    * A write transaction is active.
        34797  +**    * If the connection is open in rollback-mode, a RESERVED or greater 
        34798  +**      lock is held on the database file.
        34799  +**    * If the connection is open in WAL-mode, a WAL write transaction
        34800  +**      is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
        34801  +**      called).
        34802  +**    * The dbSize, dbOrigSize and dbFileSize variables are all valid.
        34803  +**    * The contents of the pager cache have not been modified.
        34804  +**    * The journal file may or may not be open.
        34805  +**    * Nothing (not even the first header) has been written to the journal.
        34806  +**
        34807  +**  WRITER_CACHEMOD:
        34808  +**
        34809  +**    A pager moves from WRITER_LOCKED state to this state when a page is
        34810  +**    first modified by the upper layer. In rollback mode the journal file
        34811  +**    is opened (if it is not already open) and a header written to the
        34812  +**    start of it. The database file on disk has not been modified.
        34813  +**
        34814  +**    * A write transaction is active.
        34815  +**    * A RESERVED or greater lock is held on the database file.
        34816  +**    * The journal file is open and the first header has been written 
        34817  +**      to it, but the header has not been synced to disk.
        34818  +**    * The contents of the page cache have been modified.
        34819  +**
        34820  +**  WRITER_DBMOD:
        34821  +**
        34822  +**    The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
        34823  +**    when it modifies the contents of the database file. WAL connections
        34824  +**    never enter this state (since they do not modify the database file,
        34825  +**    just the log file).
        34826  +**
        34827  +**    * A write transaction is active.
        34828  +**    * An EXCLUSIVE or greater lock is held on the database file.
        34829  +**    * The journal file is open and the first header has been written 
        34830  +**      and synced to disk.
        34831  +**    * The contents of the page cache have been modified (and possibly
        34832  +**      written to disk).
        34833  +**
        34834  +**  WRITER_FINISHED:
        34835  +**
        34836  +**    It is not possible for a WAL connection to enter this state.
        34837  +**
        34838  +**    A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
        34839  +**    state after the entire transaction has been successfully written into the
        34840  +**    database file. In this state the transaction may be committed simply
        34841  +**    by finalizing the journal file. Once in WRITER_FINISHED state, it is 
        34842  +**    not possible to modify the database further. At this point, the upper 
        34843  +**    layer must either commit or rollback the transaction.
        34844  +**
        34845  +**    * A write transaction is active.
        34846  +**    * An EXCLUSIVE or greater lock is held on the database file.
        34847  +**    * All writing and syncing of journal and database data has finished.
        34848  +**      If no error occured, all that remains is to finalize the journal to
        34849  +**      commit the transaction. If an error did occur, the caller will need
        34850  +**      to rollback the transaction. 
        34851  +**
        34852  +**  ERROR:
        34853  +**
        34854  +**    The ERROR state is entered when an IO or disk-full error (including
        34855  +**    SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it 
        34856  +**    difficult to be sure that the in-memory pager state (cache contents, 
        34857  +**    db size etc.) are consistent with the contents of the file-system.
        34858  +**
        34859  +**    Temporary pager files may enter the ERROR state, but in-memory pagers
        34860  +**    cannot.
        34861  +**
        34862  +**    For example, if an IO error occurs while performing a rollback, 
        34863  +**    the contents of the page-cache may be left in an inconsistent state.
        34864  +**    At this point it would be dangerous to change back to READER state
        34865  +**    (as usually happens after a rollback). Any subsequent readers might
        34866  +**    report database corruption (due to the inconsistent cache), and if
        34867  +**    they upgrade to writers, they may inadvertently corrupt the database
        34868  +**    file. To avoid this hazard, the pager switches into the ERROR state
        34869  +**    instead of READER following such an error.
        34870  +**
        34871  +**    Once it has entered the ERROR state, any attempt to use the pager
        34872  +**    to read or write data returns an error. Eventually, once all 
        34873  +**    outstanding transactions have been abandoned, the pager is able to
        34874  +**    transition back to OPEN state, discarding the contents of the 
        34875  +**    page-cache and any other in-memory state at the same time. Everything
        34876  +**    is reloaded from disk (and, if necessary, hot-journal rollback peformed)
        34877  +**    when a read-transaction is next opened on the pager (transitioning
        34878  +**    the pager into READER state). At that point the system has recovered 
        34879  +**    from the error.
        34880  +**
        34881  +**    Specifically, the pager jumps into the ERROR state if:
        34882  +**
        34883  +**      1. An error occurs while attempting a rollback. This happens in
        34884  +**         function sqlite3PagerRollback().
        34885  +**
        34886  +**      2. An error occurs while attempting to finalize a journal file
        34887  +**         following a commit in function sqlite3PagerCommitPhaseTwo().
        34888  +**
        34889  +**      3. An error occurs while attempting to write to the journal or
        34890  +**         database file in function pagerStress() in order to free up
        34891  +**         memory.
        34892  +**
        34893  +**    In other cases, the error is returned to the b-tree layer. The b-tree
        34894  +**    layer then attempts a rollback operation. If the error condition 
        34895  +**    persists, the pager enters the ERROR state via condition (1) above.
        34896  +**
        34897  +**    Condition (3) is necessary because it can be triggered by a read-only
        34898  +**    statement executed within a transaction. In this case, if the error
        34899  +**    code were simply returned to the user, the b-tree layer would not
        34900  +**    automatically attempt a rollback, as it assumes that an error in a
        34901  +**    read-only statement cannot leave the pager in an internally inconsistent 
        34902  +**    state.
        34903  +**
        34904  +**    * The Pager.errCode variable is set to something other than SQLITE_OK.
        34905  +**    * There are one or more outstanding references to pages (after the
        34906  +**      last reference is dropped the pager should move back to OPEN state).
        34907  +**    * The pager is not an in-memory pager.
        34908  +**    
        34909  +**
        34910  +** Notes:
        34911  +**
        34912  +**   * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
        34913  +**     connection is open in WAL mode. A WAL connection is always in one
        34914  +**     of the first four states.
        34915  +**
        34916  +**   * Normally, a connection open in exclusive mode is never in PAGER_OPEN
        34917  +**     state. There are two exceptions: immediately after exclusive-mode has
        34918  +**     been turned on (and before any read or write transactions are 
        34919  +**     executed), and when the pager is leaving the "error state".
        34920  +**
        34921  +**   * See also: assert_pager_state().
        34922  +*/
        34923  +#define PAGER_OPEN                  0
        34924  +#define PAGER_READER                1
        34925  +#define PAGER_WRITER_LOCKED         2
        34926  +#define PAGER_WRITER_CACHEMOD       3
        34927  +#define PAGER_WRITER_DBMOD          4
        34928  +#define PAGER_WRITER_FINISHED       5
        34929  +#define PAGER_ERROR                 6
        34930  +
        34931  +/*
        34932  +** The Pager.eLock variable is almost always set to one of the 
        34933  +** following locking-states, according to the lock currently held on
        34934  +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
        34935  +** This variable is kept up to date as locks are taken and released by
        34936  +** the pagerLockDb() and pagerUnlockDb() wrappers.
        34937  +**
        34938  +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
        34939  +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
        34940  +** the operation was successful. In these circumstances pagerLockDb() and
        34941  +** pagerUnlockDb() take a conservative approach - eLock is always updated
        34942  +** when unlocking the file, and only updated when locking the file if the
        34943  +** VFS call is successful. This way, the Pager.eLock variable may be set
        34944  +** to a less exclusive (lower) value than the lock that is actually held
        34945  +** at the system level, but it is never set to a more exclusive value.
        34946  +**
        34947  +** This is usually safe. If an xUnlock fails or appears to fail, there may 
        34948  +** be a few redundant xLock() calls or a lock may be held for longer than
        34949  +** required, but nothing really goes wrong.
        34950  +**
        34951  +** The exception is when the database file is unlocked as the pager moves
        34952  +** from ERROR to OPEN state. At this point there may be a hot-journal file 
        34953  +** in the file-system that needs to be rolled back (as part of a OPEN->SHARED
        34954  +** transition, by the same pager or any other). If the call to xUnlock()
        34955  +** fails at this point and the pager is left holding an EXCLUSIVE lock, this
        34956  +** can confuse the call to xCheckReservedLock() call made later as part
        34957  +** of hot-journal detection.
        34958  +**
        34959  +** xCheckReservedLock() is defined as returning true "if there is a RESERVED 
        34960  +** lock held by this process or any others". So xCheckReservedLock may 
        34961  +** return true because the caller itself is holding an EXCLUSIVE lock (but
        34962  +** doesn't know it because of a previous error in xUnlock). If this happens
        34963  +** a hot-journal may be mistaken for a journal being created by an active
        34964  +** transaction in another process, causing SQLite to read from the database
        34965  +** without rolling it back.
        34966  +**
        34967  +** To work around this, if a call to xUnlock() fails when unlocking the
        34968  +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
        34969  +** is only changed back to a real locking state after a successful call
        34970  +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
        34971  +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK 
        34972  +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
        34973  +** lock on the database file before attempting to roll it back. See function
        34974  +** PagerSharedLock() for more detail.
        34975  +**
        34976  +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
        34977  +** PAGER_OPEN state.
        34978  +*/
        34979  +#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
 34209  34980   
 34210  34981   /*
 34211  34982   ** A macro used for invoking the codec if there is one
 34212  34983   */
 34213  34984   #ifdef SQLITE_HAS_CODEC
 34214  34985   # define CODEC1(P,D,N,X,E) \
 34215  34986       if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
................................................................................
 34251  35022     Pgno iSubRec;                /* Index of first record in sub-journal */
 34252  35023   #ifndef SQLITE_OMIT_WAL
 34253  35024     u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
 34254  35025   #endif
 34255  35026   };
 34256  35027   
 34257  35028   /*
 34258         -** A open page cache is an instance of the following structure.
 34259         -**
 34260         -** errCode
 34261         -**
 34262         -**   Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
 34263         -**   or SQLITE_FULL. Once one of the first three errors occurs, it persists
 34264         -**   and is returned as the result of every major pager API call.  The
 34265         -**   SQLITE_FULL return code is slightly different. It persists only until the
 34266         -**   next successful rollback is performed on the pager cache. Also,
 34267         -**   SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
 34268         -**   APIs, they may still be used successfully.
 34269         -**
 34270         -** dbSizeValid, dbSize, dbOrigSize, dbFileSize
 34271         -**
 34272         -**   Managing the size of the database file in pages is a little complicated.
 34273         -**   The variable Pager.dbSize contains the number of pages that the database
 34274         -**   image currently contains. As the database image grows or shrinks this
 34275         -**   variable is updated. The variable Pager.dbFileSize contains the number
 34276         -**   of pages in the database file. This may be different from Pager.dbSize
 34277         -**   if some pages have been appended to the database image but not yet written
 34278         -**   out from the cache to the actual file on disk. Or if the image has been
 34279         -**   truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable
 34280         -**   contains the number of pages in the database image when the current
 34281         -**   transaction was opened. The contents of all three of these variables is
 34282         -**   only guaranteed to be correct if the boolean Pager.dbSizeValid is true.
 34283         -**
 34284         -**   TODO: Under what conditions is dbSizeValid set? Cleared?
        35029  +** A open page cache is an instance of struct Pager. A description of
        35030  +** some of the more important member variables follows:
        35031  +**
        35032  +** eState
        35033  +**
        35034  +**   The current 'state' of the pager object. See the comment and state
        35035  +**   diagram above for a description of the pager state.
        35036  +**
        35037  +** eLock
        35038  +**
        35039  +**   For a real on-disk database, the current lock held on the database file -
        35040  +**   NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
        35041  +**
        35042  +**   For a temporary or in-memory database (neither of which require any
        35043  +**   locks), this variable is always set to EXCLUSIVE_LOCK. Since such
        35044  +**   databases always have Pager.exclusiveMode==1, this tricks the pager
        35045  +**   logic into thinking that it already has all the locks it will ever
        35046  +**   need (and no reason to release them).
        35047  +**
        35048  +**   In some (obscure) circumstances, this variable may also be set to
        35049  +**   UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
        35050  +**   details.
 34285  35051   **
 34286  35052   ** changeCountDone
 34287  35053   **
 34288  35054   **   This boolean variable is used to make sure that the change-counter 
 34289  35055   **   (the 4-byte header field at byte offset 24 of the database file) is 
 34290  35056   **   not updated more often than necessary. 
 34291  35057   **
................................................................................
 34296  35062   **   The changeCountDone flag is inspected. If it is true, the work of
 34297  35063   **   updating the change-counter is omitted for the current transaction.
 34298  35064   **
 34299  35065   **   This mechanism means that when running in exclusive mode, a connection 
 34300  35066   **   need only update the change-counter once, for the first transaction
 34301  35067   **   committed.
 34302  35068   **
 34303         -** dbModified
 34304         -**
 34305         -**   The dbModified flag is set whenever a database page is dirtied.
 34306         -**   It is cleared at the end of each transaction.
 34307         -**
 34308         -**   It is used when committing or otherwise ending a transaction. If
 34309         -**   the dbModified flag is clear then less work has to be done.
 34310         -**
 34311         -** journalStarted
 34312         -**
 34313         -**   This flag is set during a write-transaction after the first 
 34314         -**   journal-header is written and synced to disk.
 34315         -**
 34316         -**   After this has happened, new pages appended to the database 
 34317         -**   do not need the PGHDR_NEED_SYNC flag set, as they do not need
 34318         -**   to wait for a journal sync before they can be written out to
 34319         -**   the database file (see function pager_write()).
 34320         -**   
 34321  35069   ** setMaster
 34322  35070   **
 34323  35071   **   When PagerCommitPhaseOne() is called to commit a transaction, it may
 34324  35072   **   (or may not) specify a master-journal name to be written into the 
 34325  35073   **   journal file before it is synced to disk.
 34326  35074   **
 34327  35075   **   Whether or not a journal file contains a master-journal pointer affects 
 34328  35076   **   the way in which the journal file is finalized after the transaction is 
 34329  35077   **   committed or rolled back when running in "journal_mode=PERSIST" mode.
 34330  35078   **   If a journal file does not contain a master-journal pointer, it is
 34331         -**   finalized by overwriting the first journal header with zeroes. If,
 34332         -**   on the other hand, it does contain a master-journal pointer, the
 34333         -**   journal file is finalized by truncating it to zero bytes, just as if
 34334         -**   the connection were running in "journal_mode=truncate" mode.
        35079  +**   finalized by overwriting the first journal header with zeroes. If
        35080  +**   it does contain a master-journal pointer the journal file is finalized 
        35081  +**   by truncating it to zero bytes, just as if the connection were 
        35082  +**   running in "journal_mode=truncate" mode.
 34335  35083   **
 34336  35084   **   Journal files that contain master journal pointers cannot be finalized
 34337  35085   **   simply by overwriting the first journal-header with zeroes, as the
 34338  35086   **   master journal pointer could interfere with hot-journal rollback of any
 34339  35087   **   subsequently interrupted transaction that reuses the journal file.
 34340  35088   **
 34341  35089   **   The flag is cleared as soon as the journal file is finalized (either
 34342  35090   **   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
 34343  35091   **   journal file from being successfully finalized, the setMaster flag
 34344         -**   is cleared anyway.
        35092  +**   is cleared anyway (and the pager will move to ERROR state).
 34345  35093   **
 34346  35094   ** doNotSpill, doNotSyncSpill
 34347  35095   **
 34348         -**   When enabled, cache spills are prohibited.  The doNotSpill variable
 34349         -**   inhibits all cache spill and doNotSyncSpill inhibits those spills that
 34350         -**   would require a journal sync.  The doNotSyncSpill is set and cleared 
 34351         -**   by sqlite3PagerWrite() in order to prevent a journal sync from happening 
 34352         -**   in between the journalling of two pages on the same sector.  The
 34353         -**   doNotSpill value set to prevent pagerStress() from trying to use
 34354         -**   the journal during a rollback.
        35096  +**   These two boolean variables control the behaviour of cache-spills
        35097  +**   (calls made by the pcache module to the pagerStress() routine to
        35098  +**   write cached data to the file-system in order to free up memory).
 34355  35099   **
 34356         -** needSync
 34357         -**
 34358         -**   TODO: It might be easier to set this variable in writeJournalHdr()
 34359         -**   and writeMasterJournal() only. Change its meaning to "unsynced data
 34360         -**   has been written to the journal".
        35100  +**   When doNotSpill is non-zero, writing to the database from pagerStress()
        35101  +**   is disabled altogether. This is done in a very obscure case that
        35102  +**   comes up during savepoint rollback that requires the pcache module
        35103  +**   to allocate a new page to prevent the journal file from being written
        35104  +**   while it is being traversed by code in pager_playback().
        35105  +** 
        35106  +**   If doNotSyncSpill is non-zero, writing to the database from pagerStress()
        35107  +**   is permitted, but syncing the journal file is not. This flag is set
        35108  +**   by sqlite3PagerWrite() when the file-system sector-size is larger than
        35109  +**   the database page-size in order to prevent a journal sync from happening 
        35110  +**   in between the journalling of two pages on the same sector. 
 34361  35111   **
 34362  35112   ** subjInMemory
 34363  35113   **
 34364  35114   **   This is a boolean variable. If true, then any required sub-journal
 34365  35115   **   is opened as an in-memory journal file. If false, then in-memory
 34366  35116   **   sub-journals are only used for in-memory pager files.
        35117  +**
        35118  +**   This variable is updated by the upper layer each time a new 
        35119  +**   write-transaction is opened.
        35120  +**
        35121  +** dbSize, dbOrigSize, dbFileSize
        35122  +**
        35123  +**   Variable dbSize is set to the number of pages in the database file.
        35124  +**   It is valid in PAGER_READER and higher states (all states except for
        35125  +**   OPEN and ERROR). 
        35126  +**
        35127  +**   dbSize is set based on the size of the database file, which may be 
        35128  +**   larger than the size of the database (the value stored at offset
        35129  +**   28 of the database header by the btree). If the size of the file
        35130  +**   is not an integer multiple of the page-size, the value stored in
        35131  +**   dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
        35132  +**   Except, any file that is greater than 0 bytes in size is considered
        35133  +**   to have at least one page. (i.e. a 1KB file with 2K page-size leads
        35134  +**   to dbSize==1).
        35135  +**
        35136  +**   During a write-transaction, if pages with page-numbers greater than
        35137  +**   dbSize are modified in the cache, dbSize is updated accordingly.
        35138  +**   Similarly, if the database is truncated using PagerTruncateImage(), 
        35139  +**   dbSize is updated.
        35140  +**
        35141  +**   Variables dbOrigSize and dbFileSize are valid in states 
        35142  +**   PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
        35143  +**   variable at the start of the transaction. It is used during rollback,
        35144  +**   and to determine whether or not pages need to be journalled before
        35145  +**   being modified.
        35146  +**
        35147  +**   Throughout a write-transaction, dbFileSize contains the size of
        35148  +**   the file on disk in pages. It is set to a copy of dbSize when the
        35149  +**   write-transaction is first opened, and updated when VFS calls are made
        35150  +**   to write or truncate the database file on disk. 
        35151  +**
        35152  +**   The only reason the dbFileSize variable is required is to suppress 
        35153  +**   unnecessary calls to xTruncate() after committing a transaction. If, 
        35154  +**   when a transaction is committed, the dbFileSize variable indicates 
        35155  +**   that the database file is larger than the database image (Pager.dbSize), 
        35156  +**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
        35157  +**   to measure the database file on disk, and then truncates it if required.
        35158  +**   dbFileSize is not used when rolling back a transaction. In this case
        35159  +**   pager_truncate() is called unconditionally (which means there may be
        35160  +**   a call to xFilesize() that is not strictly required). In either case,
        35161  +**   pager_truncate() may cause the file to become smaller or larger.
        35162  +**
        35163  +** dbHintSize
        35164  +**
        35165  +**   The dbHintSize variable is used to limit the number of calls made to
        35166  +**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
        35167  +**
        35168  +**   dbHintSize is set to a copy of the dbSize variable when a
        35169  +**   write-transaction is opened (at the same time as dbFileSize and
        35170  +**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
        35171  +**   dbHintSize is increased to the number of pages that correspond to the
        35172  +**   size-hint passed to the method call. See pager_write_pagelist() for 
        35173  +**   details.
        35174  +**
        35175  +** errCode
        35176  +**
        35177  +**   The Pager.errCode variable is only ever used in PAGER_ERROR state. It
        35178  +**   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
        35179  +**   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
        35180  +**   sub-codes.
 34367  35181   */
 34368  35182   struct Pager {
 34369  35183     sqlite3_vfs *pVfs;          /* OS functions to use for IO */
 34370  35184     u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
 34371         -  u8 journalMode;             /* On of the PAGER_JOURNALMODE_* values */
        35185  +  u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
 34372  35186     u8 useJournal;              /* Use a rollback journal on this file */
 34373  35187     u8 noReadlock;              /* Do not bother to obtain readlocks */
 34374  35188     u8 noSync;                  /* Do not sync the journal if true */
 34375  35189     u8 fullSync;                /* Do extra syncs of the journal for robustness */
 34376  35190     u8 sync_flags;              /* One of SYNC_NORMAL or SYNC_FULL */
 34377  35191     u8 tempFile;                /* zFilename is a temporary file */
 34378  35192     u8 readOnly;                /* True for a read-only database */
 34379  35193     u8 memDb;                   /* True to inhibit all file I/O */
 34380  35194   
 34381         -  /* The following block contains those class members that are dynamically
 34382         -  ** modified during normal operations. The other variables in this structure
 34383         -  ** are either constant throughout the lifetime of the pager, or else
 34384         -  ** used to store configuration parameters that affect the way the pager 
 34385         -  ** operates.
 34386         -  **
 34387         -  ** The 'state' variable is described in more detail along with the
 34388         -  ** descriptions of the values it may take - PAGER_UNLOCK etc. Many of the
 34389         -  ** other variables in this block are described in the comment directly 
 34390         -  ** above this class definition.
        35195  +  /**************************************************************************
        35196  +  ** The following block contains those class members that change during
        35197  +  ** routine opertion.  Class members not in this block are either fixed
        35198  +  ** when the pager is first created or else only change when there is a
        35199  +  ** significant mode change (such as changing the page_size, locking_mode,
        35200  +  ** or the journal_mode).  From another view, these class members describe
        35201  +  ** the "state" of the pager, while other class members describe the
        35202  +  ** "configuration" of the pager.
 34391  35203     */
 34392         -  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
 34393         -  u8 dbModified;              /* True if there are any changes to the Db */
 34394         -  u8 needSync;                /* True if an fsync() is needed on the journal */
 34395         -  u8 journalStarted;          /* True if header of journal is synced */
        35204  +  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
        35205  +  u8 eLock;                   /* Current lock held on database file */
 34396  35206     u8 changeCountDone;         /* Set after incrementing the change-counter */
 34397  35207     u8 setMaster;               /* True if a m-j name has been written to jrnl */
 34398  35208     u8 doNotSpill;              /* Do not spill the cache when non-zero */
 34399  35209     u8 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
 34400         -  u8 dbSizeValid;             /* Set when dbSize is correct */
 34401  35210     u8 subjInMemory;            /* True to use in-memory sub-journals */
 34402  35211     Pgno dbSize;                /* Number of pages in the database */
 34403  35212     Pgno dbOrigSize;            /* dbSize before the current transaction */
 34404  35213     Pgno dbFileSize;            /* Number of pages in the database file */
        35214  +  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
 34405  35215     int errCode;                /* One of several kinds of errors */
 34406  35216     int nRec;                   /* Pages journalled since last j-header written */
 34407  35217     u32 cksumInit;              /* Quasi-random value added to every checksum */
 34408  35218     u32 nSubRec;                /* Number of records written to sub-journal */
 34409  35219     Bitvec *pInJournal;         /* One bit for each page in the database file */
 34410  35220     sqlite3_file *fd;           /* File descriptor for database */
 34411  35221     sqlite3_file *jfd;          /* File descriptor for main journal */
 34412  35222     sqlite3_file *sjfd;         /* File descriptor for sub-journal */
 34413  35223     i64 journalOff;             /* Current write offset in the journal file */
 34414  35224     i64 journalHdr;             /* Byte offset to previous journal header */
 34415         -  i64 journalSizeLimit;       /* Size limit for persistent journal files */
        35225  +  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
 34416  35226     PagerSavepoint *aSavepoint; /* Array of active savepoints */
 34417  35227     int nSavepoint;             /* Number of elements in aSavepoint[] */
 34418  35228     char dbFileVers[16];        /* Changes whenever database file changes */
 34419         -  u32 sectorSize;             /* Assumed sector size during rollback */
        35229  +  /*
        35230  +  ** End of the routinely-changing class members
        35231  +  ***************************************************************************/
 34420  35232   
 34421  35233     u16 nExtra;                 /* Add this many bytes to each in-memory page */
 34422  35234     i16 nReserve;               /* Number of unused bytes at end of each page */
 34423  35235     u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
        35236  +  u32 sectorSize;             /* Assumed sector size during rollback */
 34424  35237     int pageSize;               /* Number of bytes in a page */
 34425  35238     Pgno mxPgno;                /* Maximum allowed size of the database */
        35239  +  i64 journalSizeLimit;       /* Size limit for persistent journal files */
 34426  35240     char *zFilename;            /* Name of the database file */
 34427  35241     char *zJournal;             /* Name of the journal file */
 34428  35242     int (*xBusyHandler)(void*); /* Function to call when busy */
 34429  35243     void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
 34430  35244   #ifdef SQLITE_TEST
 34431  35245     int nHit, nMiss;            /* Cache hits and missing */
 34432  35246     int nRead, nWrite;          /* Database pages read/written */
................................................................................
 34436  35250     void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
 34437  35251     void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
 34438  35252     void (*xCodecFree)(void*);             /* Destructor for the codec */
 34439  35253     void *pCodec;               /* First argument to xCodec... methods */
 34440  35254   #endif
 34441  35255     char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
 34442  35256     PCache *pPCache;            /* Pointer to page cache object */
 34443         -  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
 34444  35257   #ifndef SQLITE_OMIT_WAL
 34445  35258     Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
 34446  35259     char *zWal;                 /* File name for write-ahead log */
 34447  35260   #endif
 34448  35261   };
 34449  35262   
 34450  35263   /*
................................................................................
 34515  35328   #endif
 34516  35329   
 34517  35330   /*
 34518  35331   ** The maximum legal page number is (2^31 - 1).
 34519  35332   */
 34520  35333   #define PAGER_MAX_PGNO 2147483647
 34521  35334   
        35335  +/*
        35336  +** The argument to this macro is a file descriptor (type sqlite3_file*).
        35337  +** Return 0 if it is not open, or non-zero (but not 1) if it is.
        35338  +**
        35339  +** This is so that expressions can be written as:
        35340  +**
        35341  +**   if( isOpen(pPager->jfd) ){ ...
        35342  +**
        35343  +** instead of
        35344  +**
        35345  +**   if( pPager->jfd->pMethods ){ ...
        35346  +*/
        35347  +#define isOpen(pFd) ((pFd)->pMethods)
        35348  +
        35349  +/*
        35350  +** Return true if this pager uses a write-ahead log instead of the usual
        35351  +** rollback journal. Otherwise false.
        35352  +*/
        35353  +#ifndef SQLITE_OMIT_WAL
        35354  +static int pagerUseWal(Pager *pPager){
        35355  +  return (pPager->pWal!=0);
        35356  +}
        35357  +#else
        35358  +# define pagerUseWal(x) 0
        35359  +# define pagerRollbackWal(x) 0
        35360  +# define pagerWalFrames(v,w,x,y,z) 0
        35361  +# define pagerOpenWalIfPresent(z) SQLITE_OK
        35362  +# define pagerBeginReadTransaction(z) SQLITE_OK
        35363  +#endif
        35364  +
 34522  35365   #ifndef NDEBUG 
 34523  35366   /*
 34524  35367   ** Usage:
 34525  35368   **
 34526  35369   **   assert( assert_pager_state(pPager) );
 34527         -*/
 34528         -static int assert_pager_state(Pager *pPager){
 34529         -
 34530         -  /* A temp-file is always in PAGER_EXCLUSIVE or PAGER_SYNCED state. */
 34531         -  assert( pPager->tempFile==0 || pPager->state>=PAGER_EXCLUSIVE );
 34532         -
 34533         -  /* The changeCountDone flag is always set for temp-files */
 34534         -  assert( pPager->tempFile==0 || pPager->changeCountDone );
 34535         -
 34536         -  return 1;
        35370  +**
        35371  +** This function runs many asserts to try to find inconsistencies in
        35372  +** the internal state of the Pager object.
        35373  +*/
        35374  +static int assert_pager_state(Pager *p){
        35375  +  Pager *pPager = p;
        35376  +
        35377  +  /* State must be valid. */
        35378  +  assert( p->eState==PAGER_OPEN
        35379  +       || p->eState==PAGER_READER
        35380  +       || p->eState==PAGER_WRITER_LOCKED
        35381  +       || p->eState==PAGER_WRITER_CACHEMOD
        35382  +       || p->eState==PAGER_WRITER_DBMOD
        35383  +       || p->eState==PAGER_WRITER_FINISHED
        35384  +       || p->eState==PAGER_ERROR
        35385  +  );
        35386  +
        35387  +  /* Regardless of the current state, a temp-file connection always behaves
        35388  +  ** as if it has an exclusive lock on the database file. It never updates
        35389  +  ** the change-counter field, so the changeCountDone flag is always set.
        35390  +  */
        35391  +  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
        35392  +  assert( p->tempFile==0 || pPager->changeCountDone );
        35393  +
        35394  +  /* If the useJournal flag is clear, the journal-mode must be "OFF". 
        35395  +  ** And if the journal-mode is "OFF", the journal file must not be open.
        35396  +  */
        35397  +  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
        35398  +  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
        35399  +
        35400  +  /* Check that MEMDB implies noSync. And an in-memory journal. Since 
        35401  +  ** this means an in-memory pager performs no IO at all, it cannot encounter 
        35402  +  ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing 
        35403  +  ** a journal file. (although the in-memory journal implementation may 
        35404  +  ** return SQLITE_IOERR_NOMEM while the journal file is being written). It 
        35405  +  ** is therefore not possible for an in-memory pager to enter the ERROR 
        35406  +  ** state.
        35407  +  */
        35408  +  if( MEMDB ){
        35409  +    assert( p->noSync );
        35410  +    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
        35411  +         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
        35412  +    );
        35413  +    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
        35414  +    assert( pagerUseWal(p)==0 );
        35415  +  }
        35416  +
        35417  +  /* If changeCountDone is set, a RESERVED lock or greater must be held
        35418  +  ** on the file.
        35419  +  */
        35420  +  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
        35421  +  assert( p->eLock!=PENDING_LOCK );
        35422  +
        35423  +  switch( p->eState ){
        35424  +    case PAGER_OPEN:
        35425  +      assert( !MEMDB );
        35426  +      assert( pPager->errCode==SQLITE_OK );
        35427  +      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
        35428  +      break;
        35429  +
        35430  +    case PAGER_READER:
        35431  +      assert( pPager->errCode==SQLITE_OK );
        35432  +      assert( p->eLock!=UNKNOWN_LOCK );
        35433  +      assert( p->eLock>=SHARED_LOCK || p->noReadlock );
        35434  +      break;
        35435  +
        35436  +    case PAGER_WRITER_LOCKED:
        35437  +      assert( p->eLock!=UNKNOWN_LOCK );
        35438  +      assert( pPager->errCode==SQLITE_OK );
        35439  +      if( !pagerUseWal(pPager) ){
        35440  +        assert( p->eLock>=RESERVED_LOCK );
        35441  +      }
        35442  +      assert( pPager->dbSize==pPager->dbOrigSize );
        35443  +      assert( pPager->dbOrigSize==pPager->dbFileSize );
        35444  +      assert( pPager->dbOrigSize==pPager->dbHintSize );
        35445  +      assert( pPager->setMaster==0 );
        35446  +      break;
        35447  +
        35448  +    case PAGER_WRITER_CACHEMOD:
        35449  +      assert( p->eLock!=UNKNOWN_LOCK );
        35450  +      assert( pPager->errCode==SQLITE_OK );
        35451  +      if( !pagerUseWal(pPager) ){
        35452  +        /* It is possible that if journal_mode=wal here that neither the
        35453  +        ** journal file nor the WAL file are open. This happens during
        35454  +        ** a rollback transaction that switches from journal_mode=off
        35455  +        ** to journal_mode=wal.
        35456  +        */
        35457  +        assert( p->eLock>=RESERVED_LOCK );
        35458  +        assert( isOpen(p->jfd) 
        35459  +             || p->journalMode==PAGER_JOURNALMODE_OFF 
        35460  +             || p->journalMode==PAGER_JOURNALMODE_WAL 
        35461  +        );
        35462  +      }
        35463  +      assert( pPager->dbOrigSize==pPager->dbFileSize );
        35464  +      assert( pPager->dbOrigSize==pPager->dbHintSize );
        35465  +      break;
        35466  +
        35467  +    case PAGER_WRITER_DBMOD:
        35468  +      assert( p->eLock==EXCLUSIVE_LOCK );
        35469  +      assert( pPager->errCode==SQLITE_OK );
        35470  +      assert( !pagerUseWal(pPager) );
        35471  +      assert( p->eLock>=EXCLUSIVE_LOCK );
        35472  +      assert( isOpen(p->jfd) 
        35473  +           || p->journalMode==PAGER_JOURNALMODE_OFF 
        35474  +           || p->journalMode==PAGER_JOURNALMODE_WAL 
        35475  +      );
        35476  +      assert( pPager->dbOrigSize<=pPager->dbHintSize );
        35477  +      break;
        35478  +
        35479  +    case PAGER_WRITER_FINISHED:
        35480  +      assert( p->eLock==EXCLUSIVE_LOCK );
        35481  +      assert( pPager->errCode==SQLITE_OK );
        35482  +      assert( !pagerUseWal(pPager) );
        35483  +      assert( isOpen(p->jfd) 
        35484  +           || p->journalMode==PAGER_JOURNALMODE_OFF 
        35485  +           || p->journalMode==PAGER_JOURNALMODE_WAL 
        35486  +      );
        35487  +      break;
        35488  +
        35489  +    case PAGER_ERROR:
        35490  +      /* There must be at least one outstanding reference to the pager if
        35491  +      ** in ERROR state. Otherwise the pager should have already dropped
        35492  +      ** back to OPEN state.
        35493  +      */
        35494  +      assert( pPager->errCode!=SQLITE_OK );
        35495  +      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
        35496  +      break;
        35497  +  }
        35498  +
        35499  +  return 1;
        35500  +}
        35501  +
        35502  +/*
        35503  +** Return a pointer to a human readable string in a static buffer
        35504  +** containing the state of the Pager object passed as an argument. This
        35505  +** is intended to be used within debuggers. For example, as an alternative
        35506  +** to "print *pPager" in gdb:
        35507  +**
        35508  +** (gdb) printf "%s", print_pager_state(pPager)
        35509  +*/
        35510  +static char *print_pager_state(Pager *p){
        35511  +  static char zRet[1024];
        35512  +
        35513  +  sqlite3_snprintf(1024, zRet,
        35514  +      "Filename:      %s\n"
        35515  +      "State:         %s errCode=%d\n"
        35516  +      "Lock:          %s\n"
        35517  +      "Locking mode:  locking_mode=%s\n"
        35518  +      "Journal mode:  journal_mode=%s\n"
        35519  +      "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
        35520  +      "Journal:       journalOff=%lld journalHdr=%lld\n"
        35521  +      "Size:          dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
        35522  +      , p->zFilename
        35523  +      , p->eState==PAGER_OPEN            ? "OPEN" :
        35524  +        p->eState==PAGER_READER          ? "READER" :
        35525  +        p->eState==PAGER_WRITER_LOCKED   ? "WRITER_LOCKED" :
        35526  +        p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
        35527  +        p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
        35528  +        p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
        35529  +        p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
        35530  +      , (int)p->errCode
        35531  +      , p->eLock==NO_LOCK         ? "NO_LOCK" :
        35532  +        p->eLock==RESERVED_LOCK   ? "RESERVED" :
        35533  +        p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
        35534  +        p->eLock==SHARED_LOCK     ? "SHARED" :
        35535  +        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
        35536  +      , p->exclusiveMode ? "exclusive" : "normal"
        35537  +      , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
        35538  +        p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
        35539  +        p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
        35540  +        p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
        35541  +        p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
        35542  +        p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
        35543  +      , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
        35544  +      , p->journalOff, p->journalHdr
        35545  +      , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
        35546  +  );
        35547  +
        35548  +  return zRet;
 34537  35549   }
 34538  35550   #endif
 34539  35551   
 34540  35552   /*
 34541  35553   ** Return true if it is necessary to write page *pPg into the sub-journal.
 34542  35554   ** A page needs to be written into the sub-journal if there exists one
 34543  35555   ** or more open savepoints for which:
................................................................................
 34582  35594     return rc;
 34583  35595   }
 34584  35596   
 34585  35597   /*
 34586  35598   ** Write a 32-bit integer into a string buffer in big-endian byte order.
 34587  35599   */
 34588  35600   #define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
        35601  +
 34589  35602   
 34590  35603   /*
 34591  35604   ** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
 34592  35605   ** on success or an error code is something goes wrong.
 34593  35606   */
 34594  35607   static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
 34595  35608     char ac[4];
 34596  35609     put32bits(ac, val);
 34597  35610     return sqlite3OsWrite(fd, ac, 4, offset);
 34598  35611   }
 34599  35612   
 34600  35613   /*
 34601         -** The argument to this macro is a file descriptor (type sqlite3_file*).
 34602         -** Return 0 if it is not open, or non-zero (but not 1) if it is.
 34603         -**
 34604         -** This is so that expressions can be written as:
 34605         -**
 34606         -**   if( isOpen(pPager->jfd) ){ ...
 34607         -**
 34608         -** instead of
 34609         -**
 34610         -**   if( pPager->jfd->pMethods ){ ...
 34611         -*/
 34612         -#define isOpen(pFd) ((pFd)->pMethods)
 34613         -
 34614         -/*
 34615         -** If file pFd is open, call sqlite3OsUnlock() on it.
 34616         -*/
 34617         -static int osUnlock(sqlite3_file *pFd, int eLock){
 34618         -  if( !isOpen(pFd) ){
 34619         -    return SQLITE_OK;
 34620         -  }
 34621         -  return sqlite3OsUnlock(pFd, eLock);
        35614  +** Unlock the database file to level eLock, which must be either NO_LOCK
        35615  +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
        35616  +** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
        35617  +**
        35618  +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
        35619  +** called, do not modify it. See the comment above the #define of 
        35620  +** UNKNOWN_LOCK for an explanation of this.
        35621  +*/
        35622  +static int pagerUnlockDb(Pager *pPager, int eLock){
        35623  +  int rc = SQLITE_OK;
        35624  +
        35625  +  assert( !pPager->exclusiveMode );
        35626  +  assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
        35627  +  assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
        35628  +  if( isOpen(pPager->fd) ){
        35629  +    assert( pPager->eLock>=eLock );
        35630  +    rc = sqlite3OsUnlock(pPager->fd, eLock);
        35631  +    if( pPager->eLock!=UNKNOWN_LOCK ){
        35632  +      pPager->eLock = (u8)eLock;
        35633  +    }
        35634  +    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
        35635  +  }
        35636  +  return rc;
        35637  +}
        35638  +
        35639  +/*
        35640  +** Lock the database file to level eLock, which must be either SHARED_LOCK,
        35641  +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
        35642  +** Pager.eLock variable to the new locking state. 
        35643  +**
        35644  +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is 
        35645  +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. 
        35646  +** See the comment above the #define of UNKNOWN_LOCK for an explanation 
        35647  +** of this.
        35648  +*/
        35649  +static int pagerLockDb(Pager *pPager, int eLock){
        35650  +  int rc = SQLITE_OK;
        35651  +
        35652  +  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
        35653  +  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
        35654  +    rc = sqlite3OsLock(pPager->fd, eLock);
        35655  +    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
        35656  +      pPager->eLock = (u8)eLock;
        35657  +      IOTRACE(("LOCK %p %d\n", pPager, eLock))
        35658  +    }
        35659  +  }
        35660  +  return rc;
 34622  35661   }
 34623  35662   
 34624  35663   /*
 34625  35664   ** This function determines whether or not the atomic-write optimization
 34626  35665   ** can be used with this pager. The optimization can be used if:
 34627  35666   **
 34628  35667   **  (a) the value returned by OsDeviceCharacteristics() indicates that
................................................................................
 34690  35729   ** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
 34691  35730   ** is defined, and NDEBUG is not defined, an assert() statement checks
 34692  35731   ** that the page is either dirty or still matches the calculated page-hash.
 34693  35732   */
 34694  35733   #define CHECK_PAGE(x) checkPage(x)
 34695  35734   static void checkPage(PgHdr *pPg){
 34696  35735     Pager *pPager = pPg->pPager;
 34697         -  assert( !pPg->pageHash || pPager->errCode
 34698         -      || (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
        35736  +  assert( pPager->eState!=PAGER_ERROR );
        35737  +  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
 34699  35738   }
 34700  35739   
 34701  35740   #else
 34702  35741   #define pager_datahash(X,Y)  0
 34703  35742   #define pager_pagehash(X)  0
        35743  +#define pager_set_pagehash(X)
 34704  35744   #define CHECK_PAGE(x)
 34705  35745   #endif  /* SQLITE_CHECK_PAGES */
 34706  35746   
 34707  35747   /*
 34708  35748   ** When this is called the journal file for pager pPager must be open.
 34709  35749   ** This function attempts to read a master journal file name from the 
 34710  35750   ** end of the file and, if successful, copies it into memory supplied 
................................................................................
 34863  35903   ** - 4 bytes: Database page size.
 34864  35904   ** 
 34865  35905   ** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
 34866  35906   */
 34867  35907   static int writeJournalHdr(Pager *pPager){
 34868  35908     int rc = SQLITE_OK;                 /* Return code */
 34869  35909     char *zHeader = pPager->pTmpSpace;  /* Temporary space used to build header */
 34870         -  u32 nHeader = pPager->pageSize;     /* Size of buffer pointed to by zHeader */
        35910  +  u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
 34871  35911     u32 nWrite;                         /* Bytes of header sector written */
 34872  35912     int ii;                             /* Loop counter */
 34873  35913   
 34874  35914     assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
 34875  35915   
 34876  35916     if( nHeader>JOURNAL_HDR_SZ(pPager) ){
 34877  35917       nHeader = JOURNAL_HDR_SZ(pPager);
................................................................................
 34906  35946     **   * When the pager is in no-sync mode. Corruption can follow a
 34907  35947     **     power failure in this case anyway.
 34908  35948     **
 34909  35949     **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
 34910  35950     **     that garbage data is never appended to the journal file.
 34911  35951     */
 34912  35952     assert( isOpen(pPager->fd) || pPager->noSync );
 34913         -  if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
        35953  +  if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
 34914  35954      || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
 34915  35955     ){
 34916  35956       memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
 34917  35957       put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
 34918  35958     }else{
 34919  35959       memset(zHeader, 0, sizeof(aJournalMagic)+4);
 34920  35960     }
................................................................................
 35030  36070     ){
 35031  36071       return rc;
 35032  36072     }
 35033  36073   
 35034  36074     if( pPager->journalOff==0 ){
 35035  36075       u32 iPageSize;               /* Page-size field of journal header */
 35036  36076       u32 iSectorSize;             /* Sector-size field of journal header */
 35037         -    u16 iPageSize16;             /* Copy of iPageSize in 16-bit variable */
 35038  36077   
 35039  36078       /* Read the page-size and sector-size journal header fields. */
 35040  36079       if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
 35041  36080        || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
 35042  36081       ){
 35043  36082         return rc;
 35044  36083       }
        36084  +
        36085  +    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
        36086  +    ** journal header to zero. In this case, assume that the Pager.pageSize
        36087  +    ** variable is already set to the correct page size.
        36088  +    */
        36089  +    if( iPageSize==0 ){
        36090  +      iPageSize = pPager->pageSize;
        36091  +    }
 35045  36092   
 35046  36093       /* Check that the values read from the page-size and sector-size fields
 35047  36094       ** are within range. To be 'in range', both values need to be a power
 35048  36095       ** of two greater than or equal to 512 or 32, and not greater than their 
 35049  36096       ** respective compile time maximum limits.
 35050  36097       */
 35051  36098       if( iPageSize<512                  || iSectorSize<32
................................................................................
 35060  36107         return SQLITE_DONE;
 35061  36108       }
 35062  36109   
 35063  36110       /* Update the page-size to match the value read from the journal. 
 35064  36111       ** Use a testcase() macro to make sure that malloc failure within 
 35065  36112       ** PagerSetPagesize() is tested.
 35066  36113       */
 35067         -    iPageSize16 = (u16)iPageSize;
 35068         -    rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1);
        36114  +    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
 35069  36115       testcase( rc!=SQLITE_OK );
 35070         -    assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize );
 35071  36116   
 35072  36117       /* Update the assumed sector-size to match the value used by 
 35073  36118       ** the process that created this journal. If this journal was
 35074  36119       ** created by a process other than this one, then this routine
 35075  36120       ** is being called from within pager_playback(). The local value
 35076  36121       ** of Pager.sectorSize is restored at the end of that routine.
 35077  36122       */
................................................................................
 35106  36151     int rc;                          /* Return code */
 35107  36152     int nMaster;                     /* Length of string zMaster */
 35108  36153     i64 iHdrOff;                     /* Offset of header in journal file */
 35109  36154     i64 jrnlSize;                    /* Size of journal file on disk */
 35110  36155     u32 cksum = 0;                   /* Checksum of string zMaster */
 35111  36156   
 35112  36157     assert( pPager->setMaster==0 );
        36158  +  assert( !pagerUseWal(pPager) );
        36159  +
 35113  36160     if( !zMaster 
 35114  36161      || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
 35115  36162      || pPager->journalMode==PAGER_JOURNALMODE_OFF 
 35116  36163     ){
 35117  36164       return SQLITE_OK;
 35118  36165     }
 35119  36166     pPager->setMaster = 1;
................................................................................
 35142  36189      || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
 35143  36190      || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
 35144  36191      || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
 35145  36192     ){
 35146  36193       return rc;
 35147  36194     }
 35148  36195     pPager->journalOff += (nMaster+20);
 35149         -  pPager->needSync = !pPager->noSync;
 35150  36196   
 35151  36197     /* If the pager is in peristent-journal mode, then the physical 
 35152  36198     ** journal-file may extend past the end of the master-journal name
 35153  36199     ** and 8 bytes of magic data just written to the file. This is 
 35154  36200     ** dangerous because the code to rollback a hot-journal file
 35155  36201     ** will not be able to find the master-journal name to determine 
 35156  36202     ** whether or not the journal is hot. 
................................................................................
 35178  36224     ** fail, since no attempt to allocate dynamic memory will be made.
 35179  36225     */
 35180  36226     (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
 35181  36227     return p;
 35182  36228   }
 35183  36229   
 35184  36230   /*
 35185         -** Unless the pager is in error-state, discard all in-memory pages. If
 35186         -** the pager is in error-state, then this call is a no-op.
 35187         -**
 35188         -** TODO: Why can we not reset the pager while in error state?
        36231  +** Discard the entire contents of the in-memory page-cache.
 35189  36232   */
 35190  36233   static void pager_reset(Pager *pPager){
 35191         -  if( SQLITE_OK==pPager->errCode ){
 35192         -    sqlite3BackupRestart(pPager->pBackup);
 35193         -    sqlite3PcacheClear(pPager->pPCache);
 35194         -    pPager->dbSizeValid = 0;
 35195         -  }
        36234  +  sqlite3BackupRestart(pPager->pBackup);
        36235  +  sqlite3PcacheClear(pPager->pPCache);
 35196  36236   }
 35197  36237   
 35198  36238   /*
 35199  36239   ** Free all structures in the Pager.aSavepoint[] array and set both
 35200  36240   ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
 35201  36241   ** if it is open and the pager is not in exclusive mode.
 35202  36242   */
................................................................................
 35231  36271         assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
 35232  36272       }
 35233  36273     }
 35234  36274     return rc;
 35235  36275   }
 35236  36276   
 35237  36277   /*
 35238         -** Return true if this pager uses a write-ahead log instead of the usual
 35239         -** rollback journal. Otherwise false.
 35240         -*/
 35241         -#ifndef SQLITE_OMIT_WAL
 35242         -static int pagerUseWal(Pager *pPager){
 35243         -  return (pPager->pWal!=0);
 35244         -}
 35245         -#else
 35246         -# define pagerUseWal(x) 0
 35247         -# define pagerRollbackWal(x) 0
 35248         -# define pagerWalFrames(v,w,x,y,z) 0
 35249         -# define pagerOpenWalIfPresent(z) SQLITE_OK
 35250         -# define pagerBeginReadTransaction(z) SQLITE_OK
 35251         -#endif
 35252         -
 35253         -/*
 35254         -** Unlock the database file. This function is a no-op if the pager
 35255         -** is in exclusive mode.
        36278  +** This function is a no-op if the pager is in exclusive mode and not
        36279  +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
        36280  +** state.
 35256  36281   **
 35257         -** If the pager is currently in error state, discard the contents of 
 35258         -** the cache and reset the Pager structure internal state. If there is
 35259         -** an open journal-file, then the next time a shared-lock is obtained
 35260         -** on the pager file (by this or any other process), it will be
 35261         -** treated as a hot-journal and rolled back.
        36282  +** If the pager is not in exclusive-access mode, the database file is
        36283  +** completely unlocked. If the file is unlocked and the file-system does
        36284  +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
        36285  +** closed (if it is open).
        36286  +**
        36287  +** If the pager is in ERROR state when this function is called, the 
        36288  +** contents of the pager cache are discarded before switching back to 
        36289  +** the OPEN state. Regardless of whether the pager is in exclusive-mode
        36290  +** or not, any journal file left in the file-system will be treated
        36291  +** as a hot-journal and rolled back the next time a read-transaction
        36292  +** is opened (by this or by any other connection).
 35262  36293   */
 35263  36294   static void pager_unlock(Pager *pPager){
 35264         -  if( !pPager->exclusiveMode ){
 35265         -    int rc = SQLITE_OK;          /* Return code */
        36295  +
        36296  +  assert( pPager->eState==PAGER_READER 
        36297  +       || pPager->eState==PAGER_OPEN 
        36298  +       || pPager->eState==PAGER_ERROR 
        36299  +  );
        36300  +
        36301  +  sqlite3BitvecDestroy(pPager->pInJournal);
        36302  +  pPager->pInJournal = 0;
        36303  +  releaseAllSavepoints(pPager);
        36304  +
        36305  +  if( pagerUseWal(pPager) ){
        36306  +    assert( !isOpen(pPager->jfd) );
        36307  +    sqlite3WalEndReadTransaction(pPager->pWal);
        36308  +    pPager->eState = PAGER_OPEN;
        36309  +  }else if( !pPager->exclusiveMode ){
        36310  +    int rc;                       /* Error code returned by pagerUnlockDb() */
 35266  36311       int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
 35267  36312   
 35268  36313       /* If the operating system support deletion of open files, then
 35269  36314       ** close the journal file when dropping the database lock.  Otherwise
 35270  36315       ** another connection with journal_mode=delete might delete the file
 35271  36316       ** out from under us.
 35272  36317       */
................................................................................
 35278  36323       assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
 35279  36324       if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
 35280  36325        || 1!=(pPager->journalMode & 5)
 35281  36326       ){
 35282  36327         sqlite3OsClose(pPager->jfd);
 35283  36328       }
 35284  36329   
 35285         -    sqlite3BitvecDestroy(pPager->pInJournal);
 35286         -    pPager->pInJournal = 0;
 35287         -    releaseAllSavepoints(pPager);
 35288         -
 35289         -    /* If the file is unlocked, somebody else might change it. The
 35290         -    ** values stored in Pager.dbSize etc. might become invalid if
 35291         -    ** this happens.  One can argue that this doesn't need to be cleared
 35292         -    ** until the change-counter check fails in PagerSharedLock().
 35293         -    ** Clearing the page size cache here is being conservative.
 35294         -    */
 35295         -    pPager->dbSizeValid = 0;
 35296         -
 35297         -    if( pagerUseWal(pPager) ){
 35298         -      sqlite3WalEndReadTransaction(pPager->pWal);
 35299         -    }else{
 35300         -      rc = osUnlock(pPager->fd, NO_LOCK);
 35301         -    }
 35302         -    if( rc ){
 35303         -      pPager->errCode = rc;
 35304         -    }
 35305         -    IOTRACE(("UNLOCK %p\n", pPager))
 35306         -
 35307         -    /* If Pager.errCode is set, the contents of the pager cache cannot be
 35308         -    ** trusted. Now that the pager file is unlocked, the contents of the
 35309         -    ** cache can be discarded and the error code safely cleared.
 35310         -    */
 35311         -    if( pPager->errCode ){
 35312         -      if( rc==SQLITE_OK ){
 35313         -        pPager->errCode = SQLITE_OK;
 35314         -      }
 35315         -      pager_reset(pPager);
 35316         -    }
 35317         -
        36330  +    /* If the pager is in the ERROR state and the call to unlock the database
        36331  +    ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
        36332  +    ** above the #define for UNKNOWN_LOCK for an explanation of why this
        36333  +    ** is necessary.
        36334  +    */
        36335  +    rc = pagerUnlockDb(pPager, NO_LOCK);
        36336  +    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
        36337  +      pPager->eLock = UNKNOWN_LOCK;
        36338  +    }
        36339  +
        36340  +    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
        36341  +    ** without clearing the error code. This is intentional - the error
        36342  +    ** code is cleared and the cache reset in the block below.
        36343  +    */
        36344  +    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
 35318  36345       pPager->changeCountDone = 0;
 35319         -    pPager->state = PAGER_UNLOCK;
 35320         -    pPager->dbModified = 0;
 35321         -  }
 35322         -}
 35323         -
 35324         -/*
 35325         -** This function should be called when an IOERR, CORRUPT or FULL error
 35326         -** may have occurred. The first argument is a pointer to the pager 
 35327         -** structure, the second the error-code about to be returned by a pager 
 35328         -** API function. The value returned is a copy of the second argument 
 35329         -** to this function. 
 35330         -**
 35331         -** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
 35332         -** the error becomes persistent. Until the persistent error is cleared,
 35333         -** subsequent API calls on this Pager will immediately return the same 
 35334         -** error code.
 35335         -**
 35336         -** A persistent error indicates that the contents of the pager-cache 
        36346  +    pPager->eState = PAGER_OPEN;
        36347  +  }
        36348  +
        36349  +  /* If Pager.errCode is set, the contents of the pager cache cannot be
        36350  +  ** trusted. Now that there are no outstanding references to the pager,
        36351  +  ** it can safely move back to PAGER_OPEN state. This happens in both
        36352  +  ** normal and exclusive-locking mode.
        36353  +  */
        36354  +  if( pPager->errCode ){
        36355  +    assert( !MEMDB );
        36356  +    pager_reset(pPager);
        36357  +    pPager->changeCountDone = pPager->tempFile;
        36358  +    pPager->eState = PAGER_OPEN;
        36359  +    pPager->errCode = SQLITE_OK;
        36360  +  }
        36361  +
        36362  +  pPager->journalOff = 0;
        36363  +  pPager->journalHdr = 0;
        36364  +  pPager->setMaster = 0;
        36365  +}
        36366  +
        36367  +/*
        36368  +** This function is called whenever an IOERR or FULL error that requires
        36369  +** the pager to transition into the ERROR state may ahve occurred.
        36370  +** The first argument is a pointer to the pager structure, the second 
        36371  +** the error-code about to be returned by a pager API function. The 
        36372  +** value returned is a copy of the second argument to this function. 
        36373  +**
        36374  +** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
        36375  +** IOERR sub-codes, the pager enters the ERROR state and the error code
        36376  +** is stored in Pager.errCode. While the pager remains in the ERROR state,
        36377  +** all major API calls on the Pager will immediately return Pager.errCode.
        36378  +**
        36379  +** The ERROR state indicates that the contents of the pager-cache 
 35337  36380   ** cannot be trusted. This state can be cleared by completely discarding 
 35338  36381   ** the contents of the pager-cache. If a transaction was active when
 35339  36382   ** the persistent error occurred, then the rollback journal may need
 35340  36383   ** to be replayed to restore the contents of the database file (as if
 35341  36384   ** it were a hot-journal).
 35342  36385   */
 35343  36386   static int pager_error(Pager *pPager, int rc){
................................................................................
 35346  36389     assert(
 35347  36390          pPager->errCode==SQLITE_FULL ||
 35348  36391          pPager->errCode==SQLITE_OK ||
 35349  36392          (pPager->errCode & 0xff)==SQLITE_IOERR
 35350  36393     );
 35351  36394     if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
 35352  36395       pPager->errCode = rc;
        36396  +    pPager->eState = PAGER_ERROR;
 35353  36397     }
 35354  36398     return rc;
 35355  36399   }
 35356  36400   
 35357         -/*
 35358         -** Execute a rollback if a transaction is active and unlock the 
 35359         -** database file. 
 35360         -**
 35361         -** If the pager has already entered the error state, do not attempt 
 35362         -** the rollback at this time. Instead, pager_unlock() is called. The
 35363         -** call to pager_unlock() will discard all in-memory pages, unlock
 35364         -** the database file and clear the error state. If this means that
 35365         -** there is a hot-journal left in the file-system, the next connection
 35366         -** to obtain a shared lock on the pager (which may be this one) will
 35367         -** roll it back.
 35368         -**
 35369         -** If the pager has not already entered the error state, but an IO or
 35370         -** malloc error occurs during a rollback, then this will itself cause 
 35371         -** the pager to enter the error state. Which will be cleared by the
 35372         -** call to pager_unlock(), as described above.
 35373         -*/
 35374         -static void pagerUnlockAndRollback(Pager *pPager){
 35375         -  if( pPager->errCode==SQLITE_OK && pPager->state>=PAGER_RESERVED ){
 35376         -    sqlite3BeginBenignMalloc();
 35377         -    sqlite3PagerRollback(pPager);
 35378         -    sqlite3EndBenignMalloc();
 35379         -  }
 35380         -  pager_unlock(pPager);
 35381         -}
 35382         -
 35383  36401   /*
 35384  36402   ** This routine ends a transaction. A transaction is usually ended by 
 35385  36403   ** either a COMMIT or a ROLLBACK operation. This routine may be called 
 35386  36404   ** after rollback of a hot-journal, or if an error occurs while opening
 35387  36405   ** the journal file or writing the very first journal-header of a
 35388  36406   ** database transaction.
 35389  36407   ** 
 35390         -** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this
 35391         -** routine is called, it is a no-op (returns SQLITE_OK).
        36408  +** This routine is never called in PAGER_ERROR state. If it is called
        36409  +** in PAGER_NONE or PAGER_SHARED state and the lock held is less
        36410  +** exclusive than a RESERVED lock, it is a no-op.
 35392  36411   **
 35393  36412   ** Otherwise, any active savepoints are released.
 35394  36413   **
 35395  36414   ** If the journal file is open, then it is "finalized". Once a journal 
 35396  36415   ** file has been finalized it is not possible to use it to roll back a 
 35397  36416   ** transaction. Nor will it be considered to be a hot-journal by this
 35398  36417   ** or any other database connection. Exactly how a journal is finalized
................................................................................
 35415  36434   **     The journal file is closed and deleted using sqlite3OsDelete().
 35416  36435   **
 35417  36436   **     If the pager is running in exclusive mode, this method of finalizing
 35418  36437   **     the journal file is never used. Instead, if the journalMode is
 35419  36438   **     DELETE and the pager is in exclusive mode, the method described under
 35420  36439   **     journalMode==PERSIST is used instead.
 35421  36440   **
 35422         -** After the journal is finalized, if running in non-exclusive mode, the
 35423         -** pager moves to PAGER_SHARED state (and downgrades the lock on the
 35424         -** database file accordingly).
 35425         -**
 35426         -** If the pager is running in exclusive mode and is in PAGER_SYNCED state,
 35427         -** it moves to PAGER_EXCLUSIVE. No locks are downgraded when running in
 35428         -** exclusive mode.
        36441  +** After the journal is finalized, the pager moves to PAGER_READER state.
        36442  +** If running in non-exclusive rollback mode, the lock on the file is 
        36443  +** downgraded to a SHARED_LOCK.
 35429  36444   **
 35430  36445   ** SQLITE_OK is returned if no error occurs. If an error occurs during
 35431  36446   ** any of the IO operations to finalize the journal file or unlock the
 35432  36447   ** database then the IO error code is returned to the user. If the 
 35433  36448   ** operation to finalize the journal file fails, then the code still
 35434  36449   ** tries to unlock the database file if not in exclusive mode. If the
 35435  36450   ** unlock operation fails as well, then the first error code related
................................................................................
 35436  36451   ** to the first error encountered (the journal finalization one) is
 35437  36452   ** returned.
 35438  36453   */
 35439  36454   static int pager_end_transaction(Pager *pPager, int hasMaster){
 35440  36455     int rc = SQLITE_OK;      /* Error code from journal finalization operation */
 35441  36456     int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */
 35442  36457   
 35443         -  if( pPager->state<PAGER_RESERVED ){
        36458  +  /* Do nothing if the pager does not have an open write transaction
        36459  +  ** or at least a RESERVED lock. This function may be called when there
        36460  +  ** is no write-transaction active but a RESERVED or greater lock is
        36461  +  ** held under two circumstances:
        36462  +  **
        36463  +  **   1. After a successful hot-journal rollback, it is called with
        36464  +  **      eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
        36465  +  **
        36466  +  **   2. If a connection with locking_mode=exclusive holding an EXCLUSIVE 
        36467  +  **      lock switches back to locking_mode=normal and then executes a
        36468  +  **      read-transaction, this function is called with eState==PAGER_READER 
        36469  +  **      and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
        36470  +  */
        36471  +  assert( assert_pager_state(pPager) );
        36472  +  assert( pPager->eState!=PAGER_ERROR );
        36473  +  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
 35444  36474       return SQLITE_OK;
 35445  36475     }
        36476  +
 35446  36477     releaseAllSavepoints(pPager);
 35447         -
 35448  36478     assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
 35449  36479     if( isOpen(pPager->jfd) ){
 35450  36480       assert( !pagerUseWal(pPager) );
 35451  36481   
 35452  36482       /* Finalize the journal file. */
 35453  36483       if( sqlite3IsMemJournal(pPager->jfd) ){
 35454  36484         assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
................................................................................
 35456  36486       }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
 35457  36487         if( pPager->journalOff==0 ){
 35458  36488           rc = SQLITE_OK;
 35459  36489         }else{
 35460  36490           rc = sqlite3OsTruncate(pPager->jfd, 0);
 35461  36491         }
 35462  36492         pPager->journalOff = 0;
 35463         -      pPager->journalStarted = 0;
 35464  36493       }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
 35465  36494         || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
 35466  36495       ){
 35467  36496         rc = zeroJournalHdr(pPager, hasMaster);
 35468         -      pager_error(pPager, rc);
 35469  36497         pPager->journalOff = 0;
 35470         -      pPager->journalStarted = 0;
 35471  36498       }else{
 35472  36499         /* This branch may be executed with Pager.journalMode==MEMORY if
 35473  36500         ** a hot-journal was just rolled back. In this case the journal
 35474  36501         ** file should be closed and deleted. If this connection writes to
 35475  36502         ** the database file, it will do so using an in-memory journal. 
 35476  36503         */
 35477  36504         assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
................................................................................
 35479  36506              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
 35480  36507         );
 35481  36508         sqlite3OsClose(pPager->jfd);
 35482  36509         if( !pPager->tempFile ){
 35483  36510           rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
 35484  36511         }
 35485  36512       }
        36513  +  }
 35486  36514   
 35487  36515   #ifdef SQLITE_CHECK_PAGES
 35488         -    sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
        36516  +  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
        36517  +  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
        36518  +    PgHdr *p = pager_lookup(pPager, 1);
        36519  +    if( p ){
        36520  +      p->pageHash = 0;
        36521  +      sqlite3PagerUnref(p);
        36522  +    }
        36523  +  }
 35489  36524   #endif
 35490         -  }
        36525  +
 35491  36526     sqlite3BitvecDestroy(pPager->pInJournal);
 35492  36527     pPager->pInJournal = 0;
 35493  36528     pPager->nRec = 0;
 35494  36529     sqlite3PcacheCleanAll(pPager->pPCache);
        36530  +  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
 35495  36531   
 35496  36532     if( pagerUseWal(pPager) ){
        36533  +    /* Drop the WAL write-lock, if any. Also, if the connection was in 
        36534  +    ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE 
        36535  +    ** lock held on the database file.
        36536  +    */
 35497  36537       rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
 35498  36538       assert( rc2==SQLITE_OK );
 35499         -    pPager->state = PAGER_SHARED;
 35500         -
 35501         -    /* If the connection was in locking_mode=exclusive mode but is no longer,
 35502         -    ** drop the EXCLUSIVE lock held on the database file.
 35503         -    */
 35504         -    if( !pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, 0) ){
 35505         -      rc2 = osUnlock(pPager->fd, SHARED_LOCK);
 35506         -    }
 35507         -  }else if( !pPager->exclusiveMode ){
 35508         -    rc2 = osUnlock(pPager->fd, SHARED_LOCK);
 35509         -    pPager->state = PAGER_SHARED;
        36539  +  }
        36540  +  if( !pPager->exclusiveMode 
        36541  +   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
        36542  +  ){
        36543  +    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
 35510  36544       pPager->changeCountDone = 0;
 35511         -  }else if( pPager->state==PAGER_SYNCED ){
 35512         -    pPager->state = PAGER_EXCLUSIVE;
 35513  36545     }
        36546  +  pPager->eState = PAGER_READER;
 35514  36547     pPager->setMaster = 0;
 35515         -  pPager->needSync = 0;
 35516         -  pPager->dbModified = 0;
 35517         -
 35518         -  /* TODO: Is this optimal? Why is the db size invalidated here 
 35519         -  ** when the database file is not unlocked? */
 35520         -  pPager->dbOrigSize = 0;
 35521         -  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
 35522         -  if( !MEMDB ){
 35523         -    pPager->dbSizeValid = 0;
 35524         -  }
 35525  36548   
 35526  36549     return (rc==SQLITE_OK?rc2:rc);
 35527  36550   }
        36551  +
        36552  +/*
        36553  +** Execute a rollback if a transaction is active and unlock the 
        36554  +** database file. 
        36555  +**
        36556  +** If the pager has already entered the ERROR state, do not attempt 
        36557  +** the rollback at this time. Instead, pager_unlock() is called. The
        36558  +** call to pager_unlock() will discard all in-memory pages, unlock
        36559  +** the database file and move the pager back to OPEN state. If this 
        36560  +** means that there is a hot-journal left in the file-system, the next 
        36561  +** connection to obtain a shared lock on the pager (which may be this one) 
        36562  +** will roll it back.
        36563  +**
        36564  +** If the pager has not already entered the ERROR state, but an IO or
        36565  +** malloc error occurs during a rollback, then this will itself cause 
        36566  +** the pager to enter the ERROR state. Which will be cleared by the
        36567  +** call to pager_unlock(), as described above.
        36568  +*/
        36569  +static void pagerUnlockAndRollback(Pager *pPager){
        36570  +  if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
        36571  +    assert( assert_pager_state(pPager) );
        36572  +    if( pPager->eState>=PAGER_WRITER_LOCKED ){
        36573  +      sqlite3BeginBenignMalloc();
        36574  +      sqlite3PagerRollback(pPager);
        36575  +      sqlite3EndBenignMalloc();
        36576  +    }else if( !pPager->exclusiveMode ){
        36577  +      assert( pPager->eState==PAGER_READER );
        36578  +      pager_end_transaction(pPager, 0);
        36579  +    }
        36580  +  }
        36581  +  pager_unlock(pPager);
        36582  +}
 35528  36583   
 35529  36584   /*
 35530  36585   ** Parameter aData must point to a buffer of pPager->pageSize bytes
 35531  36586   ** of data. Compute and return a checksum based ont the contents of the 
 35532  36587   ** page of data and the current value of pPager->cksumInit.
 35533  36588   **
 35534  36589   ** This is not a real checksum. It is really just the sum of the 
................................................................................
 35572  36627   
 35573  36628   /*
 35574  36629   ** Read a single page from either the journal file (if isMainJrnl==1) or
 35575  36630   ** from the sub-journal (if isMainJrnl==0) and playback that page.
 35576  36631   ** The page begins at offset *pOffset into the file. The *pOffset
 35577  36632   ** value is increased to the start of the next page in the journal.
 35578  36633   **
 35579         -** The isMainJrnl flag is true if this is the main rollback journal and
 35580         -** false for the statement journal.  The main rollback journal uses
 35581         -** checksums - the statement journal does not.
        36634  +** The main rollback journal uses checksums - the statement journal does 
        36635  +** not.
 35582  36636   **
 35583  36637   ** If the page number of the page record read from the (sub-)journal file
 35584  36638   ** is greater than the current value of Pager.dbSize, then playback is
 35585  36639   ** skipped and SQLITE_OK is returned.
 35586  36640   **
 35587  36641   ** If pDone is not NULL, then it is a record of pages that have already
 35588  36642   ** been played back.  If the page at *pOffset has already been played back
................................................................................
 35627  36681     assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
 35628  36682     assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
 35629  36683     assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */
 35630  36684   
 35631  36685     aData = pPager->pTmpSpace;
 35632  36686     assert( aData );         /* Temp storage must have already been allocated */
 35633  36687     assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
        36688  +
        36689  +  /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction 
        36690  +  ** or savepoint rollback done at the request of the caller) or this is
        36691  +  ** a hot-journal rollback. If it is a hot-journal rollback, the pager
        36692  +  ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
        36693  +  ** only reads from the main journal, not the sub-journal.
        36694  +  */
        36695  +  assert( pPager->eState>=PAGER_WRITER_CACHEMOD
        36696  +       || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
        36697  +  );
        36698  +  assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
 35634  36699   
 35635  36700     /* Read the page number and page data from the journal or sub-journal
 35636  36701     ** file. Return an error code to the caller if an IO error occurs.
 35637  36702     */
 35638  36703     jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
 35639  36704     rc = read32bits(jfd, *pOffset, &pgno);
 35640  36705     if( rc!=SQLITE_OK ) return rc;
................................................................................
 35664  36729   
 35665  36730     /* If this page has already been played by before during the current
 35666  36731     ** rollback, then don't bother to play it back again.
 35667  36732     */
 35668  36733     if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
 35669  36734       return rc;
 35670  36735     }
 35671         -  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
 35672  36736   
 35673  36737     /* When playing back page 1, restore the nReserve setting
 35674  36738     */
 35675  36739     if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
 35676  36740       pPager->nReserve = ((u8*)aData)[20];
 35677  36741       pagerReportSize(pPager);
 35678  36742     }
 35679  36743   
 35680         -  /* If the pager is in RESERVED state, then there must be a copy of this
        36744  +  /* If the pager is in CACHEMOD state, then there must be a copy of this
 35681  36745     ** page in the pager cache. In this case just update the pager cache,
 35682  36746     ** not the database file. The page is left marked dirty in this case.
 35683  36747     **
 35684  36748     ** An exception to the above rule: If the database is in no-sync mode
 35685  36749     ** and a page is moved during an incremental vacuum then the page may
 35686  36750     ** not be in the pager cache. Later: if a malloc() or IO error occurs
 35687  36751     ** during a Movepage() call, then the page may not be in the cache
 35688  36752     ** either. So the condition described in the above paragraph is not
 35689  36753     ** assert()able.
 35690  36754     **
 35691         -  ** If in EXCLUSIVE state, then we update the pager cache if it exists
 35692         -  ** and the main file. The page is then marked not dirty.
        36755  +  ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
        36756  +  ** pager cache if it exists and the main file. The page is then marked 
        36757  +  ** not dirty. Since this code is only executed in PAGER_OPEN state for
        36758  +  ** a hot-journal rollback, it is guaranteed that the page-cache is empty
        36759  +  ** if the pager is in OPEN state.
 35693  36760     **
 35694  36761     ** Ticket #1171:  The statement journal might contain page content that is
 35695  36762     ** different from the page content at the start of the transaction.
 35696  36763     ** This occurs when a page is changed prior to the start of a statement
 35697  36764     ** then changed again within the statement.  When rolling back such a
 35698  36765     ** statement we must not write to the original database unless we know
 35699  36766     ** for certain that original page contents are synced into the main rollback
................................................................................
 35711  36778     */
 35712  36779     if( pagerUseWal(pPager) ){
 35713  36780       pPg = 0;
 35714  36781     }else{
 35715  36782       pPg = pager_lookup(pPager, pgno);
 35716  36783     }
 35717  36784     assert( pPg || !MEMDB );
        36785  +  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
 35718  36786     PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
 35719  36787              PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
 35720  36788              (isMainJrnl?"main-journal":"sub-journal")
 35721  36789     ));
 35722  36790     if( isMainJrnl ){
 35723  36791       isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
 35724  36792     }else{
 35725  36793       isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
 35726  36794     }
 35727         -  if( (pPager->state>=PAGER_EXCLUSIVE)
 35728         -   && isOpen(pPager->fd)
        36795  +  if( isOpen(pPager->fd)
        36796  +   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
 35729  36797      && isSynced
 35730  36798     ){
 35731  36799       i64 ofst = (pgno-1)*(i64)pPager->pageSize;
 35732  36800       testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
 35733  36801       assert( !pagerUseWal(pPager) );
 35734  36802       rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
 35735  36803       if( pgno>pPager->dbFileSize ){
................................................................................
 35797  36865         ** be written out into the database file before its journal file
 35798  36866         ** segment is synced. If a crash occurs during or following this,
 35799  36867         ** database corruption may ensue.
 35800  36868         */
 35801  36869         assert( !pagerUseWal(pPager) );
 35802  36870         sqlite3PcacheMakeClean(pPg);
 35803  36871       }
 35804         -#ifdef SQLITE_CHECK_PAGES
 35805         -    pPg->pageHash = pager_pagehash(pPg);
 35806         -#endif
        36872  +    pager_set_pagehash(pPg);
        36873  +
 35807  36874       /* If this was page 1, then restore the value of Pager.dbFileVers.
 35808  36875       ** Do this before any decoding. */
 35809  36876       if( pgno==1 ){
 35810  36877         memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
 35811  36878       }
 35812  36879   
 35813  36880       /* Decode the page just read from disk */
................................................................................
 35951  37018   
 35952  37019   
 35953  37020   /*
 35954  37021   ** This function is used to change the actual size of the database 
 35955  37022   ** file in the file-system. This only happens when committing a transaction,
 35956  37023   ** or rolling back a transaction (including rolling back a hot-journal).
 35957  37024   **
 35958         -** If the main database file is not open, or an exclusive lock is not
 35959         -** held, this function is a no-op. Otherwise, the size of the file is
 35960         -** changed to nPage pages (nPage*pPager->pageSize bytes). If the file
 35961         -** on disk is currently larger than nPage pages, then use the VFS
        37025  +** If the main database file is not open, or the pager is not in either
        37026  +** DBMOD or OPEN state, this function is a no-op. Otherwise, the size 
        37027  +** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). 
        37028  +** If the file on disk is currently larger than nPage pages, then use the VFS
 35962  37029   ** xTruncate() method to truncate it.
 35963  37030   **
 35964  37031   ** Or, it might might be the case that the file on disk is smaller than 
 35965  37032   ** nPage pages. Some operating system implementations can get confused if 
 35966  37033   ** you try to truncate a file to some size that is larger than it 
 35967  37034   ** currently is, so detect this case and write a single zero byte to 
 35968  37035   ** the end of the new file instead.
 35969  37036   **
 35970  37037   ** If successful, return SQLITE_OK. If an IO error occurs while modifying
 35971  37038   ** the database file, return the error code to the caller.
 35972  37039   */
 35973  37040   static int pager_truncate(Pager *pPager, Pgno nPage){
 35974  37041     int rc = SQLITE_OK;
 35975         -  if( pPager->state>=PAGER_EXCLUSIVE && isOpen(pPager->fd) ){
        37042  +  assert( pPager->eState!=PAGER_ERROR );
        37043  +  assert( pPager->eState!=PAGER_READER );
        37044  +  
        37045  +  if( isOpen(pPager->fd) 
        37046  +   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) 
        37047  +  ){
 35976  37048       i64 currentSize, newSize;
        37049  +    assert( pPager->eLock==EXCLUSIVE_LOCK );
 35977  37050       /* TODO: Is it safe to use Pager.dbFileSize here? */
 35978  37051       rc = sqlite3OsFileSize(pPager->fd, &currentSize);
 35979  37052       newSize = pPager->pageSize*(i64)nPage;
 35980  37053       if( rc==SQLITE_OK && currentSize!=newSize ){
 35981  37054         if( currentSize>newSize ){
 35982  37055           rc = sqlite3OsTruncate(pPager->fd, newSize);
 35983  37056         }else{
................................................................................
 36093  37166     int needPagerReset;      /* True to reset page prior to first page rollback */
 36094  37167   
 36095  37168     /* Figure out how many records are in the journal.  Abort early if
 36096  37169     ** the journal is empty.
 36097  37170     */
 36098  37171     assert( isOpen(pPager->jfd) );
 36099  37172     rc = sqlite3OsFileSize(pPager->jfd, &szJ);
 36100         -  if( rc!=SQLITE_OK || szJ==0 ){
        37173  +  if( rc!=SQLITE_OK ){
 36101  37174       goto end_playback;
 36102  37175     }
 36103  37176   
 36104  37177     /* Read the master journal name from the journal, if it is present.
 36105  37178     ** If a master journal file name is specified, but the file is not
 36106  37179     ** present on disk, then the journal is not hot and does not need to be
 36107  37180     ** played back.
................................................................................
 36127  37200     /* This loop terminates either when a readJournalHdr() or 
 36128  37201     ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
 36129  37202     ** occurs. 
 36130  37203     */
 36131  37204     while( 1 ){
 36132  37205       /* Read the next journal header from the journal file.  If there are
 36133  37206       ** not enough bytes left in the journal file for a complete header, or
 36134         -    ** it is corrupted, then a process must of failed while writing it.
        37207  +    ** it is corrupted, then a process must have failed while writing it.
 36135  37208       ** This indicates nothing more needs to be rolled back.
 36136  37209       */
 36137  37210       rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
 36138  37211       if( rc!=SQLITE_OK ){ 
 36139  37212         if( rc==SQLITE_DONE ){
 36140  37213           rc = SQLITE_OK;
 36141  37214         }
................................................................................
 36241  37314     pPager->changeCountDone = pPager->tempFile;
 36242  37315   
 36243  37316     if( rc==SQLITE_OK ){
 36244  37317       zMaster = pPager->pTmpSpace;
 36245  37318       rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
 36246  37319       testcase( rc!=SQLITE_OK );
 36247  37320     }
 36248         -  if( rc==SQLITE_OK && pPager->noSync==0 && pPager->state>=PAGER_EXCLUSIVE ){
 36249         -    rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
 36250         -  }
 36251         -  if( rc==SQLITE_OK && pPager->noSync==0 && pPager->state>=PAGER_EXCLUSIVE ){
        37321  +  if( rc==SQLITE_OK && !pPager->noSync 
        37322  +   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
        37323  +  ){
 36252  37324       rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
 36253  37325     }
 36254  37326     if( rc==SQLITE_OK ){
 36255  37327       rc = pager_end_transaction(pPager, zMaster[0]!='\0');
 36256  37328       testcase( rc!=SQLITE_OK );
 36257  37329     }
 36258  37330     if( rc==SQLITE_OK && zMaster[0] && res ){
................................................................................
 36286  37358   static int readDbPage(PgHdr *pPg){
 36287  37359     Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
 36288  37360     Pgno pgno = pPg->pgno;       /* Page number to read */
 36289  37361     int rc = SQLITE_OK;          /* Return code */
 36290  37362     int isInWal = 0;             /* True if page is in log file */
 36291  37363     int pgsz = pPager->pageSize; /* Number of bytes to read */
 36292  37364   
 36293         -  assert( pPager->state>=PAGER_SHARED && !MEMDB );
        37365  +  assert( pPager->eState>=PAGER_READER && !MEMDB );
 36294  37366     assert( isOpen(pPager->fd) );
 36295  37367   
 36296  37368     if( NEVER(!isOpen(pPager->fd)) ){
 36297  37369       assert( pPager->tempFile );
 36298  37370       memset(pPg->pData, 0, pPager->pageSize);
 36299  37371       return SQLITE_OK;
 36300  37372     }
................................................................................
 36433  37505     );
 36434  37506     if( rc==SQLITE_OK && pPager->pBackup ){
 36435  37507       PgHdr *p;
 36436  37508       for(p=pList; p; p=p->pDirty){
 36437  37509         sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
 36438  37510       }
 36439  37511     }
        37512  +
        37513  +#ifdef SQLITE_CHECK_PAGES
        37514  +  {
        37515  +    PgHdr *p;
        37516  +    for(p=pList; p; p=p->pDirty) pager_set_pagehash(p);
        37517  +  }
        37518  +#endif
        37519  +
 36440  37520     return rc;
 36441  37521   }
 36442  37522   
 36443  37523   /*
 36444  37524   ** Begin a read transaction on the WAL.
 36445  37525   **
 36446  37526   ** This routine used to be called "pagerOpenSnapshot()" because it essentially
................................................................................
 36449  37529   ** other writers or checkpointers.
 36450  37530   */
 36451  37531   static int pagerBeginReadTransaction(Pager *pPager){
 36452  37532     int rc;                         /* Return code */
 36453  37533     int changed = 0;                /* True if cache must be reset */
 36454  37534   
 36455  37535     assert( pagerUseWal(pPager) );
        37536  +  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
 36456  37537   
 36457  37538     /* sqlite3WalEndReadTransaction() was not called for the previous
 36458  37539     ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
 36459  37540     ** are in locking_mode=NORMAL and EndRead() was previously called,
 36460  37541     ** the duplicate call is harmless.
 36461  37542     */
 36462  37543     sqlite3WalEndReadTransaction(pPager->pWal);
 36463  37544   
 36464  37545     rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
 36465         -  if( rc==SQLITE_OK ){
 36466         -    int dummy;
 36467         -    if( changed ){
 36468         -      pager_reset(pPager);
 36469         -      assert( pPager->errCode || pPager->dbSizeValid==0 );
 36470         -    }
 36471         -    rc = sqlite3PagerPagecount(pPager, &dummy);
 36472         -  }
 36473         -  pPager->state = PAGER_SHARED;
 36474         -
 36475         -  return rc;
 36476         -}
 36477         -
        37546  +  if( rc!=SQLITE_OK || changed ){
        37547  +    pager_reset(pPager);
        37548  +  }
        37549  +
        37550  +  return rc;
        37551  +}
        37552  +#endif
        37553  +
        37554  +/*
        37555  +** This function is called as part of the transition from PAGER_OPEN
        37556  +** to PAGER_READER state to determine the size of the database file
        37557  +** in pages (assuming the page size currently stored in Pager.pageSize).
        37558  +**
        37559  +** If no error occurs, SQLITE_OK is returned and the size of the database
        37560  +** in pages is stored in *pnPage. Otherwise, an error code (perhaps
        37561  +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
        37562  +*/
        37563  +static int pagerPagecount(Pager *pPager, Pgno *pnPage){
        37564  +  Pgno nPage;                     /* Value to return via *pnPage */
        37565  +
        37566  +  /* Query the WAL sub-system for the database size. The WalDbsize()
        37567  +  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
        37568  +  ** if the database size is not available. The database size is not
        37569  +  ** available from the WAL sub-system if the log file is empty or
        37570  +  ** contains no valid committed transactions.
        37571  +  */
        37572  +  assert( pPager->eState==PAGER_OPEN );
        37573  +  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
        37574  +  nPage = sqlite3WalDbsize(pPager->pWal);
        37575  +
        37576  +  /* If the database size was not available from the WAL sub-system,
        37577  +  ** determine it based on the size of the database file. If the size
        37578  +  ** of the database file is not an integer multiple of the page-size,
        37579  +  ** round down to the nearest page. Except, any file larger than 0
        37580  +  ** bytes in size is considered to contain at least one page.
        37581  +  */
        37582  +  if( nPage==0 ){
        37583  +    i64 n = 0;                    /* Size of db file in bytes */
        37584  +    assert( isOpen(pPager->fd) || pPager->tempFile );
        37585  +    if( isOpen(pPager->fd) ){
        37586  +      int rc = sqlite3OsFileSize(pPager->fd, &n);
        37587  +      if( rc!=SQLITE_OK ){
        37588  +        return rc;
        37589  +      }
        37590  +    }
        37591  +    nPage = (Pgno)(n / pPager->pageSize);
        37592  +    if( nPage==0 && n>0 ){
        37593  +      nPage = 1;
        37594  +    }
        37595  +  }
        37596  +
        37597  +  /* If the current number of pages in the file is greater than the
        37598  +  ** configured maximum pager number, increase the allowed limit so
        37599  +  ** that the file can be read.
        37600  +  */
        37601  +  if( nPage>pPager->mxPgno ){
        37602  +    pPager->mxPgno = (Pgno)nPage;
        37603  +  }
        37604  +
        37605  +  *pnPage = nPage;
        37606  +  return SQLITE_OK;
        37607  +}
        37608  +
        37609  +#ifndef SQLITE_OMIT_WAL
 36478  37610   /*
 36479  37611   ** Check if the *-wal file that corresponds to the database opened by pPager
 36480  37612   ** exists if the database is not empy, or verify that the *-wal file does
 36481  37613   ** not exist (by deleting it) if the database file is empty.
 36482  37614   **
 36483  37615   ** If the database is not empty and the *-wal file exists, open the pager
 36484  37616   ** in WAL mode.  If the database is empty or if no *-wal file exists and
 36485  37617   ** if no error occurs, make sure Pager.journalMode is not set to
 36486  37618   ** PAGER_JOURNALMODE_WAL.
 36487  37619   **
 36488  37620   ** Return SQLITE_OK or an error code.
 36489  37621   **
 36490         -** If the WAL file is opened, also open a snapshot (read transaction).
 36491         -**
 36492  37622   ** The caller must hold a SHARED lock on the database file to call this
 36493  37623   ** function. Because an EXCLUSIVE lock on the db file is required to delete 
 36494  37624   ** a WAL on a none-empty database, this ensures there is no race condition 
 36495  37625   ** between the xAccess() below and an xDelete() being executed by some 
 36496  37626   ** other connection.
 36497  37627   */
 36498  37628   static int pagerOpenWalIfPresent(Pager *pPager){
 36499  37629     int rc = SQLITE_OK;
        37630  +  assert( pPager->eState==PAGER_OPEN );
        37631  +  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
        37632  +
 36500  37633     if( !pPager->tempFile ){
 36501  37634       int isWal;                    /* True if WAL file exists */
 36502         -    int nPage;                    /* Size of the database file */
 36503         -    assert( pPager->state>=SHARED_LOCK );
 36504         -    rc = sqlite3PagerPagecount(pPager, &nPage);
        37635  +    Pgno nPage;                   /* Size of the database file */
        37636  +
        37637  +    rc = pagerPagecount(pPager, &nPage);
 36505  37638       if( rc ) return rc;
 36506  37639       if( nPage==0 ){
 36507  37640         rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
 36508  37641         isWal = 0;
 36509  37642       }else{
 36510  37643         rc = sqlite3OsAccess(
 36511  37644             pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
 36512  37645         );
 36513  37646       }
 36514  37647       if( rc==SQLITE_OK ){
 36515  37648         if( isWal ){
 36516         -        pager_reset(pPager);
        37649  +        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
 36517  37650           rc = sqlite3PagerOpenWal(pPager, 0);
 36518         -        if( rc==SQLITE_OK ){
 36519         -          rc = pagerBeginReadTransaction(pPager);
 36520         -        }
 36521  37651         }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
 36522  37652           pPager->journalMode = PAGER_JOURNALMODE_DELETE;
 36523  37653         }
 36524  37654       }
 36525  37655     }
 36526  37656     return rc;
 36527  37657   }
................................................................................
 36565  37695   */
 36566  37696   static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
 36567  37697     i64 szJ;                 /* Effective size of the main journal */
 36568  37698     i64 iHdrOff;             /* End of first segment of main-journal records */
 36569  37699     int rc = SQLITE_OK;      /* Return code */
 36570  37700     Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
 36571  37701   
 36572         -  assert( pPager->state>=PAGER_SHARED );
        37702  +  assert( pPager->eState!=PAGER_ERROR );
        37703  +  assert( pPager->eState>=PAGER_WRITER_LOCKED );
 36573  37704   
 36574  37705     /* Allocate a bitvec to use to store the set of pages rolled back */
 36575  37706     if( pSavepoint ){
 36576  37707       pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
 36577  37708       if( !pDone ){
 36578  37709         return SQLITE_NOMEM;
 36579  37710       }
................................................................................
 36704  37835   ** and FULL=3.
 36705  37836   */
 36706  37837   #ifndef SQLITE_OMIT_PAGER_PRAGMAS
 36707  37838   SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
 36708  37839     pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
 36709  37840     pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
 36710  37841     pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
 36711         -  if( pPager->noSync ) pPager->needSync = 0;
 36712  37842   }
 36713  37843   #endif
 36714  37844   
 36715  37845   /*
 36716  37846   ** The following global variable is incremented whenever the library
 36717  37847   ** attempts to open a temporary file.  This information is used for
 36718  37848   ** testing and analysis only.  
................................................................................
 36786  37916   
 36787  37917   /*
 36788  37918   ** Change the page size used by the Pager object. The new page size 
 36789  37919   ** is passed in *pPageSize.
 36790  37920   **
 36791  37921   ** If the pager is in the error state when this function is called, it
 36792  37922   ** is a no-op. The value returned is the error state error code (i.e. 
 36793         -** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL).
        37923  +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
 36794  37924   **
 36795  37925   ** Otherwise, if all of the following are true:
 36796  37926   **
 36797  37927   **   * the new page size (value of *pPageSize) is valid (a power 
 36798  37928   **     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
 36799  37929   **
 36800  37930   **   * there are no outstanding page references, and
................................................................................
 36810  37940   ** In all other cases, SQLITE_OK is returned.
 36811  37941   **
 36812  37942   ** If the page size is not changed, either because one of the enumerated
 36813  37943   ** conditions above is not true, the pager was in error state when this
 36814  37944   ** function was called, or because the memory allocation attempt failed, 
 36815  37945   ** then *pPageSize is set to the old, retained page size before returning.
 36816  37946   */
 36817         -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){
 36818         -  int rc = pPager->errCode;
 36819         -
 36820         -  if( rc==SQLITE_OK ){
 36821         -    u16 pageSize = *pPageSize;
 36822         -    assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
 36823         -    if( (pPager->memDb==0 || pPager->dbSize==0)
 36824         -     && sqlite3PcacheRefCount(pPager->pPCache)==0 
 36825         -     && pageSize && pageSize!=pPager->pageSize 
 36826         -    ){
 36827         -      char *pNew = (char *)sqlite3PageMalloc(pageSize);
 36828         -      if( !pNew ){
 36829         -        rc = SQLITE_NOMEM;
 36830         -      }else{
 36831         -        pager_reset(pPager);
 36832         -        pPager->pageSize = pageSize;
 36833         -        sqlite3PageFree(pPager->pTmpSpace);
 36834         -        pPager->pTmpSpace = pNew;
 36835         -        sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
 36836         -      }
 36837         -    }
 36838         -    *pPageSize = (u16)pPager->pageSize;
        37947  +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
        37948  +  int rc = SQLITE_OK;
        37949  +
        37950  +  /* It is not possible to do a full assert_pager_state() here, as this
        37951  +  ** function may be called from within PagerOpen(), before the state
        37952  +  ** of the Pager object is internally consistent.
        37953  +  **
        37954  +  ** At one point this function returned an error if the pager was in 
        37955  +  ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
        37956  +  ** there is at least one outstanding page reference, this function
        37957  +  ** is a no-op for that case anyhow.
        37958  +  */
        37959  +
        37960  +  u32 pageSize = *pPageSize;
        37961  +  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
        37962  +  if( (pPager->memDb==0 || pPager->dbSize==0)
        37963  +   && sqlite3PcacheRefCount(pPager->pPCache)==0 
        37964  +   && pageSize && pageSize!=(u32)pPager->pageSize 
        37965  +  ){
        37966  +    char *pNew = NULL;             /* New temp space */
        37967  +    i64 nByte = 0;
        37968  +
        37969  +    if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
        37970  +      rc = sqlite3OsFileSize(pPager->fd, &nByte);
        37971  +    }
        37972  +    if( rc==SQLITE_OK ){
        37973  +      pNew = (char *)sqlite3PageMalloc(pageSize);
        37974  +      if( !pNew ) rc = SQLITE_NOMEM;
        37975  +    }
        37976  +
        37977  +    if( rc==SQLITE_OK ){
        37978  +      pager_reset(pPager);
        37979  +      pPager->dbSize = (Pgno)(nByte/pageSize);
        37980  +      pPager->pageSize = pageSize;
        37981  +      sqlite3PageFree(pPager->pTmpSpace);
        37982  +      pPager->pTmpSpace = pNew;
        37983  +      sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
        37984  +    }
        37985  +  }
        37986  +
        37987  +  *pPageSize = pPager->pageSize;
        37988  +  if( rc==SQLITE_OK ){
 36839  37989       if( nReserve<0 ) nReserve = pPager->nReserve;
 36840  37990       assert( nReserve>=0 && nReserve<1000 );
 36841  37991       pPager->nReserve = (i16)nReserve;
 36842  37992       pagerReportSize(pPager);
 36843  37993     }
 36844  37994     return rc;
 36845  37995   }
................................................................................
 36860  38010   ** Attempt to set the maximum database page count if mxPage is positive. 
 36861  38011   ** Make no changes if mxPage is zero or negative.  And never reduce the
 36862  38012   ** maximum page count below the current size of the database.
 36863  38013   **
 36864  38014   ** Regardless of mxPage, return the current maximum page count.
 36865  38015   */
 36866  38016   SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
 36867         -  int nPage;
 36868  38017     if( mxPage>0 ){
 36869  38018       pPager->mxPgno = mxPage;
 36870  38019     }
 36871         -  if( pPager->state!=PAGER_UNLOCK ){
 36872         -    sqlite3PagerPagecount(pPager, &nPage);
 36873         -    assert( (int)pPager->mxPgno>=nPage );
        38020  +  if( pPager->eState!=PAGER_OPEN && pPager->mxPgno<pPager->dbSize ){
        38021  +    pPager->mxPgno = pPager->dbSize;
 36874  38022     }
 36875  38023     return pPager->mxPgno;
 36876  38024   }
 36877  38025   
 36878  38026   /*
 36879  38027   ** The following set of routines are used to disable the simulated
 36880  38028   ** I/O error mechanism.  These routines are used to avoid simulated
................................................................................
 36931  38079         rc = SQLITE_OK;
 36932  38080       }
 36933  38081     }
 36934  38082     return rc;
 36935  38083   }
 36936  38084   
 36937  38085   /*
 36938         -** Return the total number of pages in the database file associated 
 36939         -** with pPager. Normally, this is calculated as (<db file size>/<page-size>).
        38086  +** This function may only be called when a read-transaction is open on
        38087  +** the pager. It returns the total number of pages in the database.
        38088  +**
 36940  38089   ** However, if the file is between 1 and <page-size> bytes in size, then 
 36941  38090   ** this is considered a 1 page file.
 36942         -**
 36943         -** If the pager is in error state when this function is called, then the
 36944         -** error state error code is returned and *pnPage left unchanged. Or,
 36945         -** if the file system has to be queried for the size of the file and
 36946         -** the query attempt returns an IO error, the IO error code is returned
 36947         -** and *pnPage is left unchanged.
 36948         -**
 36949         -** Otherwise, if everything is successful, then SQLITE_OK is returned
 36950         -** and *pnPage is set to the number of pages in the database.
 36951  38091   */
 36952         -SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){
 36953         -  Pgno nPage = 0;           /* Value to return via *pnPage */
 36954         -
 36955         -  /* Determine the number of pages in the file. Store this in nPage. */
 36956         -  if( pPager->dbSizeValid ){
 36957         -    nPage = pPager->dbSize;
 36958         -  }else{
 36959         -    int rc;                 /* Error returned by OsFileSize() */
 36960         -    i64 n = 0;              /* File size in bytes returned by OsFileSize() */
 36961         -
 36962         -    if( pagerUseWal(pPager) && pPager->state!=PAGER_UNLOCK ){
 36963         -      sqlite3WalDbsize(pPager->pWal, &nPage);
 36964         -    }
 36965         -
 36966         -    if( nPage==0 ){
 36967         -      assert( isOpen(pPager->fd) || pPager->tempFile );
 36968         -      if( isOpen(pPager->fd) ){
 36969         -        if( SQLITE_OK!=(rc = sqlite3OsFileSize(pPager->fd, &n)) ){
 36970         -          pager_error(pPager, rc);
 36971         -          return rc;
 36972         -        }
 36973         -      }
 36974         -      if( n>0 && n<pPager->pageSize ){
 36975         -        nPage = 1;
 36976         -      }else{
 36977         -        nPage = (Pgno)(n / pPager->pageSize);
 36978         -      }
 36979         -    }
 36980         -    if( pPager->state!=PAGER_UNLOCK ){
 36981         -      pPager->dbSize = nPage;
 36982         -      pPager->dbFileSize = nPage;
 36983         -      pPager->dbSizeValid = 1;
 36984         -    }
 36985         -  }
 36986         -
 36987         -  /* If the current number of pages in the file is greater than the 
 36988         -  ** configured maximum pager number, increase the allowed limit so
 36989         -  ** that the file can be read.
 36990         -  */
 36991         -  if( nPage>pPager->mxPgno ){
 36992         -    pPager->mxPgno = (Pgno)nPage;
 36993         -  }
 36994         -
 36995         -  /* Set the output variable and return SQLITE_OK */
 36996         -  *pnPage = nPage;
 36997         -  return SQLITE_OK;
        38092  +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
        38093  +  assert( pPager->eState>=PAGER_READER );
        38094  +  assert( pPager->eState!=PAGER_WRITER_FINISHED );
        38095  +  *pnPage = (int)pPager->dbSize;
 36998  38096   }
 36999  38097   
 37000  38098   
 37001  38099   /*
 37002  38100   ** Try to obtain a lock of type locktype on the database file. If
 37003  38101   ** a similar or greater lock is already held, this function is a no-op
 37004  38102   ** (returning SQLITE_OK immediately).
................................................................................
 37011  38109   ** Return SQLITE_OK on success and an error code if we cannot obtain
 37012  38110   ** the lock. If the lock is obtained successfully, set the Pager.state 
 37013  38111   ** variable to locktype before returning.
 37014  38112   */
 37015  38113   static int pager_wait_on_lock(Pager *pPager, int locktype){
 37016  38114     int rc;                              /* Return code */
 37017  38115   
 37018         -  /* The OS lock values must be the same as the Pager lock values */
 37019         -  assert( PAGER_SHARED==SHARED_LOCK );
 37020         -  assert( PAGER_RESERVED==RESERVED_LOCK );
 37021         -  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
 37022         -
 37023         -  /* If the file is currently unlocked then the size must be unknown. It
 37024         -  ** must not have been modified at this point.
 37025         -  */
 37026         -  assert( pPager->state>=PAGER_SHARED || pPager->dbSizeValid==0 );
 37027         -  assert( pPager->state>=PAGER_SHARED || pPager->dbModified==0 );
 37028         -
 37029  38116     /* Check that this is either a no-op (because the requested lock is 
 37030  38117     ** already held, or one of the transistions that the busy-handler
 37031  38118     ** may be invoked during, according to the comment above
 37032  38119     ** sqlite3PagerSetBusyhandler().
 37033  38120     */
 37034         -  assert( (pPager->state>=locktype)
 37035         -       || (pPager->state==PAGER_UNLOCK && locktype==PAGER_SHARED)
 37036         -       || (pPager->state==PAGER_RESERVED && locktype==PAGER_EXCLUSIVE)
        38121  +  assert( (pPager->eLock>=locktype)
        38122  +       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
        38123  +       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
 37037  38124     );
 37038  38125   
 37039         -  if( pPager->state>=locktype ){
 37040         -    rc = SQLITE_OK;
 37041         -  }else{
 37042         -    do {
 37043         -      rc = sqlite3OsLock(pPager->fd, locktype);
 37044         -    }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
 37045         -    if( rc==SQLITE_OK ){
 37046         -      pPager->state = (u8)locktype;
 37047         -      IOTRACE(("LOCK %p %d\n", pPager, locktype))
 37048         -    }
 37049         -  }
        38126  +  do {
        38127  +    rc = pagerLockDb(pPager, locktype);
        38128  +  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
 37050  38129     return rc;
 37051  38130   }
 37052  38131   
 37053  38132   /*
 37054  38133   ** Function assertTruncateConstraint(pPager) checks that one of the 
 37055  38134   ** following is true for all dirty pages currently in the page-cache:
 37056  38135   **
................................................................................
 37087  38166   /*
 37088  38167   ** Truncate the in-memory database file image to nPage pages. This 
 37089  38168   ** function does not actually modify the database file on disk. It 
 37090  38169   ** just sets the internal state of the pager object so that the 
 37091  38170   ** truncation will be done when the current transaction is committed.
 37092  38171   */
 37093  38172   SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
 37094         -  assert( pPager->dbSizeValid );
 37095  38173     assert( pPager->dbSize>=nPage );
 37096         -  assert( pPager->state>=PAGER_RESERVED );
        38174  +  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
 37097  38175     pPager->dbSize = nPage;
 37098  38176     assertTruncateConstraint(pPager);
 37099  38177   }
 37100  38178   
 37101  38179   
 37102  38180   /*
 37103  38181   ** This function is called before attempting a hot-journal rollback. It
................................................................................
 37139  38217   ** to the caller.
 37140  38218   */
 37141  38219   SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
 37142  38220     u8 *pTmp = (u8 *)pPager->pTmpSpace;
 37143  38221   
 37144  38222     disable_simulated_io_errors();
 37145  38223     sqlite3BeginBenignMalloc();
 37146         -  pPager->errCode = 0;
        38224  +  /* pPager->errCode = 0; */
 37147  38225     pPager->exclusiveMode = 0;
 37148  38226   #ifndef SQLITE_OMIT_WAL
 37149  38227     sqlite3WalClose(pPager->pWal,
 37150  38228       (pPager->noSync ? 0 : pPager->sync_flags), 
 37151  38229       pPager->pageSize, pTmp
 37152  38230     );
 37153  38231     pPager->pWal = 0;
 37154  38232   #endif
 37155  38233     pager_reset(pPager);
 37156  38234     if( MEMDB ){
 37157  38235       pager_unlock(pPager);
 37158  38236     }else{
 37159         -    /* Set Pager.journalHdr to -1 for the benefit of the pager_playback() 
 37160         -    ** call which may be made from within pagerUnlockAndRollback(). If it
 37161         -    ** is not -1, then the unsynced portion of an open journal file may
 37162         -    ** be played back into the database. If a power failure occurs while
 37163         -    ** this is happening, the database may become corrupt.
        38237  +    /* If it is open, sync the journal file before calling UnlockAndRollback.
        38238  +    ** If this is not done, then an unsynced portion of the open journal 
        38239  +    ** file may be played back into the database. If a power failure occurs 
        38240  +    ** while this is happening, the database could become corrupt.
        38241  +    **
        38242  +    ** If an error occurs while trying to sync the journal, shift the pager
        38243  +    ** into the ERROR state. This causes UnlockAndRollback to unlock the
        38244  +    ** database and close the journal file without attempting to roll it
        38245  +    ** back or finalize it. The next database user will have to do hot-journal
        38246  +    ** rollback before accessing the database file.
 37164  38247       */
 37165  38248       if( isOpen(pPager->jfd) ){
 37166         -      pPager->errCode = pagerSyncHotJournal(pPager);
        38249  +      pager_error(pPager, pagerSyncHotJournal(pPager));
 37167  38250       }
 37168  38251       pagerUnlockAndRollback(pPager);
 37169  38252     }
 37170  38253     sqlite3EndBenignMalloc();
 37171  38254     enable_simulated_io_errors();
 37172  38255     PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
 37173  38256     IOTRACE(("CLOSE %p\n", pPager))
................................................................................
 37204  38287   }
 37205  38288   
 37206  38289   /*
 37207  38290   ** Sync the journal. In other words, make sure all the pages that have
 37208  38291   ** been written to the journal have actually reached the surface of the
 37209  38292   ** disk and can be restored in the event of a hot-journal rollback.
 37210  38293   **
 37211         -** If the Pager.needSync flag is not set, then this function is a
 37212         -** no-op. Otherwise, the actions required depend on the journal-mode
 37213         -** and the device characteristics of the the file-system, as follows:
        38294  +** If the Pager.noSync flag is set, then this function is a no-op.
        38295  +** Otherwise, the actions required depend on the journal-mode and the 
        38296  +** device characteristics of the the file-system, as follows:
 37214  38297   **
 37215  38298   **   * If the journal file is an in-memory journal file, no action need
 37216  38299   **     be taken.
 37217  38300   **
 37218  38301   **   * Otherwise, if the device does not support the SAFE_APPEND property,
 37219  38302   **     then the nRec field of the most recently written journal header
 37220  38303   **     is updated to contain the number of journal records that have
................................................................................
 37230  38313   **     if( NOT SAFE_APPEND ){
 37231  38314   **       if( <full-sync mode> ) xSync(<journal file>);
 37232  38315   **       <update nRec field>
 37233  38316   **     } 
 37234  38317   **     if( NOT SEQUENTIAL ) xSync(<journal file>);
 37235  38318   **   }
 37236  38319   **
 37237         -** The Pager.needSync flag is never be set for temporary files, or any
 37238         -** file operating in no-sync mode (Pager.noSync set to non-zero).
 37239         -**
 37240  38320   ** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
 37241  38321   ** page currently held in memory before returning SQLITE_OK. If an IO
 37242  38322   ** error is encountered, then the IO error code is returned to the caller.
 37243  38323   */
 37244         -static int syncJournal(Pager *pPager){
 37245         -  if( pPager->needSync ){
        38324  +static int syncJournal(Pager *pPager, int newHdr){
        38325  +  int rc;                         /* Return code */
        38326  +
        38327  +  assert( pPager->eState==PAGER_WRITER_CACHEMOD
        38328  +       || pPager->eState==PAGER_WRITER_DBMOD
        38329  +  );
        38330  +  assert( assert_pager_state(pPager) );
        38331  +  assert( !pagerUseWal(pPager) );
        38332  +
        38333  +  rc = sqlite3PagerExclusiveLock(pPager);
        38334  +  if( rc!=SQLITE_OK ) return rc;
        38335  +
        38336  +  if( !pPager->noSync ){
 37246  38337       assert( !pPager->tempFile );
 37247         -    if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
 37248         -      int rc;                              /* Return code */
        38338  +    if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
 37249  38339         const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
 37250  38340         assert( isOpen(pPager->jfd) );
 37251  38341   
 37252  38342         if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
 37253  38343           /* This block deals with an obscure problem. If the last connection
 37254  38344           ** that wrote to this database was operating in persistent-journal
 37255  38345           ** mode, then the journal file may at this point actually be larger
................................................................................
 37316  38406           PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
 37317  38407           IOTRACE(("JSYNC %p\n", pPager))
 37318  38408           rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags| 
 37319  38409             (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
 37320  38410           );
 37321  38411           if( rc!=SQLITE_OK ) return rc;
 37322  38412         }
        38413  +
        38414  +      pPager->journalHdr = pPager->journalOff;
        38415  +      if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
        38416  +        pPager->nRec = 0;
        38417  +        rc = writeJournalHdr(pPager);
        38418  +        if( rc!=SQLITE_OK ) return rc;
        38419  +      }
        38420  +    }else{
        38421  +      pPager->journalHdr = pPager->journalOff;
 37323  38422       }
 37324         -
 37325         -    /* The journal file was just successfully synced. Set Pager.needSync 
 37326         -    ** to zero and clear the PGHDR_NEED_SYNC flag on all pagess.
 37327         -    */
 37328         -    pPager->needSync = 0;
 37329         -    pPager->journalStarted = 1;
 37330         -    pPager->journalHdr = pPager->journalOff;
 37331         -    sqlite3PcacheClearSyncFlags(pPager->pPCache);
 37332  38423     }
 37333  38424   
        38425  +  /* Unless the pager is in noSync mode, the journal file was just 
        38426  +  ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on 
        38427  +  ** all pages.
        38428  +  */
        38429  +  sqlite3PcacheClearSyncFlags(pPager->pPCache);
        38430  +  pPager->eState = PAGER_WRITER_DBMOD;
        38431  +  assert( assert_pager_state(pPager) );
 37334  38432     return SQLITE_OK;
 37335  38433   }
 37336  38434   
 37337  38435   /*
 37338  38436   ** The argument is the first in a linked list of dirty pages connected
 37339  38437   ** by the PgHdr.pDirty pointer. This function writes each one of the
 37340  38438   ** in-memory pages in the list to the database file. The argument may
................................................................................
 37363  38461   ** the database file.
 37364  38462   **
 37365  38463   ** If everything is successful, SQLITE_OK is returned. If an IO error 
 37366  38464   ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
 37367  38465   ** be obtained, SQLITE_BUSY is returned.
 37368  38466   */
 37369  38467   static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
 37370         -  int rc;                              /* Return code */
        38468  +  int rc = SQLITE_OK;                  /* Return code */
 37371  38469   
 37372         -  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
 37373         -  ** database file. If there is already an EXCLUSIVE lock, the following
 37374         -  ** call is a no-op.
 37375         -  **
 37376         -  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
 37377         -  ** through an intermediate state PENDING.   A PENDING lock prevents new
 37378         -  ** readers from attaching to the database but is unsufficient for us to
 37379         -  ** write.  The idea of a PENDING lock is to prevent new readers from
 37380         -  ** coming in while we wait for existing readers to clear.
 37381         -  **
 37382         -  ** While the pager is in the RESERVED state, the original database file
 37383         -  ** is unchanged and we can rollback without having to playback the
 37384         -  ** journal into the original database file.  Once we transition to
 37385         -  ** EXCLUSIVE, it means the database file has been changed and any rollback
 37386         -  ** will require a journal playback.
 37387         -  */
        38470  +  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
 37388  38471     assert( !pagerUseWal(pPager) );
 37389         -  assert( pPager->state>=PAGER_RESERVED );
 37390         -  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        38472  +  assert( pPager->eState==PAGER_WRITER_DBMOD );
        38473  +  assert( pPager->eLock==EXCLUSIVE_LOCK );
 37391  38474   
 37392  38475     /* If the file is a temp-file has not yet been opened, open it now. It
 37393  38476     ** is not possible for rc to be other than SQLITE_OK if this branch
 37394  38477     ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
 37395  38478     */
 37396  38479     if( !isOpen(pPager->fd) ){
 37397  38480       assert( pPager->tempFile && rc==SQLITE_OK );
................................................................................
 37398  38481       rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
 37399  38482     }
 37400  38483   
 37401  38484     /* Before the first write, give the VFS a hint of what the final
 37402  38485     ** file size will be.
 37403  38486     */
 37404  38487     assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
 37405         -  if( rc==SQLITE_OK && pPager->dbSize>(pPager->dbOrigSize+1) ){
        38488  +  if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
 37406  38489       sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
 37407  38490       sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
        38491  +    pPager->dbHintSize = pPager->dbSize;
 37408  38492     }
 37409  38493   
 37410  38494     while( rc==SQLITE_OK && pList ){
 37411  38495       Pgno pgno = pList->pgno;
 37412  38496   
 37413  38497       /* If there are dirty pages in the page cache with page numbers greater
 37414  38498       ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
................................................................................
 37417  38501       **
 37418  38502       ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
 37419  38503       ** set (set by sqlite3PagerDontWrite()).
 37420  38504       */
 37421  38505       if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
 37422  38506         i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
 37423  38507         char *pData;                                   /* Data to write */    
        38508  +
        38509  +      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
 37424  38510   
 37425  38511         /* Encode the database */
 37426  38512         CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
 37427  38513   
 37428  38514         /* Write out the page data. */
 37429  38515         rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
 37430  38516   
................................................................................
 37446  38532                      PAGERID(pPager), pgno, pager_pagehash(pList)));
 37447  38533         IOTRACE(("PGOUT %p %d\n", pPager, pgno));
 37448  38534         PAGER_INCR(sqlite3_pager_writedb_count);
 37449  38535         PAGER_INCR(pPager->nWrite);
 37450  38536       }else{
 37451  38537         PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
 37452  38538       }
 37453         -#ifdef SQLITE_CHECK_PAGES
 37454         -    pList->pageHash = pager_pagehash(pList);
 37455         -#endif
        38539  +    pager_set_pagehash(pList);
 37456  38540       pList = pList->pDirty;
 37457  38541     }
 37458  38542   
 37459  38543     return rc;
 37460  38544   }
 37461  38545   
 37462  38546   /*
................................................................................
 37560  38644     ** journal (and adding a new header) is not allowed.  This occurs
 37561  38645     ** during calls to sqlite3PagerWrite() while trying to journal multiple
 37562  38646     ** pages belonging to the same sector.
 37563  38647     **
 37564  38648     ** The doNotSpill flag inhibits all cache spilling regardless of whether
 37565  38649     ** or not a sync is required.  This is set during a rollback.
 37566  38650     **
 37567         -  ** Spilling is also inhibited when in an error state.
        38651  +  ** Spilling is also prohibited when in an error state since that could
        38652  +  ** lead to database corruption.   In the current implementaton it 
        38653  +  ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
        38654  +  ** while in the error state, hence it is impossible for this routine to
        38655  +  ** be called in the error state.  Nevertheless, we include a NEVER()
        38656  +  ** test for the error state as a safeguard against future changes.
 37568  38657     */
 37569         -  if( pPager->errCode ) return SQLITE_OK;
        38658  +  if( NEVER(pPager->errCode) ) return SQLITE_OK;
 37570  38659     if( pPager->doNotSpill ) return SQLITE_OK;
 37571  38660     if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
 37572  38661       return SQLITE_OK;
 37573  38662     }
 37574  38663   
 37575  38664     pPg->pDirty = 0;
 37576  38665     if( pagerUseWal(pPager) ){
................................................................................
 37580  38669       }
 37581  38670       if( rc==SQLITE_OK ){
 37582  38671         rc = pagerWalFrames(pPager, pPg, 0, 0, 0);
 37583  38672       }
 37584  38673     }else{
 37585  38674     
 37586  38675       /* Sync the journal file if required. */
 37587         -    if( pPg->flags&PGHDR_NEED_SYNC ){
 37588         -      assert( !pPager->noSync );
 37589         -      rc = syncJournal(pPager);
 37590         -      if( rc==SQLITE_OK && 
 37591         -        !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
 37592         -        !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
 37593         -      ){
 37594         -        pPager->nRec = 0;
 37595         -        rc = writeJournalHdr(pPager);
 37596         -      }
        38676  +    if( pPg->flags&PGHDR_NEED_SYNC 
        38677  +     || pPager->eState==PAGER_WRITER_CACHEMOD
        38678  +    ){
        38679  +      rc = syncJournal(pPager, 1);
 37597  38680       }
 37598  38681     
 37599  38682       /* If the page number of this page is larger than the current size of
 37600  38683       ** the database image, it may need to be written to the sub-journal.
 37601  38684       ** This is because the call to pager_write_pagelist() below will not
 37602  38685       ** actually write data to the file in this case.
 37603  38686       **
................................................................................
 37627  38710           rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
 37628  38711       ) ){
 37629  38712         rc = subjournalPage(pPg);
 37630  38713       }
 37631  38714     
 37632  38715       /* Write the contents of the page out to the database file. */
 37633  38716       if( rc==SQLITE_OK ){
        38717  +      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
 37634  38718         rc = pager_write_pagelist(pPager, pPg);
 37635  38719       }
 37636  38720     }
 37637  38721   
 37638  38722     /* Mark the page as clean. */
 37639  38723     if( rc==SQLITE_OK ){
 37640  38724       PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
 37641  38725       sqlite3PcacheMakeClean(pPg);
 37642  38726     }
 37643  38727   
 37644         -  return pager_error(pPager, rc);
        38728  +  return pager_error(pPager, rc); 
 37645  38729   }
 37646  38730   
 37647  38731   
 37648  38732   /*
 37649  38733   ** Allocate and initialize a new Pager object and put a pointer to it
 37650  38734   ** in *ppPager. The pager should eventually be freed by passing it
 37651  38735   ** to sqlite3PagerClose().
................................................................................
 37692  38776     int readOnly = 0;        /* True if this is a read-only file */
 37693  38777     int journalFileSize;     /* Bytes to allocate for each journal fd */
 37694  38778     char *zPathname = 0;     /* Full path to database file */
 37695  38779     int nPathname = 0;       /* Number of bytes in zPathname */
 37696  38780     int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
 37697  38781     int noReadlock = (flags & PAGER_NO_READLOCK)!=0;  /* True to omit read-lock */
 37698  38782     int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
 37699         -  u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
        38783  +  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
 37700  38784   
 37701  38785     /* Figure out how much space is required for each journal file-handle
 37702  38786     ** (there are two of them, the main journal and the sub-journal). This
 37703  38787     ** is the maximum space required for an in-memory journal file handle 
 37704  38788     ** and a regular journal file-handle. Note that a "regular journal-handle"
 37705  38789     ** may be a wrapper capable of caching the first portion of the journal
 37706  38790     ** file in memory to implement the atomic-write optimization (see 
................................................................................
 37710  38794       journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
 37711  38795     }else{
 37712  38796       journalFileSize = ROUND8(sqlite3MemJournalSize());
 37713  38797     }
 37714  38798   
 37715  38799     /* Set the output variable to NULL in case an error occurs. */
 37716  38800     *ppPager = 0;
        38801  +
        38802  +#ifndef SQLITE_OMIT_MEMORYDB
        38803  +  if( flags & PAGER_MEMORY ){
        38804  +    memDb = 1;
        38805  +    zFilename = 0;
        38806  +  }
        38807  +#endif
 37717  38808   
 37718  38809     /* Compute and store the full pathname in an allocated buffer pointed
 37719  38810     ** to by zPathname, length nPathname. Or, if this is a temporary file,
 37720  38811     ** leave both nPathname and zPathname set to 0.
 37721  38812     */
 37722  38813     if( zFilename && zFilename[0] ){
 37723  38814       nPathname = pVfs->mxPathname+1;
 37724  38815       zPathname = sqlite3Malloc(nPathname*2);
 37725  38816       if( zPathname==0 ){
 37726  38817         return SQLITE_NOMEM;
 37727  38818       }
 37728         -#ifndef SQLITE_OMIT_MEMORYDB
 37729         -    if( strcmp(zFilename,":memory:")==0 ){
 37730         -      memDb = 1;
 37731         -      zPathname[0] = 0;
 37732         -    }else
 37733         -#endif
 37734         -    {
 37735         -      zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
 37736         -      rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
 37737         -    }
 37738         -
        38819  +    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
        38820  +    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
 37739  38821       nPathname = sqlite3Strlen30(zPathname);
 37740  38822       if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
 37741  38823         /* This branch is taken when the journal path required by
 37742  38824         ** the database being opened will be more than pVfs->mxPathname
 37743  38825         ** bytes in length. This means the database cannot be opened,
 37744  38826         ** as it will not be possible to open the journal file or even
 37745  38827         ** check for a hot-journal before reading.
................................................................................
 37786  38868     pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
 37787  38869     pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
 37788  38870     pPager->zFilename =    (char*)(pPtr += journalFileSize);
 37789  38871     assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
 37790  38872   
 37791  38873     /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
 37792  38874     if( zPathname ){
        38875  +    assert( nPathname>0 );
 37793  38876       pPager->zJournal =   (char*)(pPtr += nPathname + 1);
 37794  38877       memcpy(pPager->zFilename, zPathname, nPathname);
 37795  38878       memcpy(pPager->zJournal, zPathname, nPathname);
 37796  38879       memcpy(&pPager->zJournal[nPathname], "-journal", 8);
 37797         -    if( pPager->zFilename[0]==0 ){
 37798         -      pPager->zJournal[0] = 0;
 37799         -    }
 37800  38880   #ifndef SQLITE_OMIT_WAL
 37801         -    else{
 37802         -      pPager->zWal = &pPager->zJournal[nPathname+8+1];
 37803         -      memcpy(pPager->zWal, zPathname, nPathname);
 37804         -      memcpy(&pPager->zWal[nPathname], "-wal", 4);
 37805         -    }
        38881  +    pPager->zWal = &pPager->zJournal[nPathname+8+1];
        38882  +    memcpy(pPager->zWal, zPathname, nPathname);
        38883  +    memcpy(&pPager->zWal[nPathname], "-wal", 4);
 37806  38884   #endif
 37807  38885       sqlite3_free(zPathname);
 37808  38886     }
 37809  38887     pPager->pVfs = pVfs;
 37810  38888     pPager->vfsFlags = vfsFlags;
 37811  38889   
 37812  38890     /* Open the pager file.
 37813  38891     */
 37814         -  if( zFilename && zFilename[0] && !memDb ){
        38892  +  if( zFilename && zFilename[0] ){
 37815  38893       int fout = 0;                    /* VFS flags returned by xOpen() */
 37816  38894       rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
        38895  +    assert( !memDb );
 37817  38896       readOnly = (fout&SQLITE_OPEN_READONLY);
 37818  38897   
 37819  38898       /* If the file was successfully opened for read/write access,
 37820  38899       ** choose a default page size in case we have to create the
 37821  38900       ** database file. The default page size is the maximum of:
 37822  38901       **
 37823  38902       **    + SQLITE_DEFAULT_PAGE_SIZE,
................................................................................
 37827  38906       if( rc==SQLITE_OK && !readOnly ){
 37828  38907         setSectorSize(pPager);
 37829  38908         assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
 37830  38909         if( szPageDflt<pPager->sectorSize ){
 37831  38910           if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
 37832  38911             szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
 37833  38912           }else{
 37834         -          szPageDflt = (u16)pPager->sectorSize;
        38913  +          szPageDflt = (u32)pPager->sectorSize;
 37835  38914           }
 37836  38915         }
 37837  38916   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
 37838  38917         {
 37839  38918           int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
 37840  38919           int ii;
 37841  38920           assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
................................................................................
 37855  38934       ** opening the file until the first call to OsWrite().
 37856  38935       **
 37857  38936       ** This branch is also run for an in-memory database. An in-memory
 37858  38937       ** database is the same as a temp-file that is never written out to
 37859  38938       ** disk and uses an in-memory rollback journal.
 37860  38939       */ 
 37861  38940       tempFile = 1;
 37862         -    pPager->state = PAGER_EXCLUSIVE;
        38941  +    pPager->eState = PAGER_READER;
        38942  +    pPager->eLock = EXCLUSIVE_LOCK;
 37863  38943       readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
 37864  38944     }
 37865  38945   
 37866  38946     /* The following call to PagerSetPagesize() serves to set the value of 
 37867  38947     ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
 37868  38948     */
 37869  38949     if( rc==SQLITE_OK ){
................................................................................
 37892  38972     IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
 37893  38973   
 37894  38974     pPager->useJournal = (u8)useJournal;
 37895  38975     pPager->noReadlock = (noReadlock && readOnly) ?1:0;
 37896  38976     /* pPager->stmtOpen = 0; */
 37897  38977     /* pPager->stmtInUse = 0; */
 37898  38978     /* pPager->nRef = 0; */
 37899         -  pPager->dbSizeValid = (u8)memDb;
 37900  38979     /* pPager->stmtSize = 0; */
 37901  38980     /* pPager->stmtJSize = 0; */
 37902  38981     /* pPager->nPage = 0; */
 37903  38982     pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
 37904  38983     /* pPager->state = PAGER_UNLOCK; */
        38984  +#if 0
 37905  38985     assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
        38986  +#endif
 37906  38987     /* pPager->errMask = 0; */
 37907  38988     pPager->tempFile = (u8)tempFile;
 37908  38989     assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
 37909  38990             || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
 37910  38991     assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
 37911  38992     pPager->exclusiveMode = (u8)tempFile; 
 37912  38993     pPager->changeCountDone = pPager->tempFile;
 37913  38994     pPager->memDb = (u8)memDb;
 37914  38995     pPager->readOnly = (u8)readOnly;
 37915         -  /* pPager->needSync = 0; */
 37916  38996     assert( useJournal || pPager->tempFile );
 37917  38997     pPager->noSync = pPager->tempFile;
 37918  38998     pPager->fullSync = pPager->noSync ?0:1;
 37919  38999     pPager->sync_flags = SQLITE_SYNC_NORMAL;
 37920  39000     /* pPager->pFirst = 0; */
 37921  39001     /* pPager->pFirstSynced = 0; */
 37922  39002     /* pPager->pLast = 0; */
................................................................................
 37973  39053   */
 37974  39054   static int hasHotJournal(Pager *pPager, int *pExists){
 37975  39055     sqlite3_vfs * const pVfs = pPager->pVfs;
 37976  39056     int rc = SQLITE_OK;           /* Return code */
 37977  39057     int exists = 1;               /* True if a journal file is present */
 37978  39058     int jrnlOpen = !!isOpen(pPager->jfd);
 37979  39059   
 37980         -  assert( pPager!=0 );
 37981  39060     assert( pPager->useJournal );
 37982  39061     assert( isOpen(pPager->fd) );
 37983         -  assert( pPager->state <= PAGER_SHARED );
        39062  +  assert( pPager->eState==PAGER_OPEN );
        39063  +
 37984  39064     assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
 37985  39065       SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
 37986  39066     ));
 37987  39067   
 37988  39068     *pExists = 0;
 37989  39069     if( !jrnlOpen ){
 37990  39070       rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
 37991  39071     }
 37992  39072     if( rc==SQLITE_OK && exists ){
 37993         -    int locked;                 /* True if some process holds a RESERVED lock */
        39073  +    int locked = 0;             /* True if some process holds a RESERVED lock */
 37994  39074   
 37995  39075       /* Race condition here:  Another process might have been holding the
 37996  39076       ** the RESERVED lock and have a journal open at the sqlite3OsAccess() 
 37997  39077       ** call above, but then delete the journal and drop the lock before
 37998  39078       ** we get to the following sqlite3OsCheckReservedLock() call.  If that
 37999  39079       ** is the case, this routine might think there is a hot journal when
 38000  39080       ** in fact there is none.  This results in a false-positive which will
 38001  39081       ** be dealt with by the playback routine.  Ticket #3883.
 38002  39082       */
 38003  39083       rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
 38004  39084       if( rc==SQLITE_OK && !locked ){
 38005         -      int nPage;
        39085  +      Pgno nPage;                 /* Number of pages in database file */
 38006  39086   
 38007  39087         /* Check the size of the database file. If it consists of 0 pages,
 38008  39088         ** then delete the journal file. See the header comment above for 
 38009  39089         ** the reasoning here.  Delete the obsolete journal file under
 38010  39090         ** a RESERVED lock to avoid race conditions and to avoid violating
 38011  39091         ** [H33020].
 38012  39092         */
 38013         -      rc = sqlite3PagerPagecount(pPager, &nPage);
        39093  +      rc = pagerPagecount(pPager, &nPage);
 38014  39094         if( rc==SQLITE_OK ){
 38015  39095           if( nPage==0 ){
 38016  39096             sqlite3BeginBenignMalloc();
 38017         -          if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
        39097  +          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
 38018  39098               sqlite3OsDelete(pVfs, pPager->zJournal, 0);
 38019         -            sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
        39099  +            pagerUnlockDb(pPager, SHARED_LOCK);
 38020  39100             }
 38021  39101             sqlite3EndBenignMalloc();
 38022  39102           }else{
 38023  39103             /* The journal file exists and no other connection has a reserved
 38024  39104             ** or greater lock on the database file. Now check that there is
 38025  39105             ** at least one non-zero bytes at the start of the journal file.
 38026  39106             ** If there is, then we consider this journal to be hot. If not, 
................................................................................
 38065  39145   ** This function is called to obtain a shared lock on the database file.
 38066  39146   ** It is illegal to call sqlite3PagerAcquire() until after this function
 38067  39147   ** has been successfully called. If a shared-lock is already held when
 38068  39148   ** this function is called, it is a no-op.
 38069  39149   **
 38070  39150   ** The following operations are also performed by this function.
 38071  39151   **
 38072         -**   1) If the pager is currently in PAGER_UNLOCK state (no lock held
        39152  +**   1) If the pager is currently in PAGER_OPEN state (no lock held
 38073  39153   **      on the database file), then an attempt is made to obtain a
 38074  39154   **      SHARED lock on the database file. Immediately after obtaining
 38075  39155   **      the SHARED lock, the file-system is checked for a hot-journal,
 38076  39156   **      which is played back if present. Following any hot-journal 
 38077  39157   **      rollback, the contents of the cache are validated by checking
 38078  39158   **      the 'change-counter' field of the database file header and
 38079  39159   **      discarded if they are found to be invalid.
................................................................................
 38080  39160   **
 38081  39161   **   2) If the pager is running in exclusive-mode, and there are currently
 38082  39162   **      no outstanding references to any pages, and is in the error state,
 38083  39163   **      then an attempt is made to clear the error state by discarding
 38084  39164   **      the contents of the page cache and rolling back any open journal
 38085  39165   **      file.
 38086  39166   **
 38087         -** If the operation described by (2) above is not attempted, and if the
 38088         -** pager is in an error state other than SQLITE_FULL when this is called,
 38089         -** the error state error code is returned. It is permitted to read the
 38090         -** database when in SQLITE_FULL error state.
 38091         -**
 38092         -** Otherwise, if everything is successful, SQLITE_OK is returned. If an
 38093         -** IO error occurs while locking the database, checking for a hot-journal
 38094         -** file or rolling back a journal file, the IO error code is returned.
        39167  +** If everything is successful, SQLITE_OK is returned. If an IO error 
        39168  +** occurs while locking the database, checking for a hot-journal file or 
        39169  +** rolling back a journal file, the IO error code is returned.
 38095  39170   */
 38096  39171   SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
 38097  39172     int rc = SQLITE_OK;                /* Return code */
 38098         -  int isErrorReset = 0;              /* True if recovering from error state */
 38099  39173   
 38100  39174     /* This routine is only called from b-tree and only when there are no
 38101         -  ** outstanding pages */
        39175  +  ** outstanding pages. This implies that the pager state should either
        39176  +  ** be OPEN or READER. READER is only possible if the pager is or was in 
        39177  +  ** exclusive access mode.
        39178  +  */
 38102  39179     assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
        39180  +  assert( assert_pager_state(pPager) );
        39181  +  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
 38103  39182     if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
 38104  39183   
 38105         -  /* If this database is in an error-state, now is a chance to clear
 38106         -  ** the error. Discard the contents of the pager-cache and rollback
 38107         -  ** any hot journal in the file-system.
 38108         -  */
 38109         -  if( pPager->errCode ){
 38110         -    if( isOpen(pPager->jfd) || pPager->zJournal ){
 38111         -      isErrorReset = 1;
 38112         -    }
 38113         -    pPager->errCode = SQLITE_OK;
 38114         -    pager_reset(pPager);
 38115         -  }
        39184  +  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
        39185  +    int bHotJournal = 1;          /* True if there exists a hot journal-file */
 38116  39186   
 38117         -  if( pagerUseWal(pPager) ){
 38118         -    rc = pagerBeginReadTransaction(pPager);
 38119         -  }else if( pPager->state==PAGER_UNLOCK || isErrorReset ){
 38120         -    sqlite3_vfs * const pVfs = pPager->pVfs;
 38121         -    int isHotJournal = 0;
 38122  39187       assert( !MEMDB );
 38123         -    assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
 38124         -    if( pPager->noReadlock ){
 38125         -      assert( pPager->readOnly );
 38126         -      pPager->state = PAGER_SHARED;
 38127         -    }else{
        39188  +    assert( pPager->noReadlock==0 || pPager->readOnly );
        39189  +
        39190  +    if( pPager->noReadlock==0 ){
 38128  39191         rc = pager_wait_on_lock(pPager, SHARED_LOCK);
 38129  39192         if( rc!=SQLITE_OK ){
 38130         -        assert( pPager->state==PAGER_UNLOCK );
 38131         -        return pager_error(pPager, rc);
        39193  +        assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
        39194  +        goto failed;
 38132  39195         }
 38133  39196       }
 38134         -    assert( pPager->state>=SHARED_LOCK );
 38135  39197   
 38136  39198       /* If a journal file exists, and there is no RESERVED lock on the
 38137  39199       ** database file, then it either needs to be played back or deleted.
 38138  39200       */
 38139         -    if( !isErrorReset ){
 38140         -      assert( pPager->state <= PAGER_SHARED );
 38141         -      rc = hasHotJournal(pPager, &isHotJournal);
 38142         -      if( rc!=SQLITE_OK ){
 38143         -        goto failed;
 38144         -      }
        39201  +    if( pPager->eLock<=SHARED_LOCK ){
        39202  +      rc = hasHotJournal(pPager, &bHotJournal);
 38145  39203       }
 38146         -    if( isErrorReset || isHotJournal ){
        39204  +    if( rc!=SQLITE_OK ){
        39205  +      goto failed;
        39206  +    }
        39207  +    if( bHotJournal ){
 38147  39208         /* Get an EXCLUSIVE lock on the database file. At this point it is
 38148  39209         ** important that a RESERVED lock is not obtained on the way to the
 38149  39210         ** EXCLUSIVE lock. If it were, another process might open the
 38150  39211         ** database file, detect the RESERVED lock, and conclude that the
 38151  39212         ** database is safe to read while this process is still rolling the 
 38152  39213         ** hot-journal back.
 38153  39214         ** 
 38154  39215         ** Because the intermediate RESERVED lock is not requested, any
 38155  39216         ** other process attempting to access the database file will get to 
 38156  39217         ** this point in the code and fail to obtain its own EXCLUSIVE lock 
 38157  39218         ** on the database file.
        39219  +      **
        39220  +      ** Unless the pager is in locking_mode=exclusive mode, the lock is
        39221  +      ** downgraded to SHARED_LOCK before this function returns.
 38158  39222         */
 38159         -      if( pPager->state<EXCLUSIVE_LOCK ){
 38160         -        rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
 38161         -        if( rc!=SQLITE_OK ){
 38162         -          rc = pager_error(pPager, rc);
 38163         -          goto failed;
 38164         -        }
 38165         -        pPager->state = PAGER_EXCLUSIVE;
 38166         -      }
 38167         - 
 38168         -      /* Open the journal for read/write access. This is because in 
 38169         -      ** exclusive-access mode the file descriptor will be kept open and
 38170         -      ** possibly used for a transaction later on. On some systems, the
 38171         -      ** OsTruncate() call used in exclusive-access mode also requires
 38172         -      ** a read/write file handle.
 38173         -      */
 38174         -      if( !isOpen(pPager->jfd) ){
 38175         -        int res;
 38176         -        rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
 38177         -        if( rc==SQLITE_OK ){
 38178         -          if( res ){
 38179         -            int fout = 0;
 38180         -            int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
 38181         -            assert( !pPager->tempFile );
 38182         -            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
 38183         -            assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
 38184         -            if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
 38185         -              rc = SQLITE_CANTOPEN_BKPT;
 38186         -              sqlite3OsClose(pPager->jfd);
 38187         -            }
 38188         -          }else{
 38189         -            /* If the journal does not exist, it usually means that some 
 38190         -            ** other connection managed to get in and roll it back before 
 38191         -            ** this connection obtained the exclusive lock above. Or, it 
 38192         -            ** may mean that the pager was in the error-state when this
 38193         -            ** function was called and the journal file does not exist.  */
 38194         -            rc = pager_end_transaction(pPager, 0);
 38195         -          }
 38196         -        }
 38197         -      }
        39223  +      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
 38198  39224         if( rc!=SQLITE_OK ){
 38199  39225           goto failed;
 38200  39226         }
 38201         -
 38202         -      /* Reset the journal status fields to indicates that we have no
 38203         -      ** rollback journal at this time. */
 38204         -      pPager->journalStarted = 0;
 38205         -      pPager->journalOff = 0;
 38206         -      pPager->setMaster = 0;
 38207         -      pPager->journalHdr = 0;
 38208  39227    
 38209         -      /* Make sure the journal file has been synced to disk. */
        39228  +      /* If it is not already open and the file exists on disk, open the 
        39229  +      ** journal for read/write access. Write access is required because 
        39230  +      ** in exclusive-access mode the file descriptor will be kept open 
        39231  +      ** and possibly used for a transaction later on. Also, write-access 
        39232  +      ** is usually required to finalize the journal in journal_mode=persist 
        39233  +      ** mode (and also for journal_mode=truncate on some systems).
        39234  +      **
        39235  +      ** If the journal does not exist, it usually means that some 
        39236  +      ** other connection managed to get in and roll it back before 
        39237  +      ** this connection obtained the exclusive lock above. Or, it 
        39238  +      ** may mean that the pager was in the error-state when this
        39239  +      ** function was called and the journal file does not exist.
        39240  +      */
        39241  +      if( !isOpen(pPager->jfd) ){
        39242  +        sqlite3_vfs * const pVfs = pPager->pVfs;
        39243  +        int bExists;              /* True if journal file exists */
        39244  +        rc = sqlite3OsAccess(
        39245  +            pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
        39246  +        if( rc==SQLITE_OK && bExists ){
        39247  +          int fout = 0;
        39248  +          int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
        39249  +          assert( !pPager->tempFile );
        39250  +          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
        39251  +          assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
        39252  +          if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
        39253  +            rc = SQLITE_CANTOPEN_BKPT;
        39254  +            sqlite3OsClose(pPager->jfd);
        39255  +          }
        39256  +        }
        39257  +      }
 38210  39258    
 38211  39259         /* Playback and delete the journal.  Drop the database write
 38212  39260         ** lock and reacquire the read lock. Purge the cache before
 38213  39261         ** playing back the hot-journal so that we don't end up with
 38214  39262         ** an inconsistent cache.  Sync the hot journal before playing
 38215  39263         ** it back since the process that crashed and left the hot journal
 38216  39264         ** probably did not sync it and we are required to always sync
 38217  39265         ** the journal before playing it back.
 38218  39266         */
 38219  39267         if( isOpen(pPager->jfd) ){
        39268  +        assert( rc==SQLITE_OK );
 38220  39269           rc = pagerSyncHotJournal(pPager);
 38221  39270           if( rc==SQLITE_OK ){
 38222  39271             rc = pager_playback(pPager, 1);
 38223         -        }
 38224         -        if( rc!=SQLITE_OK ){
 38225         -          rc = pager_error(pPager, rc);
 38226         -          goto failed;
 38227         -        }
 38228         -      }
 38229         -      assert( (pPager->state==PAGER_SHARED)
 38230         -           || (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
 38231         -      );
 38232         -    }
 38233         -
 38234         -    if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){
        39272  +          pPager->eState = PAGER_OPEN;
        39273  +        }
        39274  +      }else if( !pPager->exclusiveMode ){
        39275  +        pagerUnlockDb(pPager, SHARED_LOCK);
        39276  +      }
        39277  +
        39278  +      if( rc!=SQLITE_OK ){
        39279  +        /* This branch is taken if an error occurs while trying to open
        39280  +        ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
        39281  +        ** pager_unlock() routine will be called before returning to unlock
        39282  +        ** the file. If the unlock attempt fails, then Pager.eLock must be
        39283  +        ** set to UNKNOWN_LOCK (see the comment above the #define for 
        39284  +        ** UNKNOWN_LOCK above for an explanation). 
        39285  +        **
        39286  +        ** In order to get pager_unlock() to do this, set Pager.eState to
        39287  +        ** PAGER_ERROR now. This is not actually counted as a transition
        39288  +        ** to ERROR state in the state diagram at the top of this file,
        39289  +        ** since we know that the same call to pager_unlock() will very
        39290  +        ** shortly transition the pager object to the OPEN state. Calling
        39291  +        ** assert_pager_state() would fail now, as it should not be possible
        39292  +        ** to be in ERROR state when there are zero outstanding page 
        39293  +        ** references.
        39294  +        */
        39295  +        pager_error(pPager, rc);
        39296  +        goto failed;
        39297  +      }
        39298  +
        39299  +      assert( pPager->eState==PAGER_OPEN );
        39300  +      assert( (pPager->eLock==SHARED_LOCK)
        39301  +           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
        39302  +      );
        39303  +    }
        39304  +
        39305  +    if( !pPager->tempFile 
        39306  +     && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) 
        39307  +    ){
 38235  39308         /* The shared-lock has just been acquired on the database file
 38236  39309         ** and there are already pages in the cache (from a previous
 38237  39310         ** read or write transaction).  Check to see if the database
 38238  39311         ** has been modified.  If the database has changed, flush the
 38239  39312         ** cache.
 38240  39313         **
 38241  39314         ** Database changes is detected by looking at 15 bytes beginning
................................................................................
 38244  39317         ** other bytes change randomly with each file change when
 38245  39318         ** a codec is in use.
 38246  39319         ** 
 38247  39320         ** There is a vanishingly small chance that a change will not be 
 38248  39321         ** detected.  The chance of an undetected change is so small that
 38249  39322         ** it can be neglected.
 38250  39323         */
 38251         -      int nPage = 0;
        39324  +      Pgno nPage = 0;
 38252  39325         char dbFileVers[sizeof(pPager->dbFileVers)];
 38253         -      sqlite3PagerPagecount(pPager, &nPage);
 38254  39326   
 38255         -      if( pPager->errCode ){
 38256         -        rc = pPager->errCode;
 38257         -        goto failed;
 38258         -      }
        39327  +      rc = pagerPagecount(pPager, &nPage);
        39328  +      if( rc ) goto failed;
 38259  39329   
 38260  39330         if( nPage>0 ){
 38261  39331           IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
 38262  39332           rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
 38263  39333           if( rc!=SQLITE_OK ){
 38264  39334             goto failed;
 38265  39335           }
................................................................................
 38267  39337           memset(dbFileVers, 0, sizeof(dbFileVers));
 38268  39338         }
 38269  39339   
 38270  39340         if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
 38271  39341           pager_reset(pPager);
 38272  39342         }
 38273  39343       }
 38274         -    assert( pPager->exclusiveMode || pPager->state==PAGER_SHARED );
 38275  39344   
 38276  39345       /* If there is a WAL file in the file-system, open this database in WAL
 38277  39346       ** mode. Otherwise, the following function call is a no-op.
 38278  39347       */
 38279  39348       rc = pagerOpenWalIfPresent(pPager);
        39349  +#ifndef SQLITE_OMIT_WAL
        39350  +    assert( pPager->pWal==0 || rc==SQLITE_OK );
        39351  +#endif
        39352  +  }
        39353  +
        39354  +  if( pagerUseWal(pPager) ){
        39355  +    assert( rc==SQLITE_OK );
        39356  +    rc = pagerBeginReadTransaction(pPager);
        39357  +  }
        39358  +
        39359  +  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
        39360  +    rc = pagerPagecount(pPager, &pPager->dbSize);
 38280  39361     }
 38281  39362   
 38282  39363    failed:
 38283  39364     if( rc!=SQLITE_OK ){
 38284         -    /* pager_unlock() is a no-op for exclusive mode and in-memory databases. */
        39365  +    assert( !MEMDB );
 38285  39366       pager_unlock(pPager);
        39367  +    assert( pPager->eState==PAGER_OPEN );
        39368  +  }else{
        39369  +    pPager->eState = PAGER_READER;
 38286  39370     }
 38287  39371     return rc;
 38288  39372   }
 38289  39373   
 38290  39374   /*
 38291  39375   ** If the reference count has reached zero, rollback any active
 38292  39376   ** transaction and unlock the pager.
 38293  39377   **
 38294  39378   ** Except, in locking_mode=EXCLUSIVE when there is nothing to in
 38295  39379   ** the rollback journal, the unlock is not performed and there is
 38296  39380   ** nothing to rollback, so this routine is a no-op.
 38297  39381   */ 
 38298  39382   static void pagerUnlockIfUnused(Pager *pPager){
 38299         -  if( (sqlite3PcacheRefCount(pPager->pPCache)==0)
 38300         -   && (!pPager->exclusiveMode || pPager->journalOff>0) 
 38301         -  ){
        39383  +  if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
 38302  39384       pagerUnlockAndRollback(pPager);
 38303  39385     }
 38304  39386   }
 38305  39387   
 38306  39388   /*
 38307  39389   ** Acquire a reference to page number pgno in pager pPager (a page
 38308  39390   ** reference has type DbPage*). If the requested reference is 
................................................................................
 38358  39440     Pgno pgno,          /* Page number to fetch */
 38359  39441     DbPage **ppPage,    /* Write a pointer to the page here */
 38360  39442     int noContent       /* Do not bother reading content from disk if true */
 38361  39443   ){
 38362  39444     int rc;
 38363  39445     PgHdr *pPg;
 38364  39446   
        39447  +  assert( pPager->eState>=PAGER_READER );
 38365  39448     assert( assert_pager_state(pPager) );
 38366         -  assert( pPager->state>PAGER_UNLOCK );
 38367  39449   
 38368  39450     if( pgno==0 ){
 38369  39451       return SQLITE_CORRUPT_BKPT;
 38370  39452     }
 38371  39453   
 38372  39454     /* If the pager is in the error state, return an error immediately. 
 38373  39455     ** Otherwise, request the page from the PCache layer. */
 38374         -  if( pPager->errCode!=SQLITE_OK && pPager->errCode!=SQLITE_FULL ){
        39456  +  if( pPager->errCode!=SQLITE_OK ){
 38375  39457       rc = pPager->errCode;
 38376  39458     }else{
 38377  39459       rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
 38378  39460     }
 38379  39461   
 38380  39462     if( rc!=SQLITE_OK ){
 38381  39463       /* Either the call to sqlite3PcacheFetch() returned an error or the
................................................................................
 38393  39475       assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
 38394  39476       PAGER_INCR(pPager->nHit);
 38395  39477       return SQLITE_OK;
 38396  39478   
 38397  39479     }else{
 38398  39480       /* The pager cache has created a new page. Its content needs to 
 38399  39481       ** be initialized.  */
 38400         -    int nMax;
 38401  39482   
 38402  39483       PAGER_INCR(pPager->nMiss);
 38403  39484       pPg = *ppPage;
 38404  39485       pPg->pPager = pPager;
 38405  39486   
 38406  39487       /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
 38407  39488       ** number greater than this, or the unused locking-page, is requested. */
 38408  39489       if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
 38409  39490         rc = SQLITE_CORRUPT_BKPT;
 38410  39491         goto pager_acquire_err;
 38411  39492       }
 38412  39493   
 38413         -    rc = sqlite3PagerPagecount(pPager, &nMax);
 38414         -    if( rc!=SQLITE_OK ){
 38415         -      goto pager_acquire_err;
 38416         -    }
 38417         -
 38418         -    if( MEMDB || nMax<(int)pgno || noContent || !isOpen(pPager->fd) ){
        39494  +    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
 38419  39495         if( pgno>pPager->mxPgno ){
 38420  39496           rc = SQLITE_FULL;
 38421  39497           goto pager_acquire_err;
 38422  39498         }
 38423  39499         if( noContent ){
 38424  39500           /* Failure to set the bits in the InJournal bit-vectors is benign.
 38425  39501           ** It merely means that we might do some extra work to journal a 
................................................................................
 38441  39517       }else{
 38442  39518         assert( pPg->pPager==pPager );
 38443  39519         rc = readDbPage(pPg);
 38444  39520         if( rc!=SQLITE_OK ){
 38445  39521           goto pager_acquire_err;
 38446  39522         }
 38447  39523       }
 38448         -#ifdef SQLITE_CHECK_PAGES
 38449         -    pPg->pageHash = pager_pagehash(pPg);
 38450         -#endif
        39524  +    pager_set_pagehash(pPg);
 38451  39525     }
 38452  39526   
 38453  39527     return SQLITE_OK;
 38454  39528   
 38455  39529   pager_acquire_err:
 38456  39530     assert( rc!=SQLITE_OK );
 38457  39531     if( pPg ){
................................................................................
 38462  39536     *ppPage = 0;
 38463  39537     return rc;
 38464  39538   }
 38465  39539   
 38466  39540   /*
 38467  39541   ** Acquire a page if it is already in the in-memory cache.  Do
 38468  39542   ** not read the page from disk.  Return a pointer to the page,
 38469         -** or 0 if the page is not in cache. Also, return 0 if the 
 38470         -** pager is in PAGER_UNLOCK state when this function is called,
 38471         -** or if the pager is in an error state other than SQLITE_FULL.
        39543  +** or 0 if the page is not in cache. 
 38472  39544   **
 38473  39545   ** See also sqlite3PagerGet().  The difference between this routine
 38474  39546   ** and sqlite3PagerGet() is that _get() will go to the disk and read
 38475  39547   ** in the page if the page is not already in cache.  This routine
 38476  39548   ** returns NULL if the page is not in cache or if a disk I/O error 
 38477  39549   ** has ever happened.
 38478  39550   */
 38479  39551   SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
 38480  39552     PgHdr *pPg = 0;
 38481  39553     assert( pPager!=0 );
 38482  39554     assert( pgno!=0 );
 38483  39555     assert( pPager->pPCache!=0 );
 38484         -  assert( pPager->state > PAGER_UNLOCK );
        39556  +  assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR );
 38485  39557     sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
 38486  39558     return pPg;
 38487  39559   }
 38488  39560   
 38489  39561   /*
 38490  39562   ** Release a page reference.
 38491  39563   **
................................................................................
 38522  39594   **
 38523  39595   ** Return SQLITE_OK if everything is successful. Otherwise, return 
 38524  39596   ** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or 
 38525  39597   ** an IO error code if opening or writing the journal file fails.
 38526  39598   */
 38527  39599   static int pager_open_journal(Pager *pPager){
 38528  39600     int rc = SQLITE_OK;                        /* Return code */
 38529         -  int nPage;                                 /* Size of database file */
 38530  39601     sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
 38531  39602   
 38532         -  assert( pPager->state>=PAGER_RESERVED );
 38533         -  assert( pPager->useJournal );
 38534         -  assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF );
        39603  +  assert( pPager->eState==PAGER_WRITER_LOCKED );
        39604  +  assert( assert_pager_state(pPager) );
 38535  39605     assert( pPager->pInJournal==0 );
 38536  39606     
 38537  39607     /* If already in the error state, this function is a no-op.  But on
 38538  39608     ** the other hand, this routine is never called if we are already in
 38539  39609     ** an error state. */
 38540  39610     if( NEVER(pPager->errCode) ) return pPager->errCode;
 38541  39611   
 38542         -  testcase( pPager->dbSizeValid==0 );
 38543         -  rc = sqlite3PagerPagecount(pPager, &nPage);
 38544         -  if( rc ) return rc;
 38545         -  pPager->pInJournal = sqlite3BitvecCreate(nPage);
 38546         -  if( pPager->pInJournal==0 ){
 38547         -    return SQLITE_NOMEM;
 38548         -  }
 38549         -
 38550         -  /* Open the journal file if it is not already open. */
 38551         -  if( !isOpen(pPager->jfd) ){
 38552         -    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
 38553         -      sqlite3MemJournalOpen(pPager->jfd);
 38554         -    }else{
 38555         -      const int flags =                   /* VFS flags to open journal file */
 38556         -        SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
 38557         -        (pPager->tempFile ? 
 38558         -          (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
 38559         -          (SQLITE_OPEN_MAIN_JOURNAL)
 38560         -        );
 38561         -#ifdef SQLITE_ENABLE_ATOMIC_WRITE
 38562         -      rc = sqlite3JournalOpen(
 38563         -          pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
 38564         -      );
 38565         -#else
 38566         -      rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
 38567         -#endif
 38568         -    }
 38569         -    assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
 38570         -  }
 38571         -
 38572         -
 38573         -  /* Write the first journal header to the journal file and open 
 38574         -  ** the sub-journal if necessary.
 38575         -  */
 38576         -  if( rc==SQLITE_OK ){
 38577         -    /* TODO: Check if all of these are really required. */
 38578         -    pPager->dbOrigSize = pPager->dbSize;
 38579         -    pPager->journalStarted = 0;
 38580         -    pPager->needSync = 0;
 38581         -    pPager->nRec = 0;
 38582         -    pPager->journalOff = 0;
 38583         -    pPager->setMaster = 0;
 38584         -    pPager->journalHdr = 0;
 38585         -    rc = writeJournalHdr(pPager);
        39612  +  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
        39613  +    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
        39614  +    if( pPager->pInJournal==0 ){
        39615  +      return SQLITE_NOMEM;
        39616  +    }
        39617  +  
        39618  +    /* Open the journal file if it is not already open. */
        39619  +    if( !isOpen(pPager->jfd) ){
        39620  +      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
        39621  +        sqlite3MemJournalOpen(pPager->jfd);
        39622  +      }else{
        39623  +        const int flags =                   /* VFS flags to open journal file */
        39624  +          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
        39625  +          (pPager->tempFile ? 
        39626  +            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
        39627  +            (SQLITE_OPEN_MAIN_JOURNAL)
        39628  +          );
        39629  +  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
        39630  +        rc = sqlite3JournalOpen(
        39631  +            pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
        39632  +        );
        39633  +  #else
        39634  +        rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
        39635  +  #endif
        39636  +      }
        39637  +      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
        39638  +    }
        39639  +  
        39640  +  
        39641  +    /* Write the first journal header to the journal file and open 
        39642  +    ** the sub-journal if necessary.
        39643  +    */
        39644  +    if( rc==SQLITE_OK ){
        39645  +      /* TODO: Check if all of these are really required. */
        39646  +      pPager->nRec = 0;
        39647  +      pPager->journalOff = 0;
        39648  +      pPager->setMaster = 0;
        39649  +      pPager->journalHdr = 0;
        39650  +      rc = writeJournalHdr(pPager);
        39651  +    }
 38586  39652     }
 38587  39653   
 38588  39654     if( rc!=SQLITE_OK ){
 38589  39655       sqlite3BitvecDestroy(pPager->pInJournal);
 38590  39656       pPager->pInJournal = 0;
        39657  +  }else{
        39658  +    assert( pPager->eState==PAGER_WRITER_LOCKED );
        39659  +    pPager->eState = PAGER_WRITER_CACHEMOD;
 38591  39660     }
        39661  +
 38592  39662     return rc;
 38593  39663   }
 38594  39664   
 38595  39665   /*
 38596  39666   ** Begin a write-transaction on the specified pager object. If a 
 38597  39667   ** write-transaction has already been opened, this function is a no-op.
 38598  39668   **
 38599  39669   ** If the exFlag argument is false, then acquire at least a RESERVED
 38600  39670   ** lock on the database file. If exFlag is true, then acquire at least
 38601  39671   ** an EXCLUSIVE lock. If such a lock is already held, no locking 
 38602  39672   ** functions need be called.
 38603  39673   **
 38604         -** If this is not a temporary or in-memory file and, the journal file is 
 38605         -** opened if it has not been already. For a temporary file, the opening 
 38606         -** of the journal file is deferred until there is an actual need to 
 38607         -** write to the journal. TODO: Why handle temporary files differently?
 38608         -**
 38609         -** If the journal file is opened (or if it is already open), then a
 38610         -** journal-header is written to the start of it.
 38611         -**
 38612  39674   ** If the subjInMemory argument is non-zero, then any sub-journal opened
 38613  39675   ** within this transaction will be opened as an in-memory file. This
 38614  39676   ** has no effect if the sub-journal is already opened (as it may be when
 38615  39677   ** running in exclusive mode) or if the transaction does not require a
 38616  39678   ** sub-journal. If the subjInMemory argument is zero, then any required
 38617  39679   ** sub-journal is implemented in-memory if pPager is an in-memory database, 
 38618  39680   ** or using a temporary file otherwise.
 38619  39681   */
 38620  39682   SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
 38621  39683     int rc = SQLITE_OK;
 38622         -  assert( pPager->state!=PAGER_UNLOCK );
        39684  +
        39685  +  if( pPager->errCode ) return pPager->errCode;
        39686  +  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
 38623  39687     pPager->subjInMemory = (u8)subjInMemory;
 38624  39688   
 38625         -  if( pPager->state==PAGER_SHARED ){
        39689  +  if( ALWAYS(pPager->eState==PAGER_READER) ){
 38626  39690       assert( pPager->pInJournal==0 );
 38627         -    assert( !MEMDB && !pPager->tempFile );
 38628  39691   
 38629  39692       if( pagerUseWal(pPager) ){
 38630  39693         /* If the pager is configured to use locking_mode=exclusive, and an
 38631  39694         ** exclusive lock on the database is not already held, obtain it now.
 38632  39695         */
 38633  39696         if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
 38634         -        rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
 38635         -        pPager->state = PAGER_SHARED;
        39697  +        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
 38636  39698           if( rc!=SQLITE_OK ){
 38637  39699             return rc;
 38638  39700           }
 38639  39701           sqlite3WalExclusiveMode(pPager->pWal, 1);
 38640  39702         }
 38641  39703   
 38642  39704         /* Grab the write lock on the log file. If successful, upgrade to
 38643  39705         ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
 38644  39706         ** The busy-handler is not invoked if another connection already
 38645  39707         ** holds the write-lock. If possible, the upper layer will call it.
 38646         -      **
 38647         -      ** WAL mode sets Pager.state to PAGER_RESERVED when it has an open
 38648         -      ** transaction, but never to PAGER_EXCLUSIVE. This is because in 
 38649         -      ** PAGER_EXCLUSIVE state the code to roll back savepoint transactions
 38650         -      ** may copy data from the sub-journal into the database file as well
 38651         -      ** as into the page cache. Which would be incorrect in WAL mode.
 38652  39708         */
 38653  39709         rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
 38654         -      if( rc==SQLITE_OK ){
 38655         -        pPager->dbOrigSize = pPager->dbSize;
 38656         -        pPager->state = PAGER_RESERVED;
 38657         -        pPager->journalOff = 0;
 38658         -      }
 38659         -
 38660         -      assert( rc!=SQLITE_OK || pPager->state==PAGER_RESERVED );
 38661         -      assert( rc==SQLITE_OK || pPager->state==PAGER_SHARED );
 38662  39710       }else{
 38663  39711         /* Obtain a RESERVED lock on the database file. If the exFlag parameter
 38664  39712         ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
 38665  39713         ** busy-handler callback can be used when upgrading to the EXCLUSIVE
 38666  39714         ** lock, but not when obtaining the RESERVED lock.
 38667  39715         */
 38668         -      rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
 38669         -      if( rc==SQLITE_OK ){
 38670         -        pPager->state = PAGER_RESERVED;
 38671         -        if( exFlag ){
 38672         -          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
 38673         -        }
 38674         -      }
 38675         -    }
 38676         -
 38677         -    /* No need to open the journal file at this time.  It will be
 38678         -    ** opened before it is written to.  If we defer opening the journal,
 38679         -    ** we might save the work of creating a file if the transaction
 38680         -    ** ends up being a no-op.
 38681         -    */
 38682         -
 38683         -    if( rc!=SQLITE_OK ){
 38684         -      assert( !pPager->dbModified );
 38685         -      /* Ignore any IO error that occurs within pager_end_transaction(). The
 38686         -      ** purpose of this call is to reset the internal state of the pager
 38687         -      ** sub-system. It doesn't matter if the journal-file is not properly
 38688         -      ** finalized at this point (since it is not a valid journal file anyway).
 38689         -      */
 38690         -      pager_end_transaction(pPager, 0);
 38691         -    }
        39716  +      rc = pagerLockDb(pPager, RESERVED_LOCK);
        39717  +      if( rc==SQLITE_OK && exFlag ){
        39718  +        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        39719  +      }
        39720  +    }
        39721  +
        39722  +    if( rc==SQLITE_OK ){
        39723  +      /* Change to WRITER_LOCKED state.
        39724  +      **
        39725  +      ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
        39726  +      ** when it has an open transaction, but never to DBMOD or FINISHED.
        39727  +      ** This is because in those states the code to roll back savepoint 
        39728  +      ** transactions may copy data from the sub-journal into the database 
        39729  +      ** file as well as into the page cache. Which would be incorrect in 
        39730  +      ** WAL mode.
        39731  +      */
        39732  +      pPager->eState = PAGER_WRITER_LOCKED;
        39733  +      pPager->dbHintSize = pPager->dbSize;
        39734  +      pPager->dbFileSize = pPager->dbSize;
        39735  +      pPager->dbOrigSize = pPager->dbSize;
        39736  +      pPager->journalOff = 0;
        39737  +    }
        39738  +
        39739  +    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
        39740  +    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
        39741  +    assert( assert_pager_state(pPager) );
 38692  39742     }
 38693  39743   
 38694  39744     PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
 38695  39745     return rc;
 38696  39746   }
 38697  39747   
 38698  39748   /*
................................................................................
 38703  39753   ** of any open savepoints as appropriate.
 38704  39754   */
 38705  39755   static int pager_write(PgHdr *pPg){
 38706  39756     void *pData = pPg->pData;
 38707  39757     Pager *pPager = pPg->pPager;
 38708  39758     int rc = SQLITE_OK;
 38709  39759   
 38710         -  /* This routine is not called unless a transaction has already been
 38711         -  ** started.
        39760  +  /* This routine is not called unless a write-transaction has already 
        39761  +  ** been started. The journal file may or may not be open at this point.
        39762  +  ** It is never called in the ERROR state.
 38712  39763     */
 38713         -  assert( pPager->state>=PAGER_RESERVED );
        39764  +  assert( pPager->eState==PAGER_WRITER_LOCKED
        39765  +       || pPager->eState==PAGER_WRITER_CACHEMOD
        39766  +       || pPager->eState==PAGER_WRITER_DBMOD
        39767  +  );
        39768  +  assert( assert_pager_state(pPager) );
 38714  39769   
 38715  39770     /* If an error has been previously detected, report the same error
 38716         -  ** again.
 38717         -  */
        39771  +  ** again. This should not happen, but the check provides robustness. */
 38718  39772     if( NEVER(pPager->errCode) )  return pPager->errCode;
 38719  39773   
 38720  39774     /* Higher-level routines never call this function if database is not
 38721  39775     ** writable.  But check anyway, just for robustness. */
 38722  39776     if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
 38723  39777   
 38724         -  assert( !pPager->setMaster );
 38725         -
 38726  39778     CHECK_PAGE(pPg);
        39779  +
        39780  +  /* The journal file needs to be opened. Higher level routines have already
        39781  +  ** obtained the necessary locks to begin the write-transaction, but the
        39782  +  ** rollback journal might not yet be open. Open it now if this is the case.
        39783  +  **
        39784  +  ** This is done before calling sqlite3PcacheMakeDirty() on the page. 
        39785  +  ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
        39786  +  ** an error might occur and the pager would end up in WRITER_LOCKED state
        39787  +  ** with pages marked as dirty in the cache.
        39788  +  */
        39789  +  if( pPager->eState==PAGER_WRITER_LOCKED ){
        39790  +    rc = pager_open_journal(pPager);
        39791  +    if( rc!=SQLITE_OK ) return rc;
        39792  +  }
        39793  +  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
        39794  +  assert( assert_pager_state(pPager) );
 38727  39795   
 38728  39796     /* Mark the page as dirty.  If the page has already been written
 38729  39797     ** to the journal then we can return right away.
 38730  39798     */
 38731  39799     sqlite3PcacheMakeDirty(pPg);
 38732  39800     if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
 38733  39801       assert( !pagerUseWal(pPager) );
 38734         -    pPager->dbModified = 1;
 38735  39802     }else{
 38736         -
 38737         -    /* If we get this far, it means that the page needs to be
 38738         -    ** written to the transaction journal or the ckeckpoint journal
 38739         -    ** or both.
 38740         -    **
 38741         -    ** Higher level routines should have already started a transaction,
 38742         -    ** which means they have acquired the necessary locks but the rollback
 38743         -    ** journal might not yet be open.
 38744         -    */
 38745         -    assert( pPager->state>=RESERVED_LOCK );
 38746         -    if( pPager->pInJournal==0
 38747         -     && pPager->journalMode!=PAGER_JOURNALMODE_OFF 
 38748         -     && !pagerUseWal(pPager)
 38749         -    ){
 38750         -      assert( pPager->useJournal );
 38751         -      rc = pager_open_journal(pPager);
 38752         -      if( rc!=SQLITE_OK ) return rc;
 38753         -    }
 38754         -    pPager->dbModified = 1;
 38755  39803     
 38756  39804       /* The transaction journal now exists and we have a RESERVED or an
 38757  39805       ** EXCLUSIVE lock on the main database file.  Write the current page to
 38758  39806       ** the transaction journal if it is not there already.
 38759  39807       */
 38760         -    if( !pageInJournal(pPg) && isOpen(pPager->jfd) ){
 38761         -      assert( !pagerUseWal(pPager) );
 38762         -      if( pPg->pgno<=pPager->dbOrigSize ){
        39808  +    if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){
        39809  +      assert( pagerUseWal(pPager)==0 );
        39810  +      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
 38763  39811           u32 cksum;
 38764  39812           char *pData2;
        39813  +        i64 iOff = pPager->journalOff;
 38765  39814   
 38766  39815           /* We should never write to the journal file the page that
 38767  39816           ** contains the database locks.  The following assert verifies
 38768  39817           ** that we do not. */
 38769  39818           assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
 38770  39819   
 38771         -        assert( pPager->journalHdr <= pPager->journalOff );
        39820  +        assert( pPager->journalHdr<=pPager->journalOff );
 38772  39821           CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
 38773  39822           cksum = pager_cksum(pPager, (u8*)pData2);
 38774         -        rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
 38775         -        if( rc==SQLITE_OK ){
 38776         -          rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize,
 38777         -                              pPager->journalOff + 4);
 38778         -          pPager->journalOff += pPager->pageSize+4;
 38779         -        }
 38780         -        if( rc==SQLITE_OK ){
 38781         -          rc = write32bits(pPager->jfd, pPager->journalOff, cksum);
 38782         -          pPager->journalOff += 4;
 38783         -        }
        39823  +
        39824  +        /* Even if an IO or diskfull error occurs while journalling the
        39825  +        ** page in the block above, set the need-sync flag for the page.
        39826  +        ** Otherwise, when the transaction is rolled back, the logic in
        39827  +        ** playback_one_page() will think that the page needs to be restored
        39828  +        ** in the database file. And if an IO error occurs while doing so,
        39829  +        ** then corruption may follow.
        39830  +        */
        39831  +        pPg->flags |= PGHDR_NEED_SYNC;
        39832  +
        39833  +        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
        39834  +        if( rc!=SQLITE_OK ) return rc;
        39835  +        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
        39836  +        if( rc!=SQLITE_OK ) return rc;
        39837  +        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
        39838  +        if( rc!=SQLITE_OK ) return rc;
        39839  +
 38784  39840           IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
 38785  39841                    pPager->journalOff, pPager->pageSize));
 38786  39842           PAGER_INCR(sqlite3_pager_writej_count);
 38787  39843           PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
 38788  39844                PAGERID(pPager), pPg->pgno, 
 38789  39845                ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
 38790  39846   
 38791         -        /* Even if an IO or diskfull error occurred while journalling the
 38792         -        ** page in the block above, set the need-sync flag for the page.
 38793         -        ** Otherwise, when the transaction is rolled back, the logic in
 38794         -        ** playback_one_page() will think that the page needs to be restored
 38795         -        ** in the database file. And if an IO error occurs while doing so,
 38796         -        ** then corruption may follow.
 38797         -        */
 38798         -        if( !pPager->noSync ){
 38799         -          pPg->flags |= PGHDR_NEED_SYNC;
 38800         -          pPager->needSync = 1;
 38801         -        }
 38802         -
 38803         -        /* An error has occurred writing to the journal file. The 
 38804         -        ** transaction will be rolled back by the layer above.
 38805         -        */
 38806         -        if( rc!=SQLITE_OK ){
 38807         -          return rc;
 38808         -        }
 38809         -
        39847  +        pPager->journalOff += 8 + pPager->pageSize;
 38810  39848           pPager->nRec++;
 38811  39849           assert( pPager->pInJournal!=0 );
 38812  39850           rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
 38813  39851           testcase( rc==SQLITE_NOMEM );
 38814  39852           assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
 38815  39853           rc |= addToSavepointBitvecs(pPager, pPg->pgno);
 38816  39854           if( rc!=SQLITE_OK ){
 38817  39855             assert( rc==SQLITE_NOMEM );
 38818  39856             return rc;
 38819  39857           }
 38820  39858         }else{
 38821         -        if( !pPager->journalStarted && !pPager->noSync ){
        39859  +        if( pPager->eState!=PAGER_WRITER_DBMOD ){
 38822  39860             pPg->flags |= PGHDR_NEED_SYNC;
 38823         -          pPager->needSync = 1;
 38824  39861           }
 38825  39862           PAGERTRACE(("APPEND %d page %d needSync=%d\n",
 38826  39863                   PAGERID(pPager), pPg->pgno,
 38827  39864                  ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
 38828  39865         }
 38829  39866       }
 38830  39867     
................................................................................
 38836  39873       if( subjRequiresPage(pPg) ){
 38837  39874         rc = subjournalPage(pPg);
 38838  39875       }
 38839  39876     }
 38840  39877   
 38841  39878     /* Update the database size and return.
 38842  39879     */
 38843         -  assert( pPager->state>=PAGER_SHARED );
 38844  39880     if( pPager->dbSize<pPg->pgno ){
 38845  39881       pPager->dbSize = pPg->pgno;
 38846  39882     }
 38847  39883     return rc;
 38848  39884   }
 38849  39885   
 38850  39886   /*
................................................................................
 38864  39900   SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
 38865  39901     int rc = SQLITE_OK;
 38866  39902   
 38867  39903     PgHdr *pPg = pDbPage;
 38868  39904     Pager *pPager = pPg->pPager;
 38869  39905     Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
 38870  39906   
        39907  +  assert( pPager->eState>=PAGER_WRITER_LOCKED );
        39908  +  assert( pPager->eState!=PAGER_ERROR );
        39909  +  assert( assert_pager_state(pPager) );
        39910  +
 38871  39911     if( nPagePerSector>1 ){
 38872  39912       Pgno nPageCount;          /* Total number of pages in database file */
 38873  39913       Pgno pg1;                 /* First page of the sector pPg is located on. */
 38874  39914       int nPage = 0;            /* Number of pages starting at pg1 to journal */
 38875  39915       int ii;                   /* Loop counter */
 38876  39916       int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */
 38877  39917   
................................................................................
 38885  39925   
 38886  39926       /* This trick assumes that both the page-size and sector-size are
 38887  39927       ** an integer power of 2. It sets variable pg1 to the identifier
 38888  39928       ** of the first page of the sector pPg is located on.
 38889  39929       */
 38890  39930       pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
 38891  39931   
 38892         -    rc = sqlite3PagerPagecount(pPager, (int *)&nPageCount);
 38893         -    if( rc==SQLITE_OK ){
 38894         -      if( pPg->pgno>nPageCount ){
 38895         -        nPage = (pPg->pgno - pg1)+1;
 38896         -      }else if( (pg1+nPagePerSector-1)>nPageCount ){
 38897         -        nPage = nPageCount+1-pg1;
 38898         -      }else{
 38899         -        nPage = nPagePerSector;
 38900         -      }
 38901         -      assert(nPage>0);
 38902         -      assert(pg1<=pPg->pgno);
 38903         -      assert((pg1+nPage)>pPg->pgno);
        39932  +    nPageCount = pPager->dbSize;
        39933  +    if( pPg->pgno>nPageCount ){
        39934  +      nPage = (pPg->pgno - pg1)+1;
        39935  +    }else if( (pg1+nPagePerSector-1)>nPageCount ){
        39936  +      nPage = nPageCount+1-pg1;
        39937  +    }else{
        39938  +      nPage = nPagePerSector;
 38904  39939       }
        39940  +    assert(nPage>0);
        39941  +    assert(pg1<=pPg->pgno);
        39942  +    assert((pg1+nPage)>pPg->pgno);
 38905  39943   
 38906  39944       for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
 38907  39945         Pgno pg = pg1+ii;
 38908  39946         PgHdr *pPage;
 38909  39947         if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
 38910  39948           if( pg!=PAGER_MJ_PGNO(pPager) ){
 38911  39949             rc = sqlite3PagerGet(pPager, pg, &pPage);
 38912  39950             if( rc==SQLITE_OK ){
 38913  39951               rc = pager_write(pPage);
 38914  39952               if( pPage->flags&PGHDR_NEED_SYNC ){
 38915  39953                 needSync = 1;
 38916         -              assert(pPager->needSync);
 38917  39954               }
 38918  39955               sqlite3PagerUnref(pPage);
 38919  39956             }
 38920  39957           }
 38921  39958         }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
 38922  39959           if( pPage->flags&PGHDR_NEED_SYNC ){
 38923  39960             needSync = 1;
................................................................................
 38929  39966       /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
 38930  39967       ** starting at pg1, then it needs to be set for all of them. Because
 38931  39968       ** writing to any of these nPage pages may damage the others, the
 38932  39969       ** journal file must contain sync()ed copies of all of them
 38933  39970       ** before any of them can be written out to the database file.
 38934  39971       */
 38935  39972       if( rc==SQLITE_OK && needSync ){
 38936         -      assert( !MEMDB && pPager->noSync==0 );
        39973  +      assert( !MEMDB );
 38937  39974         for(ii=0; ii<nPage; ii++){
 38938  39975           PgHdr *pPage = pager_lookup(pPager, pg1+ii);
 38939  39976           if( pPage ){
 38940  39977             pPage->flags |= PGHDR_NEED_SYNC;
 38941  39978             sqlite3PagerUnref(pPage);
 38942  39979           }
 38943  39980         }
 38944         -      assert(pPager->needSync);
 38945  39981       }
 38946  39982   
 38947  39983       assert( pPager->doNotSyncSpill==1 );
 38948  39984       pPager->doNotSyncSpill--;
 38949  39985     }else{
 38950  39986       rc = pager_write(pDbPage);
 38951  39987     }
................................................................................
 38979  40015   */
 38980  40016   SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
 38981  40017     Pager *pPager = pPg->pPager;
 38982  40018     if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
 38983  40019       PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
 38984  40020       IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
 38985  40021       pPg->flags |= PGHDR_DONT_WRITE;
 38986         -#ifdef SQLITE_CHECK_PAGES
 38987         -    pPg->pageHash = pager_pagehash(pPg);
 38988         -#endif
        40022  +    pager_set_pagehash(pPg);
 38989  40023     }
 38990  40024   }
 38991  40025   
 38992  40026   /*
 38993  40027   ** This routine is called to increment the value of the database file 
 38994  40028   ** change-counter, stored as a 4-byte big-endian integer starting at 
 38995  40029   ** byte offset 24 of the pager file.
................................................................................
 39003  40037   ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
 39004  40038   ** if isDirect is non-zero, then the database file is updated directly
 39005  40039   ** by writing an updated version of page 1 using a call to the 
 39006  40040   ** sqlite3OsWrite() function.
 39007  40041   */
 39008  40042   static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
 39009  40043     int rc = SQLITE_OK;
        40044  +
        40045  +  assert( pPager->eState==PAGER_WRITER_CACHEMOD
        40046  +       || pPager->eState==PAGER_WRITER_DBMOD
        40047  +  );
        40048  +  assert( assert_pager_state(pPager) );
 39010  40049   
 39011  40050     /* Declare and initialize constant integer 'isDirect'. If the
 39012  40051     ** atomic-write optimization is enabled in this build, then isDirect
 39013  40052     ** is initialized to the value passed as the isDirectMode parameter
 39014  40053     ** to this function. Otherwise, it is always set to zero.
 39015  40054     **
 39016  40055     ** The idea is that if the atomic-write optimization is not
................................................................................
 39022  40061   # define DIRECT_MODE 0
 39023  40062     assert( isDirectMode==0 );
 39024  40063     UNUSED_PARAMETER(isDirectMode);
 39025  40064   #else
 39026  40065   # define DIRECT_MODE isDirectMode
 39027  40066   #endif
 39028  40067   
 39029         -  assert( pPager->state>=PAGER_RESERVED );
 39030  40068     if( !pPager->changeCountDone && pPager->dbSize>0 ){
 39031  40069       PgHdr *pPgHdr;                /* Reference to page 1 */
 39032  40070       u32 change_counter;           /* Initial value of change-counter field */
 39033  40071   
 39034  40072       assert( !pPager->tempFile && isOpen(pPager->fd) );
 39035  40073   
 39036  40074       /* Open page 1 of the file for writing. */
................................................................................
 39107  40145   ** If the EXCLUSIVE lock is already held or the attempt to obtain it is
 39108  40146   ** successful, or the connection is in WAL mode, SQLITE_OK is returned.
 39109  40147   ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
 39110  40148   ** returned.
 39111  40149   */
 39112  40150   SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
 39113  40151     int rc = SQLITE_OK;
 39114         -  assert( pPager->state>=PAGER_RESERVED );
        40152  +  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
        40153  +       || pPager->eState==PAGER_WRITER_DBMOD 
        40154  +       || pPager->eState==PAGER_WRITER_LOCKED 
        40155  +  );
        40156  +  assert( assert_pager_state(pPager) );
 39115  40157     if( 0==pagerUseWal(pPager) ){
 39116         -    rc = pager_wait_on_lock(pPager, PAGER_EXCLUSIVE);
        40158  +    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
 39117  40159     }
 39118  40160     return rc;
 39119  40161   }
 39120  40162   
 39121  40163   /*
 39122  40164   ** Sync the database file for the pager pPager. zMaster points to the name
 39123  40165   ** of a master journal file that should be written into the individual
................................................................................
 39147  40189   SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
 39148  40190     Pager *pPager,                  /* Pager object */
 39149  40191     const char *zMaster,            /* If not NULL, the master journal name */
 39150  40192     int noSync                      /* True to omit the xSync on the db file */
 39151  40193   ){
 39152  40194     int rc = SQLITE_OK;             /* Return code */
 39153  40195   
 39154         -  /* The dbOrigSize is never set if journal_mode=OFF */
 39155         -  assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
        40196  +  assert( pPager->eState==PAGER_WRITER_LOCKED
        40197  +       || pPager->eState==PAGER_WRITER_CACHEMOD
        40198  +       || pPager->eState==PAGER_WRITER_DBMOD
        40199  +       || pPager->eState==PAGER_ERROR
        40200  +  );
        40201  +  assert( assert_pager_state(pPager) );
 39156  40202   
 39157  40203     /* If a prior error occurred, report that error again. */
 39158         -  if( pPager->errCode ) return pPager->errCode;
        40204  +  if( NEVER(pPager->errCode) ) return pPager->errCode;
 39159  40205   
 39160  40206     PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
 39161  40207         pPager->zFilename, zMaster, pPager->dbSize));
 39162  40208   
 39163         -  if( MEMDB && pPager->dbModified ){
        40209  +  /* If no database changes have been made, return early. */
        40210  +  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
        40211  +
        40212  +  if( MEMDB ){
 39164  40213       /* If this is an in-memory db, or no pages have been written to, or this
 39165  40214       ** function has already been called, it is mostly a no-op.  However, any
 39166  40215       ** backup in progress needs to be restarted.
 39167  40216       */
 39168  40217       sqlite3BackupRestart(pPager->pBackup);
 39169         -  }else if( pPager->dbModified ){
        40218  +  }else{
 39170  40219       if( pagerUseWal(pPager) ){
 39171  40220         PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
 39172  40221         if( pList ){
 39173  40222           rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, 
 39174  40223               (pPager->fullSync ? pPager->sync_flags : 0)
 39175  40224           );
 39176  40225         }
................................................................................
 39205  40254         PgHdr *pPg;
 39206  40255         assert( isOpen(pPager->jfd) 
 39207  40256              || pPager->journalMode==PAGER_JOURNALMODE_OFF 
 39208  40257              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
 39209  40258         );
 39210  40259         if( !zMaster && isOpen(pPager->jfd) 
 39211  40260          && pPager->journalOff==jrnlBufferSize(pPager) 
 39212         -       && pPager->dbSize>=pPager->dbFileSize
        40261  +       && pPager->dbSize>=pPager->dbOrigSize
 39213  40262          && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
 39214  40263         ){
 39215  40264           /* Update the db file change counter via the direct-write method. The 
 39216  40265           ** following call will modify the in-memory representation of page 1 
 39217  40266           ** to include the updated change counter and then write page 1 
 39218  40267           ** directly to the database file. Because of the atomic-write 
 39219  40268           ** property of the host file-system, this is safe.
................................................................................
 39235  40284         ** file. This can only happen in auto-vacuum mode.
 39236  40285         **
 39237  40286         ** Before reading the pages with page numbers larger than the 
 39238  40287         ** current value of Pager.dbSize, set dbSize back to the value
 39239  40288         ** that it took at the start of the transaction. Otherwise, the
 39240  40289         ** calls to sqlite3PagerGet() return zeroed pages instead of 
 39241  40290         ** reading data from the database file.
 39242         -      **
 39243         -      ** When journal_mode==OFF the dbOrigSize is always zero, so this
 39244         -      ** block never runs if journal_mode=OFF.
 39245  40291         */
 39246  40292     #ifndef SQLITE_OMIT_AUTOVACUUM
 39247  40293         if( pPager->dbSize<pPager->dbOrigSize 
 39248         -       && ALWAYS(pPager->journalMode!=PAGER_JOURNALMODE_OFF)
        40294  +       && pPager->journalMode!=PAGER_JOURNALMODE_OFF
 39249  40295         ){
 39250  40296           Pgno i;                                   /* Iterator variable */
 39251  40297           const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
 39252  40298           const Pgno dbSize = pPager->dbSize;       /* Database image size */ 
 39253  40299           pPager->dbSize = pPager->dbOrigSize;
 39254  40300           for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
 39255  40301             if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
................................................................................
 39268  40314         /* Write the master journal name into the journal file. If a master 
 39269  40315         ** journal file name has already been written to the journal file, 
 39270  40316         ** or if zMaster is NULL (no master journal), then this call is a no-op.
 39271  40317         */
 39272  40318         rc = writeMasterJournal(pPager, zMaster);
 39273  40319         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
 39274  40320     
 39275         -      /* Sync the journal file. If the atomic-update optimization is being
 39276         -      ** used, this call will not create the journal file or perform any
 39277         -      ** real IO.
        40321  +      /* Sync the journal file and write all dirty pages to the database.
        40322  +      ** If the atomic-update optimization is being used, this sync will not 
        40323  +      ** create the journal file or perform any real IO.
        40324  +      **
        40325  +      ** Because the change-counter page was just modified, unless the
        40326  +      ** atomic-update optimization is used it is almost certain that the
        40327  +      ** journal requires a sync here. However, in locking_mode=exclusive
        40328  +      ** on a system under memory pressure it is just possible that this is 
        40329  +      ** not the case. In this case it is likely enough that the redundant
        40330  +      ** xSync() call will be changed to a no-op by the OS anyhow. 
 39278  40331         */
 39279         -      rc = syncJournal(pPager);
        40332  +      rc = syncJournal(pPager, 0);
 39280  40333         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
 39281  40334     
 39282         -      /* Write all dirty pages to the database file. */
 39283  40335         rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
 39284  40336         if( rc!=SQLITE_OK ){
 39285  40337           assert( rc!=SQLITE_IOERR_BLOCKED );
 39286  40338           goto commit_phase_one_exit;
 39287  40339         }
 39288  40340         sqlite3PcacheCleanAll(pPager->pPCache);
 39289  40341     
 39290  40342         /* If the file on disk is not the same size as the database image,
 39291  40343         ** then use pager_truncate to grow or shrink the file here.
 39292  40344         */
 39293  40345         if( pPager->dbSize!=pPager->dbFileSize ){
 39294  40346           Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
 39295         -        assert( pPager->state>=PAGER_EXCLUSIVE );
        40347  +        assert( pPager->eState==PAGER_WRITER_DBMOD );
 39296  40348           rc = pager_truncate(pPager, nNew);
 39297  40349           if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
 39298  40350         }
 39299  40351     
 39300  40352         /* Finally, sync the database file. */
 39301  40353         if( !pPager->noSync && !noSync ){
 39302  40354           rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
 39303  40355         }
 39304  40356         IOTRACE(("DBSYNC %p\n", pPager))
 39305  40357       }
 39306         -
 39307         -    assert( pPager->state!=PAGER_SYNCED );
 39308         -    pPager->state = PAGER_SYNCED;
 39309  40358     }
 39310  40359   
 39311  40360   commit_phase_one_exit:
        40361  +  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
        40362  +    pPager->eState = PAGER_WRITER_FINISHED;
        40363  +  }
 39312  40364     return rc;
 39313  40365   }
 39314  40366   
 39315  40367   
 39316  40368   /*
 39317  40369   ** When this function is called, the database file has been completely
 39318  40370   ** updated to reflect the changes made by the current transaction and
................................................................................
 39332  40384     int rc = SQLITE_OK;                  /* Return code */
 39333  40385   
 39334  40386     /* This routine should not be called if a prior error has occurred.
 39335  40387     ** But if (due to a coding error elsewhere in the system) it does get
 39336  40388     ** called, just return the same error code without doing anything. */
 39337  40389     if( NEVER(pPager->errCode) ) return pPager->errCode;
 39338  40390   
 39339         -  /* This function should not be called if the pager is not in at least
 39340         -  ** PAGER_RESERVED state. **FIXME**: Make it so that this test always
 39341         -  ** fails - make it so that we never reach this point if we do not hold
 39342         -  ** all necessary locks.
 39343         -  */
 39344         -  if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR;
        40391  +  assert( pPager->eState==PAGER_WRITER_LOCKED
        40392  +       || pPager->eState==PAGER_WRITER_FINISHED
        40393  +       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
        40394  +  );
        40395  +  assert( assert_pager_state(pPager) );
 39345  40396   
 39346  40397     /* An optimization. If the database was not actually modified during
 39347  40398     ** this transaction, the pager is running in exclusive-mode and is
 39348  40399     ** using persistent journals, then this function is a no-op.
 39349  40400     **
 39350  40401     ** The start of the journal file currently contains a single journal 
 39351  40402     ** header with the nRec field set to 0. If such a journal is used as
 39352  40403     ** a hot-journal during hot-journal rollback, 0 changes will be made
 39353  40404     ** to the database file. So there is no need to zero the journal 
 39354  40405     ** header. Since the pager is in exclusive mode, there is no need
 39355  40406     ** to drop any locks either.
 39356  40407     */
 39357         -  if( pPager->dbModified==0 && pPager->exclusiveMode 
        40408  +  if( pPager->eState==PAGER_WRITER_LOCKED 
        40409  +   && pPager->exclusiveMode 
 39358  40410      && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
 39359  40411     ){
 39360  40412       assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
        40413  +    pPager->eState = PAGER_READER;
 39361  40414       return SQLITE_OK;
 39362  40415     }
 39363  40416   
 39364  40417     PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
 39365         -  assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified );
 39366  40418     rc = pager_end_transaction(pPager, pPager->setMaster);
 39367  40419     return pager_error(pPager, rc);
 39368  40420   }
 39369  40421   
 39370  40422   /*
 39371         -** Rollback all changes. The database falls back to PAGER_SHARED mode.
        40423  +** If a write transaction is open, then all changes made within the 
        40424  +** transaction are reverted and the current write-transaction is closed.
        40425  +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
        40426  +** state if an error occurs.
 39372  40427   **
 39373         -** This function performs two tasks:
        40428  +** If the pager is already in PAGER_ERROR state when this function is called,
        40429  +** it returns Pager.errCode immediately. No work is performed in this case.
        40430  +**
        40431  +** Otherwise, in rollback mode, this function performs two functions:
 39374  40432   **
 39375  40433   **   1) It rolls back the journal file, restoring all database file and 
 39376  40434   **      in-memory cache pages to the state they were in when the transaction
 39377  40435   **      was opened, and
        40436  +**
 39378  40437   **   2) It finalizes the journal file, so that it is not used for hot
 39379  40438   **      rollback at any point in the future.
 39380  40439   **
 39381         -** subject to the following qualifications:
        40440  +** Finalization of the journal file (task 2) is only performed if the 
        40441  +** rollback is successful.
 39382  40442   **
 39383         -** * If the journal file is not yet open when this function is called,
 39384         -**   then only (2) is performed. In this case there is no journal file
 39385         -**   to roll back.
 39386         -**
 39387         -** * If in an error state other than SQLITE_FULL, then task (1) is 
 39388         -**   performed. If successful, task (2). Regardless of the outcome
 39389         -**   of either, the error state error code is returned to the caller
 39390         -**   (i.e. either SQLITE_IOERR or SQLITE_CORRUPT).
 39391         -**
 39392         -** * If the pager is in PAGER_RESERVED state, then attempt (1). Whether
 39393         -**   or not (1) is successful, also attempt (2). If successful, return
 39394         -**   SQLITE_OK. Otherwise, enter the error state and return the first 
 39395         -**   error code encountered. 
 39396         -**
 39397         -**   In this case there is no chance that the database was written to. 
 39398         -**   So is safe to finalize the journal file even if the playback 
 39399         -**   (operation 1) failed. However the pager must enter the error state
 39400         -**   as the contents of the in-memory cache are now suspect.
 39401         -**
 39402         -** * Finally, if in PAGER_EXCLUSIVE state, then attempt (1). Only
 39403         -**   attempt (2) if (1) is successful. Return SQLITE_OK if successful,
 39404         -**   otherwise enter the error state and return the error code from the 
 39405         -**   failing operation.
 39406         -**
 39407         -**   In this case the database file may have been written to. So if the
 39408         -**   playback operation did not succeed it would not be safe to finalize
 39409         -**   the journal file. It needs to be left in the file-system so that
 39410         -**   some other process can use it to restore the database state (by
 39411         -**   hot-journal rollback).
        40443  +** In WAL mode, all cache-entries containing data modified within the
        40444  +** current transaction are either expelled from the cache or reverted to
        40445  +** their pre-transaction state by re-reading data from the database or
        40446  +** WAL files. The WAL transaction is then closed.
 39412  40447   */
 39413  40448   SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
 39414  40449     int rc = SQLITE_OK;                  /* Return code */
 39415  40450     PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
        40451  +
        40452  +  /* PagerRollback() is a no-op if called in READER or OPEN state. If
        40453  +  ** the pager is already in the ERROR state, the rollback is not 
        40454  +  ** attempted here. Instead, the error code is returned to the caller.
        40455  +  */
        40456  +  assert( assert_pager_state(pPager) );
        40457  +  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
        40458  +  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
        40459  +
 39416  40460     if( pagerUseWal(pPager) ){
 39417  40461       int rc2;
 39418         -
 39419  40462       rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
 39420  40463       rc2 = pager_end_transaction(pPager, pPager->setMaster);
 39421  40464       if( rc==SQLITE_OK ) rc = rc2;
 39422         -    rc = pager_error(pPager, rc);
 39423         -  }else if( !pPager->dbModified || !isOpen(pPager->jfd) ){
 39424         -    rc = pager_end_transaction(pPager, pPager->setMaster);
 39425         -  }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
 39426         -    if( pPager->state>=PAGER_EXCLUSIVE ){
 39427         -      pager_playback(pPager, 0);
 39428         -    }
 39429         -    rc = pPager->errCode;
 39430         -  }else{
 39431         -    if( pPager->state==PAGER_RESERVED ){
 39432         -      int rc2;
 39433         -      rc = pager_playback(pPager, 0);
 39434         -      rc2 = pager_end_transaction(pPager, pPager->setMaster);
 39435         -      if( rc==SQLITE_OK ){
 39436         -        rc = rc2;
 39437         -      }
 39438         -    }else{
 39439         -      rc = pager_playback(pPager, 0);
 39440         -    }
 39441         -
 39442         -    if( !MEMDB ){
 39443         -      pPager->dbSizeValid = 0;
 39444         -    }
 39445         -
 39446         -    /* If an error occurs during a ROLLBACK, we can no longer trust the pager
 39447         -    ** cache. So call pager_error() on the way out to make any error 
 39448         -    ** persistent.
 39449         -    */
 39450         -    rc = pager_error(pPager, rc);
 39451         -  }
 39452         -  return rc;
        40465  +  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
        40466  +    rc = pager_end_transaction(pPager, 0);
        40467  +  }else{
        40468  +    rc = pager_playback(pPager, 0);
        40469  +  }
        40470  +
        40471  +  assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
        40472  +  assert( rc==SQLITE_OK || rc==SQLITE_FULL || (rc&0xFF)==SQLITE_IOERR );
        40473  +
        40474  +  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
        40475  +  ** cache. So call pager_error() on the way out to make any error persistent.
        40476  +  */
        40477  +  return pager_error(pPager, rc);
 39453  40478   }
 39454  40479   
 39455  40480   /*
 39456  40481   ** Return TRUE if the database file is opened read-only.  Return FALSE
 39457  40482   ** if the database is (in theory) writable.
 39458  40483   */
 39459  40484   SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
................................................................................
 39491  40516   ** This routine is used for testing and analysis only.
 39492  40517   */
 39493  40518   SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
 39494  40519     static int a[11];
 39495  40520     a[0] = sqlite3PcacheRefCount(pPager->pPCache);
 39496  40521     a[1] = sqlite3PcachePagecount(pPager->pPCache);
 39497  40522     a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
 39498         -  a[3] = pPager->dbSizeValid ? (int) pPager->dbSize : -1;
 39499         -  a[4] = pPager->state;
        40523  +  a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
        40524  +  a[4] = pPager->eState;
 39500  40525     a[5] = pPager->errCode;
 39501  40526     a[6] = pPager->nHit;
 39502  40527     a[7] = pPager->nMiss;
 39503  40528     a[8] = 0;  /* Used to be pPager->nOvfl */
 39504  40529     a[9] = pPager->nRead;
 39505  40530     a[10] = pPager->nWrite;
 39506  40531     return a;
................................................................................
 39523  40548   ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 
 39524  40549   ** occurs while opening the sub-journal file, then an IO error code is
 39525  40550   ** returned. Otherwise, SQLITE_OK.
 39526  40551   */
 39527  40552   SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
 39528  40553     int rc = SQLITE_OK;                       /* Return code */
 39529  40554     int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
        40555  +
        40556  +  assert( pPager->eState>=PAGER_WRITER_LOCKED );
        40557  +  assert( assert_pager_state(pPager) );
 39530  40558   
 39531  40559     if( nSavepoint>nCurrent && pPager->useJournal ){
 39532  40560       int ii;                                 /* Iterator variable */
 39533  40561       PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
 39534         -    int nPage;                              /* Size of database file */
 39535         -
 39536         -    rc = sqlite3PagerPagecount(pPager, &nPage);
 39537         -    if( rc ) return rc;
 39538  40562   
 39539  40563       /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
 39540  40564       ** if the allocation fails. Otherwise, zero the new portion in case a 
 39541  40565       ** malloc failure occurs while populating it in the for(...) loop below.
 39542  40566       */
 39543  40567       aNew = (PagerSavepoint *)sqlite3Realloc(
 39544  40568           pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
................................................................................
 39547  40571         return SQLITE_NOMEM;
 39548  40572       }
 39549  40573       memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
 39550  40574       pPager->aSavepoint = aNew;
 39551  40575   
 39552  40576       /* Populate the PagerSavepoint structures just allocated. */
 39553  40577       for(ii=nCurrent; ii<nSavepoint; ii++){
 39554         -      aNew[ii].nOrig = nPage;
        40578  +      aNew[ii].nOrig = pPager->dbSize;
 39555  40579         if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
 39556  40580           aNew[ii].iOffset = pPager->journalOff;
 39557  40581         }else{
 39558  40582           aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
 39559  40583         }
 39560  40584         aNew[ii].iSubRec = pPager->nSubRec;
 39561         -      aNew[ii].pInSavepoint = sqlite3BitvecCreate(nPage);
        40585  +      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
 39562  40586         if( !aNew[ii].pInSavepoint ){
 39563  40587           return SQLITE_NOMEM;
 39564  40588         }
 39565  40589         if( pagerUseWal(pPager) ){
 39566  40590           sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
 39567  40591         }
 39568  40592         pPager->nSavepoint = ii+1;
................................................................................
 39601  40625   ** then savepoint iSavepoint is also destroyed.
 39602  40626   **
 39603  40627   ** This function may return SQLITE_NOMEM if a memory allocation fails,
 39604  40628   ** or an IO error code if an IO error occurs while rolling back a 
 39605  40629   ** savepoint. If no errors occur, SQLITE_OK is returned.
 39606  40630   */ 
 39607  40631   SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
 39608         -  int rc = SQLITE_OK;
        40632  +  int rc = pPager->errCode;       /* Return code */
 39609  40633   
 39610  40634     assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
 39611  40635     assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
 39612  40636   
 39613         -  if( iSavepoint<pPager->nSavepoint ){
        40637  +  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
 39614  40638       int ii;            /* Iterator variable */
 39615  40639       int nNew;          /* Number of remaining savepoints after this op. */
 39616  40640   
 39617  40641       /* Figure out how many savepoints will still be active after this
 39618  40642       ** operation. Store this value in nNew. Then free resources associated 
 39619  40643       ** with any savepoints that are destroyed by this operation.
 39620  40644       */
................................................................................
 39642  40666       ** the database file, so the playback operation can be skipped.
 39643  40667       */
 39644  40668       else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
 39645  40669         PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
 39646  40670         rc = pagerPlaybackSavepoint(pPager, pSavepoint);
 39647  40671         assert(rc!=SQLITE_DONE);
 39648  40672       }
 39649         -  
 39650  40673     }
        40674  +
 39651  40675     return rc;
 39652  40676   }
 39653  40677   
 39654  40678   /*
 39655  40679   ** Return the full pathname of the database file.
 39656  40680   */
 39657  40681   SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager){
................................................................................
 39741  40765   SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
 39742  40766     PgHdr *pPgOld;               /* The page being overwritten. */
 39743  40767     Pgno needSyncPgno = 0;       /* Old value of pPg->pgno, if sync is required */
 39744  40768     int rc;                      /* Return code */
 39745  40769     Pgno origPgno;               /* The original page number */
 39746  40770   
 39747  40771     assert( pPg->nRef>0 );
        40772  +  assert( pPager->eState==PAGER_WRITER_CACHEMOD
        40773  +       || pPager->eState==PAGER_WRITER_DBMOD
        40774  +  );
        40775  +  assert( assert_pager_state(pPager) );
 39748  40776   
 39749  40777     /* In order to be able to rollback, an in-memory database must journal
 39750  40778     ** the page we are moving from.
 39751  40779     */
 39752  40780     if( MEMDB ){
 39753  40781       rc = sqlite3PagerWrite(pPg);
 39754  40782       if( rc ) return rc;
................................................................................
 39790  40818     ** the journal needs to be sync()ed before database page pPg->pgno 
 39791  40819     ** can be written to. The caller has already promised not to write to it.
 39792  40820     */
 39793  40821     if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
 39794  40822       needSyncPgno = pPg->pgno;
 39795  40823       assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
 39796  40824       assert( pPg->flags&PGHDR_DIRTY );
 39797         -    assert( pPager->needSync );
 39798  40825     }
 39799  40826   
 39800  40827     /* If the cache contains a page with page-number pgno, remove it
 39801         -  ** from its hash chain. Also, if the PgHdr.needSync was set for 
        40828  +  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
 39802  40829     ** page pgno before the 'move' operation, it needs to be retained 
 39803  40830     ** for the page moved there.
 39804  40831     */
 39805  40832     pPg->flags &= ~PGHDR_NEED_SYNC;
 39806  40833     pPgOld = pager_lookup(pPager, pgno);
 39807  40834     assert( !pPgOld || pPgOld->nRef==1 );
 39808  40835     if( pPgOld ){
 39809  40836       pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
 39810  40837       if( MEMDB ){
 39811  40838         /* Do not discard pages from an in-memory database since we might
 39812  40839         ** need to rollback later.  Just move the page out of the way. */
 39813         -      assert( pPager->dbSizeValid );
 39814  40840         sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
 39815  40841       }else{
 39816  40842         sqlite3PcacheDrop(pPgOld);
 39817  40843       }
 39818  40844     }
 39819  40845   
 39820  40846     origPgno = pPg->pgno;
 39821  40847     sqlite3PcacheMove(pPg, pgno);
 39822  40848     sqlite3PcacheMakeDirty(pPg);
 39823         -  pPager->dbModified = 1;
        40849  +
        40850  +  /* For an in-memory database, make sure the original page continues
        40851  +  ** to exist, in case the transaction needs to roll back.  Use pPgOld
        40852  +  ** as the original page since it has already been allocated.
        40853  +  */
        40854  +  if( MEMDB ){
        40855  +    assert( pPgOld );
        40856  +    sqlite3PcacheMove(pPgOld, origPgno);
        40857  +    sqlite3PagerUnref(pPgOld);
        40858  +  }
 39824  40859   
 39825  40860     if( needSyncPgno ){
 39826  40861       /* If needSyncPgno is non-zero, then the journal file needs to be 
 39827  40862       ** sync()ed before any data is written to database file page needSyncPgno.
 39828  40863       ** Currently, no such page exists in the page-cache and the 
 39829  40864       ** "is journaled" bitvec flag has been set. This needs to be remedied by
 39830         -    ** loading the page into the pager-cache and setting the PgHdr.needSync 
        40865  +    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
 39831  40866       ** flag.
 39832  40867       **
 39833  40868       ** If the attempt to load the page into the page-cache fails, (due
 39834  40869       ** to a malloc() or IO failure), clear the bit in the pInJournal[]
 39835  40870       ** array. Otherwise, if the page is loaded and written again in
 39836  40871       ** this transaction, it may be written to the database file before
 39837  40872       ** it is synced into the journal file. This way, it may end up in
 39838  40873       ** the journal file twice, but that is not a problem.
 39839         -    **
 39840         -    ** The sqlite3PagerGet() call may cause the journal to sync. So make
 39841         -    ** sure the Pager.needSync flag is set too.
 39842  40874       */
 39843  40875       PgHdr *pPgHdr;
 39844         -    assert( pPager->needSync );
 39845  40876       rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
 39846  40877       if( rc!=SQLITE_OK ){
 39847  40878         if( needSyncPgno<=pPager->dbOrigSize ){
 39848  40879           assert( pPager->pTmpSpace!=0 );
 39849  40880           sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
 39850  40881         }
 39851  40882         return rc;
 39852  40883       }
 39853         -    pPager->needSync = 1;
 39854         -    assert( pPager->noSync==0 && !MEMDB );
 39855  40884       pPgHdr->flags |= PGHDR_NEED_SYNC;
 39856  40885       sqlite3PcacheMakeDirty(pPgHdr);
 39857  40886       sqlite3PagerUnref(pPgHdr);
 39858  40887     }
 39859  40888   
 39860         -  /*
 39861         -  ** For an in-memory database, make sure the original page continues
 39862         -  ** to exist, in case the transaction needs to roll back.  Use pPgOld
 39863         -  ** as the original page since it has already been allocated.
 39864         -  */
 39865         -  if( MEMDB ){
 39866         -    sqlite3PcacheMove(pPgOld, origPgno);
 39867         -    sqlite3PagerUnref(pPgOld);
 39868         -  }
 39869         -
 39870  40889     return SQLITE_OK;
 39871  40890   }
 39872  40891   #endif
 39873  40892   
 39874  40893   /*
 39875  40894   ** Return a pointer to the data for the specified page.
 39876  40895   */
................................................................................
 39927  40946   **
 39928  40947   **   *  Temporary databases cannot have _WAL journalmode.
 39929  40948   **
 39930  40949   ** The returned indicate the current (possibly updated) journal-mode.
 39931  40950   */
 39932  40951   SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
 39933  40952     u8 eOld = pPager->journalMode;    /* Prior journalmode */
        40953  +
        40954  +#ifdef SQLITE_DEBUG
        40955  +  /* The print_pager_state() routine is intended to be used by the debugger
        40956  +  ** only.  We invoke it once here to suppress a compiler warning. */
        40957  +  print_pager_state(pPager);
        40958  +#endif
        40959  +
 39934  40960   
 39935  40961     /* The eMode parameter is always valid */
 39936  40962     assert(      eMode==PAGER_JOURNALMODE_DELETE
 39937  40963               || eMode==PAGER_JOURNALMODE_TRUNCATE
 39938  40964               || eMode==PAGER_JOURNALMODE_PERSIST
 39939  40965               || eMode==PAGER_JOURNALMODE_OFF 
 39940  40966               || eMode==PAGER_JOURNALMODE_WAL 
................................................................................
 39953  40979       assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
 39954  40980       if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
 39955  40981         eMode = eOld;
 39956  40982       }
 39957  40983     }
 39958  40984   
 39959  40985     if( eMode!=eOld ){
 39960         -    /* When changing between rollback modes, close the journal file prior
 39961         -    ** to the change.  But when changing from a rollback mode to WAL, keep
 39962         -    ** the journal open since there is a rollback-style transaction in play
 39963         -    ** used to convert the version numbers in the btree header.
 39964         -    */
 39965         -    if( isOpen(pPager->jfd) && eMode!=PAGER_JOURNALMODE_WAL ){
 39966         -      sqlite3OsClose(pPager->jfd);
 39967         -    }
 39968  40986   
 39969  40987       /* Change the journal mode. */
        40988  +    assert( pPager->eState!=PAGER_ERROR );
 39970  40989       pPager->journalMode = (u8)eMode;
 39971  40990   
 39972  40991       /* When transistioning from TRUNCATE or PERSIST to any other journal
 39973         -    ** mode except WAL (and we are not in locking_mode=EXCLUSIVE) then 
        40992  +    ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
 39974  40993       ** delete the journal file.
 39975  40994       */
 39976  40995       assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
 39977  40996       assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
 39978  40997       assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
 39979  40998       assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
 39980  40999       assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
................................................................................
 39987  41006         ** not possible, then that is not a problem. Deleting the journal file
 39988  41007         ** here is an optimization only.
 39989  41008         **
 39990  41009         ** Before deleting the journal file, obtain a RESERVED lock on the
 39991  41010         ** database file. This ensures that the journal file is not deleted
 39992  41011         ** while it is in use by some other client.
 39993  41012         */
 39994         -      int rc = SQLITE_OK;
 39995         -      int state = pPager->state;
 39996         -      if( state<PAGER_SHARED ){
 39997         -        rc = sqlite3PagerSharedLock(pPager);
 39998         -      }
 39999         -      if( pPager->state==PAGER_SHARED ){
 40000         -        assert( rc==SQLITE_OK );
 40001         -        rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
 40002         -      }
 40003         -      if( rc==SQLITE_OK ){
        41013  +      sqlite3OsClose(pPager->jfd);
        41014  +      if( pPager->eLock>=RESERVED_LOCK ){
 40004  41015           sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
        41016  +      }else{
        41017  +        int rc = SQLITE_OK;
        41018  +        int state = pPager->eState;
        41019  +        assert( state==PAGER_OPEN || state==PAGER_READER );
        41020  +        if( state==PAGER_OPEN ){
        41021  +          rc = sqlite3PagerSharedLock(pPager);
        41022  +        }
        41023  +        if( pPager->eState==PAGER_READER ){
        41024  +          assert( rc==SQLITE_OK );
        41025  +          rc = pagerLockDb(pPager, RESERVED_LOCK);
        41026  +        }
        41027  +        if( rc==SQLITE_OK ){
        41028  +          sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
        41029  +        }
        41030  +        if( rc==SQLITE_OK && state==PAGER_READER ){
        41031  +          pagerUnlockDb(pPager, SHARED_LOCK);
        41032  +        }else if( state==PAGER_OPEN ){
        41033  +          pager_unlock(pPager);
        41034  +        }
        41035  +        assert( state==pPager->eState );
 40005  41036         }
 40006         -      if( rc==SQLITE_OK && state==PAGER_SHARED ){
 40007         -        sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
 40008         -      }else if( state==PAGER_UNLOCK ){
 40009         -        pager_unlock(pPager);
 40010         -      }
 40011         -      assert( state==pPager->state );
 40012  41037       }
 40013  41038     }
 40014  41039   
 40015  41040     /* Return the new journal mode */
 40016  41041     return (int)pPager->journalMode;
 40017  41042   }
 40018  41043   
................................................................................
 40025  41050   
 40026  41051   /*
 40027  41052   ** Return TRUE if the pager is in a state where it is OK to change the
 40028  41053   ** journalmode.  Journalmode changes can only happen when the database
 40029  41054   ** is unmodified.
 40030  41055   */
 40031  41056   SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
 40032         -  if( pPager->dbModified ) return 0;
        41057  +  assert( assert_pager_state(pPager) );
        41058  +  if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
 40033  41059     if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
 40034  41060     return 1;
 40035  41061   }
 40036  41062   
 40037  41063   /*
 40038  41064   ** Get/set the size-limit used for persistent journal files.
 40039  41065   **
................................................................................
 40090  41116   ** The caller must be holding a SHARED lock on the database file to call
 40091  41117   ** this function.
 40092  41118   **
 40093  41119   ** If the pager passed as the first argument is open on a real database
 40094  41120   ** file (not a temp file or an in-memory database), and the WAL file
 40095  41121   ** is not already open, make an attempt to open it now. If successful,
 40096  41122   ** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
 40097         -** not support the xShmXXX() methods, return an error code. *pisOpen is
        41123  +** not support the xShmXXX() methods, return an error code. *pbOpen is
 40098  41124   ** not modified in either case.
 40099  41125   **
 40100  41126   ** If the pager is open on a temp-file (or in-memory database), or if
 40101         -** the WAL file is already open, set *pisOpen to 1 and return SQLITE_OK
        41127  +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
 40102  41128   ** without doing anything.
 40103  41129   */
 40104  41130   SQLITE_PRIVATE int sqlite3PagerOpenWal(
 40105  41131     Pager *pPager,                  /* Pager object */
 40106         -  int *pisOpen                    /* OUT: Set to true if call is a no-op */
        41132  +  int *pbOpen                     /* OUT: Set to true if call is a no-op */
 40107  41133   ){
 40108  41134     int rc = SQLITE_OK;             /* Return code */
 40109  41135   
 40110         -  assert( pPager->state>=PAGER_SHARED );
 40111         -  assert( (pisOpen==0 && !pPager->tempFile && !pPager->pWal) || *pisOpen==0 );
        41136  +  assert( assert_pager_state(pPager) );
        41137  +  assert( pPager->eState==PAGER_OPEN   || pbOpen );
        41138  +  assert( pPager->eState==PAGER_READER || !pbOpen );
        41139  +  assert( pbOpen==0 || *pbOpen==0 );
        41140  +  assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
 40112  41141   
 40113  41142     if( !pPager->tempFile && !pPager->pWal ){
 40114  41143       if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
        41144  +
        41145  +    /* Close any rollback journal previously open */
        41146  +    sqlite3OsClose(pPager->jfd);
 40115  41147   
 40116  41148       /* Open the connection to the log file. If this operation fails, 
 40117  41149       ** (e.g. due to malloc() failure), unlock the database file and 
 40118  41150       ** return an error code.
 40119  41151       */
 40120  41152       rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal);
 40121  41153       if( rc==SQLITE_OK ){
 40122  41154         pPager->journalMode = PAGER_JOURNALMODE_WAL;
        41155  +      pPager->eState = PAGER_OPEN;
 40123  41156       }
 40124  41157     }else{
 40125         -    *pisOpen = 1;
        41158  +    *pbOpen = 1;
 40126  41159     }
 40127  41160   
 40128  41161     return rc;
 40129  41162   }
 40130  41163   
 40131  41164   /*
 40132  41165   ** This function is called to close the connection to the log file prior
................................................................................
 40144  41177   
 40145  41178     /* If the log file is not already open, but does exist in the file-system,
 40146  41179     ** it may need to be checkpointed before the connection can switch to
 40147  41180     ** rollback mode. Open it now so this can happen.
 40148  41181     */
 40149  41182     if( !pPager->pWal ){
 40150  41183       int logexists = 0;
 40151         -    rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED);
        41184  +    rc = pagerLockDb(pPager, SHARED_LOCK);
 40152  41185       if( rc==SQLITE_OK ){
 40153  41186         rc = sqlite3OsAccess(
 40154  41187             pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
 40155  41188         );
 40156  41189       }
 40157  41190       if( rc==SQLITE_OK && logexists ){
 40158  41191         rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
................................................................................
 40160  41193       }
 40161  41194     }
 40162  41195       
 40163  41196     /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
 40164  41197     ** the database file, the log and log-summary files will be deleted.
 40165  41198     */
 40166  41199     if( rc==SQLITE_OK && pPager->pWal ){
 40167         -    rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_EXCLUSIVE);
        41200  +    rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
 40168  41201       if( rc==SQLITE_OK ){
 40169  41202         rc = sqlite3WalClose(pPager->pWal,
 40170  41203                              (pPager->noSync ? 0 : pPager->sync_flags), 
 40171  41204           pPager->pageSize, (u8*)pPager->pTmpSpace
 40172  41205         );
 40173  41206         pPager->pWal = 0;
 40174  41207       }else{
 40175  41208         /* If we cannot get an EXCLUSIVE lock, downgrade the PENDING lock
 40176  41209         ** that we did get back to SHARED. */
 40177         -      sqlite3OsUnlock(pPager->fd, SQLITE_LOCK_SHARED);
        41210  +      pagerUnlockDb(pPager, SQLITE_LOCK_SHARED);
 40178  41211       }
 40179  41212     }
 40180  41213     return rc;
 40181  41214   }
 40182  41215   
 40183  41216   #ifdef SQLITE_HAS_CODEC
 40184  41217   /*
................................................................................
 40490  41523   
 40491  41524   
 40492  41525   /*
 40493  41526   ** The following object holds a copy of the wal-index header content.
 40494  41527   **
 40495  41528   ** The actual header in the wal-index consists of two copies of this
 40496  41529   ** object.
        41530  +**
        41531  +** The szPage value can be any power of 2 between 512 and 32768, inclusive.
        41532  +** Or it can be 1 to represent a 65536-byte page.  The latter case was
        41533  +** added in 3.7.1 when support for 64K pages was added.  
 40497  41534   */
 40498  41535   struct WalIndexHdr {
 40499  41536     u32 iVersion;                   /* Wal-index version */
 40500  41537     u32 unused;                     /* Unused (padding) field */
 40501  41538     u32 iChange;                    /* Counter incremented each transaction */
 40502  41539     u8 isInit;                      /* 1 when initialized */
 40503  41540     u8 bigEndCksum;                 /* True if checksums in WAL are big-endian */
 40504         -  u16 szPage;                     /* Database page size in bytes */
        41541  +  u16 szPage;                     /* Database page size in bytes. 1==64K */
 40505  41542     u32 mxFrame;                    /* Index of last valid frame in the WAL */
 40506  41543     u32 nPage;                      /* Size of database in pages */
 40507  41544     u32 aFrameCksum[2];             /* Checksum of last frame in log */
 40508  41545     u32 aSalt[2];                   /* Two salt values copied from WAL header */
 40509  41546     u32 aCksum[2];                  /* Checksum over all prior fields */
 40510  41547   };
 40511  41548   
................................................................................
 40608  41645   struct Wal {
 40609  41646     sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
 40610  41647     sqlite3_file *pDbFd;       /* File handle for the database file */
 40611  41648     sqlite3_file *pWalFd;      /* File handle for WAL file */
 40612  41649     u32 iCallback;             /* Value to pass to log callback (or 0) */
 40613  41650     int nWiData;               /* Size of array apWiData */
 40614  41651     volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
 40615         -  u16 szPage;                /* Database page size */
        41652  +  u32 szPage;                /* Database page size */
 40616  41653     i16 readLock;              /* Which read lock is being held.  -1 for none */
 40617  41654     u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
 40618  41655     u8 writeLock;              /* True if in a write transaction */
 40619  41656     u8 ckptLock;               /* True if holding a checkpoint lock */
 40620  41657     u8 readOnly;               /* True if the WAL file is open read-only */
 40621  41658     WalIndexHdr hdr;           /* Wal-index header for current transaction */
 40622  41659     const char *zWalName;      /* Name of WAL file */
................................................................................
 41279  42316        || szPage&(szPage-1) 
 41280  42317        || szPage>SQLITE_MAX_PAGE_SIZE 
 41281  42318        || szPage<512 
 41282  42319       ){
 41283  42320         goto finished;
 41284  42321       }
 41285  42322       pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
 41286         -    pWal->szPage = (u16)szPage;
        42323  +    pWal->szPage = szPage;
 41287  42324       pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
 41288  42325       memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
 41289  42326   
 41290  42327       /* Verify that the WAL header checksum is correct */
 41291  42328       walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
 41292  42329           aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
 41293  42330       );
................................................................................
 41329  42366         rc = walIndexAppend(pWal, ++iFrame, pgno);
 41330  42367         if( rc!=SQLITE_OK ) break;
 41331  42368   
 41332  42369         /* If nTruncate is non-zero, this is a commit record. */
 41333  42370         if( nTruncate ){
 41334  42371           pWal->hdr.mxFrame = iFrame;
 41335  42372           pWal->hdr.nPage = nTruncate;
 41336         -        pWal->hdr.szPage = (u16)szPage;
        42373  +        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
        42374  +        testcase( szPage<=32768 );
        42375  +        testcase( szPage>=65536 );
 41337  42376           aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
 41338  42377           aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
 41339  42378         }
 41340  42379       }
 41341  42380   
 41342  42381       sqlite3_free(aFrame);
 41343  42382     }
................................................................................
 41354  42393       ** currently holding locks that exclude all other readers, writers and
 41355  42394       ** checkpointers.
 41356  42395       */
 41357  42396       pInfo = walCkptInfo(pWal);
 41358  42397       pInfo->nBackfill = 0;
 41359  42398       pInfo->aReadMark[0] = 0;
 41360  42399       for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
        42400  +
        42401  +    /* If more than one frame was recovered from the log file, report an
        42402  +    ** event via sqlite3_log(). This is to help with identifying performance
        42403  +    ** problems caused by applications routinely shutting down without
        42404  +    ** checkpointing the log file.
        42405  +    */
        42406  +    if( pWal->hdr.nPage ){
        42407  +      sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
        42408  +          pWal->hdr.nPage, pWal->zWalName
        42409  +      );
        42410  +    }
 41361  42411     }
 41362  42412   
 41363  42413   recovery_error:
 41364  42414     WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
 41365  42415     walUnlockExclusive(pWal, iLock, nLock);
 41366  42416     return rc;
 41367  42417   }
................................................................................
 41714  42764   static int walCheckpoint(
 41715  42765     Wal *pWal,                      /* Wal connection */
 41716  42766     int sync_flags,                 /* Flags for OsSync() (or 0) */
 41717  42767     int nBuf,                       /* Size of zBuf in bytes */
 41718  42768     u8 *zBuf                        /* Temporary buffer to use */
 41719  42769   ){
 41720  42770     int rc;                         /* Return code */
 41721         -  int szPage = pWal->hdr.szPage;  /* Database page-size */
        42771  +  int szPage;                     /* Database page-size */
 41722  42772     WalIterator *pIter = 0;         /* Wal iterator context */
 41723  42773     u32 iDbpage = 0;                /* Next database page to write */
 41724  42774     u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
 41725  42775     u32 mxSafeFrame;                /* Max frame that can be backfilled */
        42776  +  u32 mxPage;                     /* Max database page to write */
 41726  42777     int i;                          /* Loop counter */
 41727  42778     volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
 41728  42779   
        42780  +  szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
        42781  +  testcase( szPage<=32768 );
        42782  +  testcase( szPage>=65536 );
 41729  42783     if( pWal->hdr.mxFrame==0 ) return SQLITE_OK;
 41730  42784   
 41731  42785     /* Allocate the iterator */
 41732  42786     rc = walIteratorInit(pWal, &pIter);
 41733  42787     if( rc!=SQLITE_OK ){
 41734  42788       return rc;
 41735  42789     }
 41736  42790     assert( pIter );
 41737  42791   
 41738  42792     /*** TODO:  Move this test out to the caller.  Make it an assert() here ***/
 41739         -  if( pWal->hdr.szPage!=nBuf ){
        42793  +  if( szPage!=nBuf ){
 41740  42794       rc = SQLITE_CORRUPT_BKPT;
 41741  42795       goto walcheckpoint_out;
 41742  42796     }
 41743  42797   
 41744  42798     /* Compute in mxSafeFrame the index of the last frame of the WAL that is
 41745  42799     ** safe to write into the database.  Frames beyond mxSafeFrame might
 41746  42800     ** overwrite database pages that are in use by active readers and thus
 41747  42801     ** cannot be backfilled from the WAL.
 41748  42802     */
 41749  42803     mxSafeFrame = pWal->hdr.mxFrame;
        42804  +  mxPage = pWal->hdr.nPage;
 41750  42805     pInfo = walCkptInfo(pWal);
 41751  42806     for(i=1; i<WAL_NREADER; i++){
 41752  42807       u32 y = pInfo->aReadMark[i];
 41753  42808       if( mxSafeFrame>=y ){
 41754  42809         assert( y<=pWal->hdr.mxFrame );
 41755  42810         rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
 41756  42811         if( rc==SQLITE_OK ){
................................................................................
 41763  42818         }
 41764  42819       }
 41765  42820     }
 41766  42821   
 41767  42822     if( pInfo->nBackfill<mxSafeFrame
 41768  42823      && (rc = walLockExclusive(pWal, WAL_READ_LOCK(0), 1))==SQLITE_OK
 41769  42824     ){
        42825  +    i64 nSize;                    /* Current size of database file */
 41770  42826       u32 nBackfill = pInfo->nBackfill;
 41771  42827   
 41772  42828       /* Sync the WAL to disk */
 41773  42829       if( sync_flags ){
 41774  42830         rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
 41775  42831       }
        42832  +
        42833  +    /* If the database file may grow as a result of this checkpoint, hint
        42834  +    ** about the eventual size of the db file to the VFS layer. 
        42835  +    */
        42836  +    if( rc==SQLITE_OK ){
        42837  +      i64 nReq = ((i64)mxPage * szPage);
        42838  +      rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
        42839  +      if( rc==SQLITE_OK && nSize<nReq ){
        42840  +        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
        42841  +      }
        42842  +    }
 41776  42843   
 41777  42844       /* Iterate through the contents of the WAL, copying data to the db file. */
 41778  42845       while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
 41779  42846         i64 iOffset;
 41780  42847         assert( walFramePgno(pWal, iFrame)==iDbpage );
 41781         -      if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue;
        42848  +      if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
 41782  42849         iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
 41783  42850         /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
 41784  42851         rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
 41785  42852         if( rc!=SQLITE_OK ) break;
 41786  42853         iOffset = (iDbpage-1)*(i64)szPage;
 41787  42854         testcase( IS_BIG_INT(iOffset) );
 41788  42855         rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
................................................................................
 41881  42948     u32 aCksum[2];                  /* Checksum on the header content */
 41882  42949     WalIndexHdr h1, h2;             /* Two copies of the header content */
 41883  42950     WalIndexHdr volatile *aHdr;     /* Header in shared memory */
 41884  42951   
 41885  42952     /* The first page of the wal-index must be mapped at this point. */
 41886  42953     assert( pWal->nWiData>0 && pWal->apWiData[0] );
 41887  42954   
 41888         -  /* Read the header. This might happen currently with a write to the
        42955  +  /* Read the header. This might happen concurrently with a write to the
 41889  42956     ** same area of shared memory on a different CPU in a SMP,
 41890  42957     ** meaning it is possible that an inconsistent snapshot is read
 41891  42958     ** from the file. If this happens, return non-zero.
 41892  42959     **
 41893  42960     ** There are two copies of the header at the beginning of the wal-index.
 41894  42961     ** When reading, read [0] first then [1].  Writes are in the reverse order.
 41895  42962     ** Memory barriers are used to prevent the compiler or the hardware from
................................................................................
 41910  42977     if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
 41911  42978       return 1;   /* Checksum does not match */
 41912  42979     }
 41913  42980   
 41914  42981     if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
 41915  42982       *pChanged = 1;
 41916  42983       memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
 41917         -    pWal->szPage = pWal->hdr.szPage;
        42984  +    pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
        42985  +    testcase( pWal->szPage<=32768 );
        42986  +    testcase( pWal->szPage>=65536 );
 41918  42987     }
 41919  42988   
 41920  42989     /* The header was successfully read. Return zero. */
 41921  42990     return 0;
 41922  42991   }
 41923  42992   
 41924  42993   /*
................................................................................
 42229  43298   }
 42230  43299   
 42231  43300   /*
 42232  43301   ** Finish with a read transaction.  All this does is release the
 42233  43302   ** read-lock.
 42234  43303   */
 42235  43304   SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
        43305  +  sqlite3WalEndWriteTransaction(pWal);
 42236  43306     if( pWal->readLock>=0 ){
 42237  43307       walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
 42238  43308       pWal->readLock = -1;
 42239  43309     }
 42240  43310   }
 42241  43311   
 42242  43312   /*
................................................................................
 42339  43409     }
 42340  43410   #endif
 42341  43411   
 42342  43412     /* If iRead is non-zero, then it is the log frame number that contains the
 42343  43413     ** required page. Read and return data from the log file.
 42344  43414     */
 42345  43415     if( iRead ){
 42346         -    i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE;
        43416  +    int sz;
        43417  +    i64 iOffset;
        43418  +    sz = pWal->hdr.szPage;
        43419  +    sz = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
        43420  +    testcase( sz<=32768 );
        43421  +    testcase( sz>=65536 );
        43422  +    iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
 42347  43423       *pInWal = 1;
 42348  43424       /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
 42349  43425       return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
 42350  43426     }
 42351  43427   
 42352  43428     *pInWal = 0;
 42353  43429     return SQLITE_OK;
 42354  43430   }
 42355  43431   
 42356  43432   
 42357  43433   /* 
 42358         -** Set *pPgno to the size of the database file (or zero, if unknown).
        43434  +** Return the size of the database in pages (or zero, if unknown).
 42359  43435   */
 42360         -SQLITE_PRIVATE void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno){
 42361         -  assert( pWal->readLock>=0 || pWal->lockError );
 42362         -  *pPgno = pWal->hdr.nPage;
        43436  +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
        43437  +  if( pWal && ALWAYS(pWal->readLock>=0) ){
        43438  +    return pWal->hdr.nPage;
        43439  +  }
        43440  +  return 0;
 42363  43441   }
 42364  43442   
 42365  43443   
 42366  43444   /* 
 42367  43445   ** This function starts a write transaction on the WAL.
 42368  43446   **
 42369  43447   ** A read transaction must have already been started by a prior call
................................................................................
 42431  43509   ** returned to the caller.
 42432  43510   **
 42433  43511   ** Otherwise, if the callback function does not return an error, this
 42434  43512   ** function returns SQLITE_OK.
 42435  43513   */
 42436  43514   SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
 42437  43515     int rc = SQLITE_OK;
 42438         -  if( pWal->writeLock ){
        43516  +  if( ALWAYS(pWal->writeLock) ){
 42439  43517       Pgno iMax = pWal->hdr.mxFrame;
 42440  43518       Pgno iFrame;
 42441  43519     
 42442  43520       /* Restore the clients cache of the wal-index header to the state it
 42443  43521       ** was in before the client began writing to the database. 
 42444  43522       */
 42445  43523       memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
................................................................................
 42519  43597   ** to the current log file, it is possible to overwrite the start of the
 42520  43598   ** existing log file with the new frames (i.e. "reset" the log). If so,
 42521  43599   ** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
 42522  43600   ** unchanged.
 42523  43601   **
 42524  43602   ** SQLITE_OK is returned if no error is encountered (regardless of whether
 42525  43603   ** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned
 42526         -** if some error 
        43604  +** if an error occurs.
 42527  43605   */
 42528  43606   static int walRestartLog(Wal *pWal){
 42529  43607     int rc = SQLITE_OK;
 42530  43608     int cnt;
 42531  43609   
 42532  43610     if( pWal->readLock==0 ){
 42533  43611       volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
................................................................................
 42552  43630           sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
 42553  43631           sqlite3_randomness(4, &aSalt[1]);
 42554  43632           walIndexWriteHdr(pWal);
 42555  43633           pInfo->nBackfill = 0;
 42556  43634           for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
 42557  43635           assert( pInfo->aReadMark[0]==0 );
 42558  43636           walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
        43637  +      }else if( rc!=SQLITE_BUSY ){
        43638  +        return rc;
 42559  43639         }
 42560  43640       }
 42561  43641       walUnlockShared(pWal, WAL_READ_LOCK(0));
 42562  43642       pWal->readLock = -1;
 42563  43643       cnt = 0;
 42564  43644       do{
 42565  43645         int notUsed;
................................................................................
 42620  43700       sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
 42621  43701       sqlite3_randomness(8, pWal->hdr.aSalt);
 42622  43702       memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
 42623  43703       walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
 42624  43704       sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
 42625  43705       sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
 42626  43706       
 42627         -    pWal->szPage = (u16)szPage;
        43707  +    pWal->szPage = szPage;
 42628  43708       pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
 42629  43709       pWal->hdr.aFrameCksum[0] = aCksum[0];
 42630  43710       pWal->hdr.aFrameCksum[1] = aCksum[1];
 42631  43711   
 42632  43712       rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
 42633  43713       WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
 42634  43714       if( rc!=SQLITE_OK ){
 42635  43715         return rc;
 42636  43716       }
 42637  43717     }
 42638         -  assert( pWal->szPage==szPage );
        43718  +  assert( (int)pWal->szPage==szPage );
 42639  43719   
 42640  43720     /* Write the log file. */
 42641  43721     for(p=pList; p; p=p->pDirty){
 42642  43722       u32 nDbsize;                  /* Db-size field for frame header */
 42643  43723       i64 iOffset;                  /* Write offset in log file */
 42644  43724       void *pData;
 42645  43725      
................................................................................
 42715  43795       iFrame++;
 42716  43796       nLast--;
 42717  43797       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
 42718  43798     }
 42719  43799   
 42720  43800     if( rc==SQLITE_OK ){
 42721  43801       /* Update the private copy of the header. */
 42722         -    pWal->hdr.szPage = (u16)szPage;
        43802  +    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
        43803  +    testcase( szPage<=32768 );
        43804  +    testcase( szPage>=65536 );
 42723  43805       pWal->hdr.mxFrame = iFrame;
 42724  43806       if( isCommit ){
 42725  43807         pWal->hdr.iChange++;
 42726  43808         pWal->hdr.nPage = nTruncate;
 42727  43809       }
 42728  43810       /* If this is a commit, update the wal-index header too. */
 42729  43811       if( isCommit ){
................................................................................
 42927  44009   ** page has a small header which contains the Ptr(N) pointer and other
 42928  44010   ** information such as the size of key and data.
 42929  44011   **
 42930  44012   ** FORMAT DETAILS
 42931  44013   **
 42932  44014   ** The file is divided into pages.  The first page is called page 1,
 42933  44015   ** the second is page 2, and so forth.  A page number of zero indicates
 42934         -** "no such page".  The page size can be any power of 2 between 512 and 32768.
        44016  +** "no such page".  The page size can be any power of 2 between 512 and 65536.
 42935  44017   ** Each page can be either a btree page, a freelist page, an overflow
 42936  44018   ** page, or a pointer-map page.
 42937  44019   **
 42938  44020   ** The first page is always a btree page.  The first 100 bytes of the first
 42939  44021   ** page contain a special header (the "file header") that describes the file.
 42940  44022   ** The format of the file header is as follows:
 42941  44023   **
................................................................................
 43289  44371     sqlite3 *db;          /* Database connection currently using this Btree */
 43290  44372     BtCursor *pCursor;    /* A list of all open cursors */
 43291  44373     MemPage *pPage1;      /* First page of the database */
 43292  44374     u8 readOnly;          /* True if the underlying file is readonly */
 43293  44375     u8 pageSizeFixed;     /* True if the page size can no longer be changed */
 43294  44376     u8 secureDelete;      /* True if secure_delete is enabled */
 43295  44377     u8 initiallyEmpty;    /* Database is empty at start of transaction */
        44378  +  u8 openFlags;         /* Flags to sqlite3BtreeOpen() */
 43296  44379   #ifndef SQLITE_OMIT_AUTOVACUUM
 43297  44380     u8 autoVacuum;        /* True if auto-vacuum is enabled */
 43298  44381     u8 incrVacuum;        /* True if incr-vacuum is enabled */
 43299  44382   #endif
 43300         -  u16 pageSize;         /* Total number of bytes on a page */
 43301         -  u16 usableSize;       /* Number of usable bytes on each page */
 43302  44383     u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
 43303  44384     u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
 43304  44385     u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
 43305  44386     u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
 43306  44387     u8 inTransaction;     /* Transaction state */
 43307  44388     u8 doNotUseWAL;       /* If true, do not open write-ahead-log file */
        44389  +  u32 pageSize;         /* Total number of bytes on a page */
        44390  +  u32 usableSize;       /* Number of usable bytes on each page */
 43308  44391     int nTransaction;     /* Number of open transactions (read + write) */
 43309  44392     u32 nPage;            /* Number of pages in the database */
 43310  44393     void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
 43311  44394     void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
 43312  44395     sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
 43313  44396     Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
 43314  44397   #ifndef SQLITE_OMIT_SHARED_CACHE
................................................................................
 43899  44982   #if 0
 43900  44983   int sqlite3BtreeTrace=1;  /* True to enable tracing */
 43901  44984   # define TRACE(X)  if(sqlite3BtreeTrace){printf X;fflush(stdout);}
 43902  44985   #else
 43903  44986   # define TRACE(X)
 43904  44987   #endif
 43905  44988   
 43906         -
        44989  +/*
        44990  +** Extract a 2-byte big-endian integer from an array of unsigned bytes.
        44991  +** But if the value is zero, make it 65536.
        44992  +**
        44993  +** This routine is used to extract the "offset to cell content area" value
        44994  +** from the header of a btree page.  If the page size is 65536 and the page
        44995  +** is empty, the offset should be 65536, but the 2-byte value stores zero.
        44996  +** This routine makes the necessary adjustment to 65536.
        44997  +*/
        44998  +#define get2byteNotZero(X)  (((((int)get2byte(X))-1)&0xffff)+1)
 43907  44999   
 43908  45000   #ifndef SQLITE_OMIT_SHARED_CACHE
 43909  45001   /*
 43910  45002   ** A list of BtShared objects that are eligible for participation
 43911  45003   ** in shared cache.  This variable has file scope during normal builds,
 43912  45004   ** but the test harness needs to access it so we make it global for 
 43913  45005   ** test builds.
................................................................................
 44588  45680   }
 44589  45681   
 44590  45682   #ifndef SQLITE_OMIT_AUTOVACUUM
 44591  45683   /*
 44592  45684   ** Given a page number of a regular database page, return the page
 44593  45685   ** number for the pointer-map page that contains the entry for the
 44594  45686   ** input page number.
        45687  +**
        45688  +** Return 0 (not a valid page) for pgno==1 since there is
        45689  +** no pointer map associated with page 1.  The integrity_check logic
        45690  +** requires that ptrmapPageno(*,1)!=1.
 44595  45691   */
 44596  45692   static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
 44597  45693     int nPagesPerMapPage;
 44598  45694     Pgno iPtrMap, ret;
 44599  45695     assert( sqlite3_mutex_held(pBt->mutex) );
        45696  +  if( pgno<2 ) return 0;
 44600  45697     nPagesPerMapPage = (pBt->usableSize/5)+1;
 44601  45698     iPtrMap = (pgno-2)/nPagesPerMapPage;
 44602  45699     ret = (iPtrMap*nPagesPerMapPage) + 2; 
 44603  45700     if( ret==PENDING_BYTE_PAGE(pBt) ){
 44604  45701       ret++;
 44605  45702     }
 44606  45703     return ret;
................................................................................
 45021  46118     assert( pPage->nOverflow==0 );
 45022  46119     usableSize = pPage->pBt->usableSize;
 45023  46120     assert( nByte < usableSize-8 );
 45024  46121   
 45025  46122     nFrag = data[hdr+7];
 45026  46123     assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
 45027  46124     gap = pPage->cellOffset + 2*pPage->nCell;
 45028         -  top = get2byte(&data[hdr+5]);
        46125  +  top = get2byteNotZero(&data[hdr+5]);
 45029  46126     if( gap>top ) return SQLITE_CORRUPT_BKPT;
 45030  46127     testcase( gap+2==top );
 45031  46128     testcase( gap+1==top );
 45032  46129     testcase( gap==top );
 45033  46130   
 45034  46131     if( nFrag>=60 ){
 45035  46132       /* Always defragment highly fragmented pages */
 45036  46133       rc = defragmentPage(pPage);
 45037  46134       if( rc ) return rc;
 45038         -    top = get2byte(&data[hdr+5]);
        46135  +    top = get2byteNotZero(&data[hdr+5]);
 45039  46136     }else if( gap+2<=top ){
 45040  46137       /* Search the freelist looking for a free slot big enough to satisfy 
 45041  46138       ** the request. The allocation is made from the first free slot in 
 45042  46139       ** the list that is large enough to accomadate it.
 45043  46140       */
 45044  46141       int pc, addr;
 45045  46142       for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
................................................................................
 45073  46170     /* Check to make sure there is enough space in the gap to satisfy
 45074  46171     ** the allocation.  If not, defragment.
 45075  46172     */
 45076  46173     testcase( gap+2+nByte==top );
 45077  46174     if( gap+2+nByte>top ){
 45078  46175       rc = defragmentPage(pPage);
 45079  46176       if( rc ) return rc;
 45080         -    top = get2byte(&data[hdr+5]);
        46177  +    top = get2byteNotZero(&data[hdr+5]);
 45081  46178       assert( gap+nByte<=top );
 45082  46179     }
 45083  46180   
 45084  46181   
 45085  46182     /* Allocate memory from the gap in between the cell pointer array
 45086  46183     ** and the cell content area.  The btreeInitPage() call has already
 45087  46184     ** validated the freelist.  Given that the freelist is valid, there
................................................................................
 45239  46336     assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
 45240  46337   
 45241  46338     if( !pPage->isInit ){
 45242  46339       u16 pc;            /* Address of a freeblock within pPage->aData[] */
 45243  46340       u8 hdr;            /* Offset to beginning of page header */
 45244  46341       u8 *data;          /* Equal to pPage->aData */
 45245  46342       BtShared *pBt;        /* The main btree structure */
 45246         -    u16 usableSize;    /* Amount of usable space on each page */
        46343  +    int usableSize;    /* Amount of usable space on each page */
 45247  46344       u16 cellOffset;    /* Offset from start of page to first cell pointer */
 45248         -    u16 nFree;         /* Number of unused bytes on the page */
 45249         -    u16 top;           /* First byte of the cell content area */
        46345  +    int nFree;         /* Number of unused bytes on the page */
        46346  +    int top;           /* First byte of the cell content area */
 45250  46347       int iCellFirst;    /* First allowable cell or freeblock offset */
 45251  46348       int iCellLast;     /* Last possible cell or freeblock offset */
 45252  46349   
 45253  46350       pBt = pPage->pBt;
 45254  46351   
 45255  46352       hdr = pPage->hdrOffset;
 45256  46353       data = pPage->aData;
 45257  46354       if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
 45258         -    assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
 45259         -    pPage->maskPage = pBt->pageSize - 1;
        46355  +    assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
        46356  +    pPage->maskPage = (u16)(pBt->pageSize - 1);
 45260  46357       pPage->nOverflow = 0;
 45261  46358       usableSize = pBt->usableSize;
 45262  46359       pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
 45263         -    top = get2byte(&data[hdr+5]);
        46360  +    top = get2byteNotZero(&data[hdr+5]);
 45264  46361       pPage->nCell = get2byte(&data[hdr+3]);
 45265  46362       if( pPage->nCell>MX_CELL(pBt) ){
 45266  46363         /* To many cells for a single page.  The page must be corrupt */
 45267  46364         return SQLITE_CORRUPT_BKPT;
 45268  46365       }
 45269  46366       testcase( pPage->nCell==MX_CELL(pBt) );
 45270  46367   
................................................................................
 45355  46452       memset(&data[hdr], 0, pBt->usableSize - hdr);
 45356  46453     }
 45357  46454     data[hdr] = (char)flags;
 45358  46455     first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
 45359  46456     memset(&data[hdr+1], 0, 4);
 45360  46457     data[hdr+7] = 0;
 45361  46458     put2byte(&data[hdr+5], pBt->usableSize);
 45362         -  pPage->nFree = pBt->usableSize - first;
        46459  +  pPage->nFree = (u16)(pBt->usableSize - first);
 45363  46460     decodeFlags(pPage, flags);
 45364  46461     pPage->hdrOffset = hdr;
 45365  46462     pPage->cellOffset = first;
 45366  46463     pPage->nOverflow = 0;
 45367         -  assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
 45368         -  pPage->maskPage = pBt->pageSize - 1;
        46464  +  assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
        46465  +  pPage->maskPage = (u16)(pBt->pageSize - 1);
 45369  46466     pPage->nCell = 0;
 45370  46467     pPage->isInit = 1;
 45371  46468   }
 45372  46469   
 45373  46470   
 45374  46471   /*
 45375  46472   ** Convert a DbPage obtained from the pager into a MemPage used by
................................................................................
 45525  46622     return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
 45526  46623   }
 45527  46624   
 45528  46625   /*
 45529  46626   ** Open a database file.
 45530  46627   ** 
 45531  46628   ** zFilename is the name of the database file.  If zFilename is NULL
 45532         -** a new database with a random name is created.  This randomly named
 45533         -** database file will be deleted when sqlite3BtreeClose() is called.
        46629  +** then an ephemeral database is created.  The ephemeral database might
        46630  +** be exclusively in memory, or it might use a disk-based memory cache.
        46631  +** Either way, the ephemeral database will be automatically deleted 
        46632  +** when sqlite3BtreeClose() is called.
        46633  +**
 45534  46634   ** If zFilename is ":memory:" then an in-memory database is created
 45535  46635   ** that is automatically destroyed when it is closed.
 45536  46636   **
        46637  +** The "flags" parameter is a bitmask that might contain bits
        46638  +** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK.  The BTREE_NO_READLOCK
        46639  +** bit is also set if the SQLITE_NoReadlock flags is set in db->flags.
        46640  +** These flags are passed through into sqlite3PagerOpen() and must
        46641  +** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK.
        46642  +**
 45537  46643   ** If the database is already opened in the same database connection
 45538  46644   ** and we are in shared cache mode, then the open will fail with an
 45539  46645   ** SQLITE_CONSTRAINT error.  We cannot allow two or more BtShared
 45540  46646   ** objects in the same database connection since doing so will lead
 45541  46647   ** to problems with locking.
 45542  46648   */
 45543  46649   SQLITE_PRIVATE int sqlite3BtreeOpen(
................................................................................
 45550  46656     sqlite3_vfs *pVfs;             /* The VFS to use for this btree */
 45551  46657     BtShared *pBt = 0;             /* Shared part of btree structure */
 45552  46658     Btree *p;                      /* Handle to return */
 45553  46659     sqlite3_mutex *mutexOpen = 0;  /* Prevents a race condition. Ticket #3537 */
 45554  46660     int rc = SQLITE_OK;            /* Result code from this function */
 45555  46661     u8 nReserve;                   /* Byte of unused space on each page */
 45556  46662     unsigned char zDbHeader[100];  /* Database header content */
        46663  +
        46664  +  /* True if opening an ephemeral, temporary database */
        46665  +  const int isTempDb = zFilename==0 || zFilename[0]==0;
 45557  46666   
 45558  46667     /* Set the variable isMemdb to true for an in-memory database, or 
 45559  46668     ** false for a file-based database. This symbol is only required if
 45560  46669     ** either of the shared-data or autovacuum features are compiled 
 45561  46670     ** into the library.
 45562  46671     */
 45563  46672   #if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
 45564  46673     #ifdef SQLITE_OMIT_MEMORYDB
 45565  46674       const int isMemdb = 0;
 45566  46675     #else
 45567         -    const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
        46676  +    const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
        46677  +                         || (isTempDb && sqlite3TempInMemory(db));
 45568  46678     #endif
 45569  46679   #endif
 45570  46680   
 45571  46681     assert( db!=0 );
 45572  46682     assert( sqlite3_mutex_held(db->mutex) );
        46683  +  assert( (flags&0xff)==flags );   /* flags fit in 8 bits */
 45573  46684   
        46685  +  /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
        46686  +  assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 );
        46687  +
        46688  +  /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
        46689  +  assert( (flags & BTREE_SINGLE)==0 || isTempDb );
        46690  +
        46691  +  if( db->flags & SQLITE_NoReadlock ){
        46692  +    flags |= BTREE_NO_READLOCK;
        46693  +  }
        46694  +  if( isMemdb ){
        46695  +    flags |= BTREE_MEMORY;
        46696  +  }
        46697  +  if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){
        46698  +    vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
        46699  +  }
 45574  46700     pVfs = db->pVfs;
 45575  46701     p = sqlite3MallocZero(sizeof(Btree));
 45576  46702     if( !p ){
 45577  46703       return SQLITE_NOMEM;
 45578  46704     }
 45579  46705     p->inTrans = TRANS_NONE;
 45580  46706     p->db = db;
................................................................................
 45584  46710   #endif
 45585  46711   
 45586  46712   #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
 45587  46713     /*
 45588  46714     ** If this Btree is a candidate for shared cache, try to find an
 45589  46715     ** existing BtShared object that we can share with
 45590  46716     */
 45591         -  if( isMemdb==0 && zFilename && zFilename[0] ){
        46717  +  if( isMemdb==0 && isTempDb==0 ){
 45592  46718       if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
 45593  46719         int nFullPathname = pVfs->mxPathname+1;
 45594  46720         char *zFullPathname = sqlite3Malloc(nFullPathname);
 45595  46721         sqlite3_mutex *mutexShared;
 45596  46722         p->sharable = 1;
 45597  46723         if( !zFullPathname ){
 45598  46724           sqlite3_free(p);
................................................................................
 45659  46785                             EXTRA_SIZE, flags, vfsFlags, pageReinit);
 45660  46786       if( rc==SQLITE_OK ){
 45661  46787         rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
 45662  46788       }
 45663  46789       if( rc!=SQLITE_OK ){
 45664  46790         goto btree_open_out;
 45665  46791       }
        46792  +    pBt->openFlags = (u8)flags;
 45666  46793       pBt->db = db;
 45667  46794       sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
 45668  46795       p->pBt = pBt;
 45669  46796     
 45670  46797       pBt->pCursor = 0;
 45671  46798       pBt->pPage1 = 0;
 45672  46799       pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
 45673  46800   #ifdef SQLITE_SECURE_DELETE
 45674  46801       pBt->secureDelete = 1;
 45675  46802   #endif
 45676         -    pBt->pageSize = get2byte(&zDbHeader[16]);
        46803  +    pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
 45677  46804       if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
 45678  46805            || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
 45679  46806         pBt->pageSize = 0;
 45680  46807   #ifndef SQLITE_OMIT_AUTOVACUUM
 45681  46808         /* If the magic name ":memory:" will create an in-memory database, then
 45682  46809         ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
 45683  46810         ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
................................................................................
 45763  46890     if( rc!=SQLITE_OK ){
 45764  46891       if( pBt && pBt->pPager ){
 45765  46892         sqlite3PagerClose(pBt->pPager);
 45766  46893       }
 45767  46894       sqlite3_free(pBt);
 45768  46895       sqlite3_free(p);
 45769  46896       *ppBtree = 0;
        46897  +  }else{
        46898  +    /* If the B-Tree was successfully opened, set the pager-cache size to the
        46899  +    ** default value. Except, when opening on an existing shared pager-cache,
        46900  +    ** do not change the pager-cache size.
        46901  +    */
        46902  +    if( sqlite3BtreeSchema(p, 0, 0)==0 ){
        46903  +      sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
        46904  +    }
 45770  46905     }
 45771  46906     if( mutexOpen ){
 45772  46907       assert( sqlite3_mutex_held(mutexOpen) );
 45773  46908       sqlite3_mutex_leave(mutexOpen);
 45774  46909     }
 45775  46910     return rc;
 45776  46911   }
................................................................................
 45983  47118       nReserve = pBt->pageSize - pBt->usableSize;
 45984  47119     }
 45985  47120     assert( nReserve>=0 && nReserve<=255 );
 45986  47121     if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
 45987  47122           ((pageSize-1)&pageSize)==0 ){
 45988  47123       assert( (pageSize & 7)==0 );
 45989  47124       assert( !pBt->pPage1 && !pBt->pCursor );
 45990         -    pBt->pageSize = (u16)pageSize;
        47125  +    pBt->pageSize = (u32)pageSize;
 45991  47126       freeTempSpace(pBt);
 45992  47127     }
 45993  47128     rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
 45994  47129     pBt->usableSize = pBt->pageSize - (u16)nReserve;
 45995  47130     if( iFix ) pBt->pageSizeFixed = 1;
 45996  47131     sqlite3BtreeLeave(p);
 45997  47132     return rc;
................................................................................
 46118  47253     rc = btreeGetPage(pBt, 1, &pPage1, 0);
 46119  47254     if( rc!=SQLITE_OK ) return rc;
 46120  47255   
 46121  47256     /* Do some checking to help insure the file we opened really is
 46122  47257     ** a valid database file. 
 46123  47258     */
 46124  47259     nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
 46125         -  if( (rc = sqlite3PagerPagecount(pBt->pPager, &nPageFile))!=SQLITE_OK ){;
 46126         -    goto page1_init_failed;
 46127         -  }
        47260  +  sqlite3PagerPagecount(pBt->pPager, &nPageFile);
 46128  47261     if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
 46129  47262       nPage = nPageFile;
 46130  47263     }
 46131  47264     if( nPage>0 ){
 46132         -    int pageSize;
 46133         -    int usableSize;
        47265  +    u32 pageSize;
        47266  +    u32 usableSize;
 46134  47267       u8 *page1 = pPage1->aData;
 46135  47268       rc = SQLITE_NOTADB;
 46136  47269       if( memcmp(page1, zMagicHeader, 16)!=0 ){
 46137  47270         goto page1_init_failed;
 46138  47271       }
 46139  47272   
 46140  47273   #ifdef SQLITE_OMIT_WAL
................................................................................
 46177  47310       ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
 46178  47311       ** The original design allowed these amounts to vary, but as of
 46179  47312       ** version 3.6.0, we require them to be fixed.
 46180  47313       */
 46181  47314       if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
 46182  47315         goto page1_init_failed;
 46183  47316       }
 46184         -    pageSize = get2byte(&page1[16]);
 46185         -    if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
 46186         -        (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
        47317  +    pageSize = (page1[16]<<8) | (page1[17]<<16);
        47318  +    if( ((pageSize-1)&pageSize)!=0
        47319  +     || pageSize>SQLITE_MAX_PAGE_SIZE 
        47320  +     || pageSize<=256 
 46187  47321       ){
 46188  47322         goto page1_init_failed;
 46189  47323       }
 46190  47324       assert( (pageSize & 7)==0 );
 46191  47325       usableSize = pageSize - page1[20];
 46192         -    if( pageSize!=pBt->pageSize ){
        47326  +    if( (u32)pageSize!=pBt->pageSize ){
 46193  47327         /* After reading the first page of the database assuming a page size
 46194  47328         ** of BtShared.pageSize, we have discovered that the page-size is
 46195  47329         ** actually pageSize. Unlock the database, leave pBt->pPage1 at
 46196  47330         ** zero and return SQLITE_OK. The caller will call this function
 46197  47331         ** again with the correct page-size.
 46198  47332         */
 46199  47333         releasePage(pPage1);
 46200         -      pBt->usableSize = (u16)usableSize;
 46201         -      pBt->pageSize = (u16)pageSize;
        47334  +      pBt->usableSize = usableSize;
        47335  +      pBt->pageSize = pageSize;
 46202  47336         freeTempSpace(pBt);
 46203  47337         rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
 46204  47338                                      pageSize-usableSize);
 46205  47339         return rc;
 46206  47340       }
 46207  47341       if( nPageHeader>nPageFile ){
 46208  47342         rc = SQLITE_CORRUPT_BKPT;
 46209  47343         goto page1_init_failed;
 46210  47344       }
 46211  47345       if( usableSize<480 ){
 46212  47346         goto page1_init_failed;
 46213  47347       }
 46214         -    pBt->pageSize = (u16)pageSize;
 46215         -    pBt->usableSize = (u16)usableSize;
        47348  +    pBt->pageSize = pageSize;
        47349  +    pBt->usableSize = usableSize;
 46216  47350   #ifndef SQLITE_OMIT_AUTOVACUUM
 46217  47351       pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
 46218  47352       pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
 46219  47353   #endif
 46220  47354     }
 46221  47355   
 46222  47356     /* maxLocal is the maximum amount of payload to store locally for
................................................................................
 46224  47358     ** cells can will fit on one page.  We assume a 10-byte page header.
 46225  47359     ** Besides the payload, the cell must store:
 46226  47360     **     2-byte pointer to the cell
 46227  47361     **     4-byte child pointer
 46228  47362     **     9-byte nKey value
 46229  47363     **     4-byte nData value
 46230  47364     **     4-byte overflow page pointer
 46231         -  ** So a cell consists of a 2-byte poiner, a header which is as much as
        47365  +  ** So a cell consists of a 2-byte pointer, a header which is as much as
 46232  47366     ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
 46233  47367     ** page pointer.
 46234  47368     */
 46235         -  pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23;
 46236         -  pBt->minLocal = (pBt->usableSize-12)*32/255 - 23;
 46237         -  pBt->maxLeaf = pBt->usableSize - 35;
 46238         -  pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
        47369  +  pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23);
        47370  +  pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23);
        47371  +  pBt->maxLeaf = (u16)(pBt->usableSize - 35);
        47372  +  pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23);
 46239  47373     assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
 46240  47374     pBt->pPage1 = pPage1;
 46241  47375     pBt->nPage = nPage;
 46242  47376     return SQLITE_OK;
 46243  47377   
 46244  47378   page1_init_failed:
 46245  47379     releasePage(pPage1);
................................................................................
 46284  47418     pP1 = pBt->pPage1;
 46285  47419     assert( pP1!=0 );
 46286  47420     data = pP1->aData;
 46287  47421     rc = sqlite3PagerWrite(pP1->pDbPage);
 46288  47422     if( rc ) return rc;
 46289  47423     memcpy(data, zMagicHeader, sizeof(zMagicHeader));
 46290  47424     assert( sizeof(zMagicHeader)==16 );
 46291         -  put2byte(&data[16], pBt->pageSize);
        47425  +  data[16] = (u8)((pBt->pageSize>>8)&0xff);
        47426  +  data[17] = (u8)((pBt->pageSize>>16)&0xff);
 46292  47427     data[18] = 1;
 46293  47428     data[19] = 1;
 46294  47429     assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
 46295  47430     data[20] = (u8)(pBt->pageSize - pBt->usableSize);
 46296  47431     data[21] = 64;
 46297  47432     data[22] = 32;
 46298  47433     data[23] = 32;
................................................................................
 48295  49430           }else{
 48296  49431             assert( nCellKey>intKey );
 48297  49432             c = +1;
 48298  49433           }
 48299  49434           pCur->validNKey = 1;
 48300  49435           pCur->info.nKey = nCellKey;
 48301  49436         }else{
 48302         -        /* The maximum supported page-size is 32768 bytes. This means that
        49437  +        /* The maximum supported page-size is 65536 bytes. This means that
 48303  49438           ** the maximum number of record bytes stored on an index B-Tree
 48304         -        ** page is at most 8198 bytes, which may be stored as a 2-byte
        49439  +        ** page is less than 16384 bytes and may be stored as a 2-byte
 48305  49440           ** varint. This information is used to attempt to avoid parsing 
 48306  49441           ** the entire cell by checking for the cases where the record is 
 48307  49442           ** stored entirely within the b-tree page by inspecting the first 
 48308  49443           ** 2 bytes of the cell.
 48309  49444           */
 48310  49445           int nCell = pCell[0];
 48311  49446           if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
................................................................................
 48660  49795           if( rc ){
 48661  49796             goto end_allocate_page;
 48662  49797           }
 48663  49798           if( k==0 ){
 48664  49799             if( !pPrevTrunk ){
 48665  49800               memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
 48666  49801             }else{
        49802  +            rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
        49803  +            if( rc!=SQLITE_OK ){
        49804  +              goto end_allocate_page;
        49805  +            }
 48667  49806               memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
 48668  49807             }
 48669  49808           }else{
 48670  49809             /* The trunk page is required by the caller but it contains 
 48671  49810             ** pointers to free-list leaves. The first leaf becomes a trunk
 48672  49811             ** page in this case.
 48673  49812             */
................................................................................
 48966  50105   */
 48967  50106   static int clearCell(MemPage *pPage, unsigned char *pCell){
 48968  50107     BtShared *pBt = pPage->pBt;
 48969  50108     CellInfo info;
 48970  50109     Pgno ovflPgno;
 48971  50110     int rc;
 48972  50111     int nOvfl;
 48973         -  u16 ovflPageSize;
        50112  +  u32 ovflPageSize;
 48974  50113   
 48975  50114     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 48976  50115     btreeParseCellPtr(pPage, pCell, &info);
 48977  50116     if( info.iOverflow==0 ){
 48978  50117       return SQLITE_OK;  /* No overflow pages. Return without doing anything */
 48979  50118     }
 48980  50119     ovflPgno = get4byte(&pCell[info.iOverflow]);
................................................................................
 49191  50330   ** the cell content has been copied someplace else.  This routine just
 49192  50331   ** removes the reference to the cell from pPage.
 49193  50332   **
 49194  50333   ** "sz" must be the number of bytes in the cell.
 49195  50334   */
 49196  50335   static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
 49197  50336     int i;          /* Loop counter */
 49198         -  int pc;         /* Offset to cell content of cell being deleted */
        50337  +  u32 pc;         /* Offset to cell content of cell being deleted */
 49199  50338     u8 *data;       /* pPage->aData */
 49200  50339     u8 *ptr;        /* Used to move bytes around within data[] */
 49201  50340     int rc;         /* The return code */
 49202  50341     int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */
 49203  50342   
 49204  50343     if( *pRC ) return;
 49205  50344   
................................................................................
 49209  50348     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 49210  50349     data = pPage->aData;
 49211  50350     ptr = &data[pPage->cellOffset + 2*idx];
 49212  50351     pc = get2byte(ptr);
 49213  50352     hdr = pPage->hdrOffset;
 49214  50353     testcase( pc==get2byte(&data[hdr+5]) );
 49215  50354     testcase( pc+sz==pPage->pBt->usableSize );
 49216         -  if( pc < get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
        50355  +  if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
 49217  50356       *pRC = SQLITE_CORRUPT_BKPT;
 49218  50357       return;
 49219  50358     }
 49220  50359     rc = freeSpace(pPage, pc, sz);
 49221  50360     if( rc ){
 49222  50361       *pRC = rc;
 49223  50362       return;
................................................................................
 49266  50405     u8 *ptr;          /* Used for moving information around in data[] */
 49267  50406   
 49268  50407     int nSkip = (iChild ? 4 : 0);
 49269  50408   
 49270  50409     if( *pRC ) return;
 49271  50410   
 49272  50411     assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
 49273         -  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
        50412  +  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
 49274  50413     assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
 49275  50414     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 49276  50415     /* The cell should normally be sized correctly.  However, when moving a
 49277  50416     ** malformed cell from a leaf page to an interior page, if the cell size
 49278  50417     ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
 49279  50418     ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
 49280  50419     ** the term after the || in the following assert(). */
................................................................................
 49346  50485     int cellbody;     /* Address of next cell body */
 49347  50486     u8 * const data = pPage->aData;             /* Pointer to data for pPage */
 49348  50487     const int hdr = pPage->hdrOffset;           /* Offset of header on pPage */
 49349  50488     const int nUsable = pPage->pBt->usableSize; /* Usable size of page */
 49350  50489   
 49351  50490     assert( pPage->nOverflow==0 );
 49352  50491     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 49353         -  assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
        50492  +  assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921);
 49354  50493     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
 49355  50494   
 49356  50495     /* Check that the page has just been zeroed by zeroPage() */
 49357  50496     assert( pPage->nCell==0 );
 49358         -  assert( get2byte(&data[hdr+5])==nUsable );
        50497  +  assert( get2byteNotZero(&data[hdr+5])==nUsable );
 49359  50498   
 49360  50499     pCellptr = &data[pPage->cellOffset + nCell*2];
 49361  50500     cellbody = nUsable;
 49362  50501     for(i=nCell-1; i>=0; i--){
 49363  50502       pCellptr -= 2;
 49364  50503       cellbody -= aSize[i];
 49365  50504       put2byte(pCellptr, cellbody);
................................................................................
 49417  50556     int rc;                              /* Return Code */
 49418  50557     Pgno pgnoNew;                        /* Page number of pNew */
 49419  50558   
 49420  50559     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 49421  50560     assert( sqlite3PagerIswriteable(pParent->pDbPage) );
 49422  50561     assert( pPage->nOverflow==1 );
 49423  50562   
        50563  +  /* This error condition is now caught prior to reaching this function */
 49424  50564     if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
 49425  50565   
 49426  50566     /* Allocate a new page. This page will become the right-sibling of 
 49427  50567     ** pPage. Make the parent page writable, so that the new divider cell
 49428  50568     ** may be inserted. If both these operations are successful, proceed.
 49429  50569     */
 49430  50570     rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
................................................................................
 49746  50886         ** Unless SQLite is compiled in secure-delete mode. In this case,
 49747  50887         ** the dropCell() routine will overwrite the entire cell with zeroes.
 49748  50888         ** In this case, temporarily copy the cell into the aOvflSpace[]
 49749  50889         ** buffer. It will be copied out again as soon as the aSpace[] buffer
 49750  50890         ** is allocated.  */
 49751  50891         if( pBt->secureDelete ){
 49752  50892           int iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
 49753         -        if( (iOff+szNew[i])>pBt->usableSize ){
        50893  +        if( (iOff+szNew[i])>(int)pBt->usableSize ){
 49754  50894             rc = SQLITE_CORRUPT_BKPT;
 49755  50895             memset(apOld, 0, (i+1)*sizeof(MemPage*));
 49756  50896             goto balance_cleanup;
 49757  50897           }else{
 49758  50898             memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
 49759  50899             apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
 49760  50900           }
................................................................................
 49825  50965       if( i<nOld-1 && !leafData){
 49826  50966         u16 sz = (u16)szNew[i];
 49827  50967         u8 *pTemp;
 49828  50968         assert( nCell<nMaxCells );
 49829  50969         szCell[nCell] = sz;
 49830  50970         pTemp = &aSpace1[iSpace1];
 49831  50971         iSpace1 += sz;
 49832         -      assert( sz<=pBt->pageSize/4 );
        50972  +      assert( sz<=pBt->maxLocal+23 );
 49833  50973         assert( iSpace1<=pBt->pageSize );
 49834  50974         memcpy(pTemp, apDiv[i], sz);
 49835  50975         apCell[nCell] = pTemp+leafCorrection;
 49836  50976         assert( leafCorrection==0 || leafCorrection==4 );
 49837  50977         szCell[nCell] = szCell[nCell] - leafCorrection;
 49838  50978         if( !pOld->leaf ){
 49839  50979           assert( leafCorrection==0 );
................................................................................
 50071  51211           */
 50072  51212           if( szCell[j]==4 ){
 50073  51213             assert(leafCorrection==4);
 50074  51214             sz = cellSizePtr(pParent, pCell);
 50075  51215           }
 50076  51216         }
 50077  51217         iOvflSpace += sz;
 50078         -      assert( sz<=pBt->pageSize/4 );
        51218  +      assert( sz<=pBt->maxLocal+23 );
 50079  51219         assert( iOvflSpace<=pBt->pageSize );
 50080  51220         insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
 50081  51221         if( rc!=SQLITE_OK ) goto balance_cleanup;
 50082  51222         assert( sqlite3PagerIswriteable(pParent->pDbPage) );
 50083  51223   
 50084  51224         j++;
 50085  51225         nxDiv++;
................................................................................
 50708  51848   ** The type of type is determined by the flags parameter.  Only the
 50709  51849   ** following values of flags are currently in use.  Other values for
 50710  51850   ** flags might not work:
 50711  51851   **
 50712  51852   **     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
 50713  51853   **     BTREE_ZERODATA                  Used for SQL indices
 50714  51854   */
 50715         -static int btreeCreateTable(Btree *p, int *piTable, int flags){
        51855  +static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
 50716  51856     BtShared *pBt = p->pBt;
 50717  51857     MemPage *pRoot;
 50718  51858     Pgno pgnoRoot;
 50719  51859     int rc;
        51860  +  int ptfFlags;          /* Page-type flage for the root page of new table */
 50720  51861   
 50721  51862     assert( sqlite3BtreeHoldsMutex(p) );
 50722  51863     assert( pBt->inTransaction==TRANS_WRITE );
 50723  51864     assert( !pBt->readOnly );
 50724  51865   
 50725  51866   #ifdef SQLITE_OMIT_AUTOVACUUM
 50726  51867     rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
................................................................................
 50831  51972   
 50832  51973     }else{
 50833  51974       rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
 50834  51975       if( rc ) return rc;
 50835  51976     }
 50836  51977   #endif
 50837  51978     assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
 50838         -  zeroPage(pRoot, flags | PTF_LEAF);
        51979  +  if( createTabFlags & BTREE_INTKEY ){
        51980  +    ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF;
        51981  +  }else{
        51982  +    ptfFlags = PTF_ZERODATA | PTF_LEAF;
        51983  +  }
        51984  +  zeroPage(pRoot, ptfFlags);
 50839  51985     sqlite3PagerUnref(pRoot->pDbPage);
        51986  +  assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 );
 50840  51987     *piTable = (int)pgnoRoot;
 50841  51988     return SQLITE_OK;
 50842  51989   }
 50843  51990   SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
 50844  51991     int rc;
 50845  51992     sqlite3BtreeEnter(p);
 50846  51993     rc = btreeCreateTable(p, piTable, flags);
................................................................................
 51315  52462       if( isFreeList ){
 51316  52463         int n = get4byte(&pOvflData[4]);
 51317  52464   #ifndef SQLITE_OMIT_AUTOVACUUM
 51318  52465         if( pCheck->pBt->autoVacuum ){
 51319  52466           checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
 51320  52467         }
 51321  52468   #endif
 51322         -      if( n>pCheck->pBt->usableSize/4-2 ){
        52469  +      if( n>(int)pCheck->pBt->usableSize/4-2 ){
 51323  52470           checkAppendMsg(pCheck, zContext,
 51324  52471              "freelist leaf count too big on page %d", iPage);
 51325  52472           N--;
 51326  52473         }else{
 51327  52474           for(i=0; i<n; i++){
 51328  52475             Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
 51329  52476   #ifndef SQLITE_OMIT_AUTOVACUUM
................................................................................
 51526  52673     */
 51527  52674     data = pPage->aData;
 51528  52675     hdr = pPage->hdrOffset;
 51529  52676     hit = sqlite3PageMalloc( pBt->pageSize );
 51530  52677     if( hit==0 ){
 51531  52678       pCheck->mallocFailed = 1;
 51532  52679     }else{
 51533         -    u16 contentOffset = get2byte(&data[hdr+5]);
        52680  +    int contentOffset = get2byteNotZero(&data[hdr+5]);
 51534  52681       assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
 51535  52682       memset(hit+contentOffset, 0, usableSize-contentOffset);
 51536  52683       memset(hit, 1, contentOffset);
 51537  52684       nCell = get2byte(&data[hdr+3]);
 51538  52685       cellStart = hdr + 12 - 4*pPage->leaf;
 51539  52686       for(i=0; i<nCell; i++){
 51540  52687         int pc = get2byte(&data[cellStart+i*2]);
 51541         -      u16 size = 1024;
        52688  +      u32 size = 65536;
 51542  52689         int j;
 51543  52690         if( pc<=usableSize-4 ){
 51544  52691           size = cellSizePtr(pPage, &data[pc]);
 51545  52692         }
 51546         -      if( (pc+size-1)>=usableSize ){
        52693  +      if( (int)(pc+size-1)>=usableSize ){
 51547  52694           checkAppendMsg(pCheck, 0, 
 51548  52695               "Corruption detected in cell %d on page %d",i,iPage);
 51549  52696         }else{
 51550  52697           for(j=pc+size-1; j>=pc; j--) hit[j]++;
 51551  52698         }
 51552  52699       }
 51553  52700       i = get2byte(&data[hdr+1]);
................................................................................
 52092  53239   
 52093  53240     if( pSrcDb==pDestDb ){
 52094  53241       sqlite3Error(
 52095  53242           pDestDb, SQLITE_ERROR, "source and destination must be distinct"
 52096  53243       );
 52097  53244       p = 0;
 52098  53245     }else {
 52099         -    /* Allocate space for a new sqlite3_backup object */
        53246  +    /* Allocate space for a new sqlite3_backup object...
        53247  +    ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
        53248  +    ** call to sqlite3_backup_init() and is destroyed by a call to
        53249  +    ** sqlite3_backup_finish(). */
 52100  53250       p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
 52101  53251       if( !p ){
 52102  53252         sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
 52103  53253       }
 52104  53254     }
 52105  53255   
 52106  53256     /* If the allocation succeeded, populate the new object. */
................................................................................
 52162  53312   
 52163  53313     /* Catch the case where the destination is an in-memory database and the
 52164  53314     ** page sizes of the source and destination differ. 
 52165  53315     */
 52166  53316     if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
 52167  53317       rc = SQLITE_READONLY;
 52168  53318     }
        53319  +
        53320  +#ifdef SQLITE_HAS_CODEC
        53321  +  /* Backup is not possible if the page size of the destination is changing
        53322  +  ** a a codec is in use.
        53323  +  */
        53324  +  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
        53325  +    rc = SQLITE_READONLY;
        53326  +  }
        53327  +#endif
 52169  53328   
 52170  53329     /* This loop runs once for each destination page spanned by the source 
 52171  53330     ** page. For each iteration, variable iOff is set to the byte offset
 52172  53331     ** of the destination page.
 52173  53332     */
 52174  53333     for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
 52175  53334       DbPage *pDestPg = 0;
................................................................................
 52466  53625   
 52467  53626     /* Exit the mutexes and free the backup context structure. */
 52468  53627     if( p->pDestDb ){
 52469  53628       sqlite3_mutex_leave(p->pDestDb->mutex);
 52470  53629     }
 52471  53630     sqlite3BtreeLeave(p->pSrc);
 52472  53631     if( p->pDestDb ){
        53632  +    /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
        53633  +    ** call to sqlite3_backup_init() and is destroyed by a call to
        53634  +    ** sqlite3_backup_finish(). */
 52473  53635       sqlite3_free(p);
 52474  53636     }
 52475  53637     sqlite3_mutex_leave(mutex);
 52476  53638     return rc;
 52477  53639   }
 52478  53640   
 52479  53641   /*
................................................................................
 52717  53879     if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
 52718  53880       if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
 52719  53881         return SQLITE_NOMEM;
 52720  53882       }
 52721  53883       pMem->z[pMem->n] = 0;
 52722  53884       pMem->z[pMem->n+1] = 0;
 52723  53885       pMem->flags |= MEM_Term;
        53886  +#ifdef SQLITE_DEBUG
        53887  +    pMem->pScopyFrom = 0;
        53888  +#endif
 52724  53889     }
 52725  53890   
 52726  53891     return SQLITE_OK;
 52727  53892   }
 52728  53893   
 52729  53894   /*
 52730  53895   ** If the given Mem* has a zero-filled tail, turn it into an ordinary
................................................................................
 52837  54002       assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
 52838  54003       assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
 52839  54004       memset(&ctx, 0, sizeof(ctx));
 52840  54005       ctx.s.flags = MEM_Null;
 52841  54006       ctx.s.db = pMem->db;
 52842  54007       ctx.pMem = pMem;
 52843  54008       ctx.pFunc = pFunc;
 52844         -    pFunc->xFinalize(&ctx);
        54009  +    pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
 52845  54010       assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
 52846  54011       sqlite3DbFree(pMem->db, pMem->zMalloc);
 52847  54012       memcpy(pMem, &ctx.s, sizeof(ctx.s));
 52848  54013       rc = ctx.isError;
 52849  54014     }
 52850  54015     return rc;
 52851  54016   }
................................................................................
 52950  54115     flags = pMem->flags;
 52951  54116     if( flags & MEM_Int ){
 52952  54117       return pMem->u.i;
 52953  54118     }else if( flags & MEM_Real ){
 52954  54119       return doubleToInt64(pMem->r);
 52955  54120     }else if( flags & (MEM_Str|MEM_Blob) ){
 52956  54121       i64 value;
 52957         -    pMem->flags |= MEM_Str;
 52958         -    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
 52959         -       || sqlite3VdbeMemNulTerminate(pMem) ){
 52960         -      return 0;
 52961         -    }
 52962         -    assert( pMem->z );
 52963         -    sqlite3Atoi64(pMem->z, &value);
        54122  +    assert( pMem->z || pMem->n==0 );
        54123  +    testcase( pMem->z==0 );
        54124  +    sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
 52964  54125       return value;
 52965  54126     }else{
 52966  54127       return 0;
 52967  54128     }
 52968  54129   }
 52969  54130   
 52970  54131   /*
................................................................................
 52979  54140     if( pMem->flags & MEM_Real ){
 52980  54141       return pMem->r;
 52981  54142     }else if( pMem->flags & MEM_Int ){
 52982  54143       return (double)pMem->u.i;
 52983  54144     }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
 52984  54145       /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
 52985  54146       double val = (double)0;
 52986         -    pMem->flags |= MEM_Str;
 52987         -    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
 52988         -       || sqlite3VdbeMemNulTerminate(pMem) ){
 52989         -      /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
 52990         -      return (double)0;
 52991         -    }
 52992         -    assert( pMem->z );
 52993         -    sqlite3AtoF(pMem->z, &val);
        54147  +    sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
 52994  54148       return val;
 52995  54149     }else{
 52996  54150       /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
 52997  54151       return (double)0;
 52998  54152     }
 52999  54153   }
 53000  54154   
................................................................................
 53059  54213   ** Invalidate any prior representations.
 53060  54214   **
 53061  54215   ** Every effort is made to force the conversion, even if the input
 53062  54216   ** is a string that does not look completely like a number.  Convert
 53063  54217   ** as much of the string as we can and ignore the rest.
 53064  54218   */
 53065  54219   SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
 53066         -  int rc;
 53067         -  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 );
 53068         -  assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
 53069         -  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
 53070         -  rc = sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8);
 53071         -  if( rc ) return rc;
 53072         -  rc = sqlite3VdbeMemNulTerminate(pMem);
 53073         -  if( rc ) return rc;
 53074         -  if( sqlite3Atoi64(pMem->z, &pMem->u.i) ){
 53075         -    MemSetTypeFlag(pMem, MEM_Int);
 53076         -  }else{
 53077         -    pMem->r = sqlite3VdbeRealValue(pMem);
 53078         -    MemSetTypeFlag(pMem, MEM_Real);
 53079         -    sqlite3VdbeIntegerAffinity(pMem);
        54220  +  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
        54221  +    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
        54222  +    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
        54223  +    if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
        54224  +      MemSetTypeFlag(pMem, MEM_Int);
        54225  +    }else{
        54226  +      pMem->r = sqlite3VdbeRealValue(pMem);
        54227  +      MemSetTypeFlag(pMem, MEM_Real);
        54228  +      sqlite3VdbeIntegerAffinity(pMem);
        54229  +    }
 53080  54230     }
        54231  +  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
        54232  +  pMem->flags &= ~(MEM_Str|MEM_Blob);
 53081  54233     return SQLITE_OK;
 53082  54234   }
 53083  54235   
 53084  54236   /*
 53085  54237   ** Delete any previous value and set the value stored in *pMem to NULL.
 53086  54238   */
 53087  54239   SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
................................................................................
 53178  54330         n += p->u.nZero;
 53179  54331       }
 53180  54332       return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
 53181  54333     }
 53182  54334     return 0; 
 53183  54335   }
 53184  54336   
        54337  +#ifdef SQLITE_DEBUG
        54338  +/*
        54339  +** This routine prepares a memory cell for modication by breaking
        54340  +** its link to a shallow copy and by marking any current shallow
        54341  +** copies of this cell as invalid.
        54342  +**
        54343  +** This is used for testing and debugging only - to make sure shallow
        54344  +** copies are not misused.
        54345  +*/
        54346  +SQLITE_PRIVATE void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){
        54347  +  int i;
        54348  +  Mem *pX;
        54349  +  for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
        54350  +    if( pX->pScopyFrom==pMem ){
        54351  +      pX->flags |= MEM_Invalid;
        54352  +      pX->pScopyFrom = 0;
        54353  +    }
        54354  +  }
        54355  +  pMem->pScopyFrom = 0;
        54356  +}
        54357  +#endif /* SQLITE_DEBUG */
        54358  +
 53185  54359   /*
 53186  54360   ** Size of struct Mem not including the Mem.zMalloc member.
 53187  54361   */
 53188  54362   #define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
 53189  54363   
 53190  54364   /*
 53191  54365   ** Make an shallow copy of pFrom into pTo.  Prior contents of
................................................................................
 53546  54720       sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
 53547  54721       if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
 53548  54722         assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
 53549  54723         if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
 53550  54724           return 0;
 53551  54725         }
 53552  54726       }
 53553         -    sqlite3VdbeMemNulTerminate(pVal);
        54727  +    sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */
 53554  54728     }else{
 53555  54729       assert( (pVal->flags&MEM_Blob)==0 );
 53556  54730       sqlite3VdbeMemStringify(pVal, enc);
 53557  54731       assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
 53558  54732     }
 53559  54733     assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
 53560  54734                 || pVal->db->mallocFailed );
................................................................................
 53594  54768     u8 enc,                   /* Encoding to use */
 53595  54769     u8 affinity,              /* Affinity to use */
 53596  54770     sqlite3_value **ppVal     /* Write the new value here */
 53597  54771   ){
 53598  54772     int op;
 53599  54773     char *zVal = 0;
 53600  54774     sqlite3_value *pVal = 0;
        54775  +  int negInt = 1;
        54776  +  const char *zNeg = "";
 53601  54777   
 53602  54778     if( !pExpr ){
 53603  54779       *ppVal = 0;
 53604  54780       return SQLITE_OK;
 53605  54781     }
 53606  54782     op = pExpr->op;
 53607  54783   
................................................................................
 53610  54786     ** when SQLITE_ENABLE_STAT2 is omitted.
 53611  54787     */
 53612  54788   #ifdef SQLITE_ENABLE_STAT2
 53613  54789     if( op==TK_REGISTER ) op = pExpr->op2;
 53614  54790   #else
 53615  54791     if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
 53616  54792   #endif
        54793  +
        54794  +  /* Handle negative integers in a single step.  This is needed in the
        54795  +  ** case when the value is -9223372036854775808.
        54796  +  */
        54797  +  if( op==TK_UMINUS
        54798  +   && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
        54799  +    pExpr = pExpr->pLeft;
        54800  +    op = pExpr->op;
        54801  +    negInt = -1;
        54802  +    zNeg = "-";
        54803  +  }
 53617  54804   
 53618  54805     if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
 53619  54806       pVal = sqlite3ValueNew(db);
 53620  54807       if( pVal==0 ) goto no_mem;
 53621  54808       if( ExprHasProperty(pExpr, EP_IntValue) ){
 53622         -      sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
        54809  +      sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
 53623  54810       }else{
 53624         -      zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
        54811  +      zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
 53625  54812         if( zVal==0 ) goto no_mem;
 53626  54813         sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
 53627  54814         if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
 53628  54815       }
 53629  54816       if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
 53630  54817         sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
 53631  54818       }else{
 53632  54819         sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
 53633  54820       }
        54821  +    if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
 53634  54822       if( enc!=SQLITE_UTF8 ){
 53635  54823         sqlite3VdbeChangeEncoding(pVal, enc);
 53636  54824       }
 53637  54825     }else if( op==TK_UMINUS ) {
        54826  +    /* This branch happens for multiple negative signs.  Ex: -(-5) */
 53638  54827       if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
        54828  +      sqlite3VdbeMemNumerify(pVal);
 53639  54829         pVal->u.i = -1 * pVal->u.i;
 53640  54830         /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */
 53641  54831         pVal->r = (double)-1 * pVal->r;
        54832  +      sqlite3ValueApplyAffinity(pVal, affinity, enc);
 53642  54833       }
 53643  54834     }
 53644  54835   #ifndef SQLITE_OMIT_BLOB_LITERAL
 53645  54836     else if( op==TK_BLOB ){
 53646  54837       int nVal;
 53647  54838       assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
 53648  54839       assert( pExpr->u.zToken[1]=='\'' );
................................................................................
 55461  56652       ** still have 'null' as the master journal pointer, so they will roll
 55462  56653       ** back independently if a failure occurs.
 55463  56654       */
 55464  56655       for(i=0; i<db->nDb; i++){
 55465  56656         Btree *pBt = db->aDb[i].pBt;
 55466  56657         if( sqlite3BtreeIsInTrans(pBt) ){
 55467  56658           char const *zFile = sqlite3BtreeGetJournalname(pBt);
 55468         -        if( zFile==0 || zFile[0]==0 ){
        56659  +        if( zFile==0 ){
 55469  56660             continue;  /* Ignore TEMP and :memory: databases */
 55470  56661           }
        56662  +        assert( zFile[0]!=0 );
 55471  56663           if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
 55472  56664             needSync = 1;
 55473  56665           }
 55474  56666           rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
 55475  56667           offset += sqlite3Strlen30(zFile)+1;
 55476  56668           if( rc!=SQLITE_OK ){
 55477  56669             sqlite3OsCloseFree(pMaster);
................................................................................
 55767  56959   
 55768  56960       /* Check for one of the special errors */
 55769  56961       mrc = p->rc & 0xff;
 55770  56962       assert( p->rc!=SQLITE_IOERR_BLOCKED );  /* This error no longer exists */
 55771  56963       isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
 55772  56964                        || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
 55773  56965       if( isSpecialError ){
 55774         -      /* If the query was read-only, we need do no rollback at all. Otherwise,
 55775         -      ** proceed with the special handling.
        56966  +      /* If the query was read-only and the error code is SQLITE_INTERRUPT, 
        56967  +      ** no rollback is necessary. Otherwise, at least a savepoint 
        56968  +      ** transaction must be rolled back to restore the database to a 
        56969  +      ** consistent state.
        56970  +      **
        56971  +      ** Even if the statement is read-only, it is important to perform
        56972  +      ** a statement or transaction rollback operation. If the error 
        56973  +      ** occured while writing to the journal, sub-journal or database
        56974  +      ** file as part of an effort to free up cache space (see function
        56975  +      ** pagerStress() in pager.c), the rollback is required to restore 
        56976  +      ** the pager to a consistent state.
 55776  56977         */
 55777  56978         if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
 55778  56979           if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
 55779  56980             eStatementOp = SAVEPOINT_ROLLBACK;
 55780  56981           }else{
 55781  56982             /* We are forced to roll back the active transaction. Before doing
 55782  56983             ** so, abort any other statements this handle currently has active.
................................................................................
 56918  58119   **
 56919  58120   ** This routine sets the error code and string returned by
 56920  58121   ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
 56921  58122   */
 56922  58123   SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
 56923  58124     int rc;
 56924  58125     if( pStmt==0 ){
        58126  +    /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
        58127  +    ** pointer is a harmless no-op. */
 56925  58128       rc = SQLITE_OK;
 56926  58129     }else{
 56927  58130       Vdbe *v = (Vdbe*)pStmt;
 56928  58131       sqlite3 *db = v->db;
 56929  58132   #if SQLITE_THREADSAFE
 56930  58133       sqlite3_mutex *mutex;
 56931  58134   #endif
................................................................................
 56994  58197   */
 56995  58198   SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
 56996  58199     Mem *p = (Mem*)pVal;
 56997  58200     if( p->flags & (MEM_Blob|MEM_Str) ){
 56998  58201       sqlite3VdbeMemExpandBlob(p);
 56999  58202       p->flags &= ~MEM_Str;
 57000  58203       p->flags |= MEM_Blob;
 57001         -    return p->z;
        58204  +    return p->n ? p->z : 0;
 57002  58205     }else{
 57003  58206       return sqlite3_value_text(pVal);
 57004  58207     }
 57005  58208   }
 57006  58209   SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
 57007  58210     return sqlite3ValueBytes(pVal, SQLITE_UTF8);
 57008  58211   }
................................................................................
 57348  58551     assert( p && p->pFunc );
 57349  58552     return p->pFunc->pUserData;
 57350  58553   }
 57351  58554   
 57352  58555   /*
 57353  58556   ** Extract the user data from a sqlite3_context structure and return a
 57354  58557   ** pointer to it.
        58558  +**
        58559  +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface
        58560  +** returns a copy of the pointer to the database connection (the 1st
        58561  +** parameter) of the sqlite3_create_function() and
        58562  +** sqlite3_create_function16() routines that originally registered the
        58563  +** application defined function.
 57355  58564   */
 57356  58565   SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
 57357  58566     assert( p && p->pFunc );
 57358  58567     return p->s.db;
 57359  58568   }
 57360  58569   
 57361  58570   /*
................................................................................
 57557  58766   **     sqlite3_column_int()
 57558  58767   **     sqlite3_column_int64()
 57559  58768   **     sqlite3_column_text()
 57560  58769   **     sqlite3_column_text16()
 57561  58770   **     sqlite3_column_real()
 57562  58771   **     sqlite3_column_bytes()
 57563  58772   **     sqlite3_column_bytes16()
 57564         -**
 57565         -** But not for sqlite3_column_blob(), which never calls malloc().
        58773  +**     sqiite3_column_blob()
 57566  58774   */
 57567  58775   static void columnMallocFailure(sqlite3_stmt *pStmt)
 57568  58776   {
 57569  58777     /* If malloc() failed during an encoding conversion within an
 57570  58778     ** sqlite3_column_XXX API, then set the return code of the statement to
 57571  58779     ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
 57572  58780     ** and _finalize() will return NOMEM.
................................................................................
 57826  59034     pVar = &p->aVar[i];
 57827  59035     sqlite3VdbeMemRelease(pVar);
 57828  59036     pVar->flags = MEM_Null;
 57829  59037     sqlite3Error(p->db, SQLITE_OK, 0);
 57830  59038   
 57831  59039     /* If the bit corresponding to this variable in Vdbe.expmask is set, then 
 57832  59040     ** binding a new value to this variable invalidates the current query plan.
        59041  +  **
        59042  +  ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
        59043  +  ** parameter in the WHERE clause might influence the choice of query plan
        59044  +  ** for a statement, then the statement will be automatically recompiled,
        59045  +  ** as if there had been a schema change, on the first sqlite3_step() call
        59046  +  ** following any change to the bindings of that parameter.
 57833  59047     */
 57834  59048     if( p->isPrepareV2 &&
 57835  59049        ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
 57836  59050     ){
 57837  59051       p->expired = 1;
 57838  59052     }
 57839  59053     return SQLITE_OK;
................................................................................
 58323  59537   ** Various scripts scan this source file in order to generate HTML
 58324  59538   ** documentation, headers files, or other derived files.  The formatting
 58325  59539   ** of the code in this file is, therefore, important.  See other comments
 58326  59540   ** in this file for details.  If in doubt, do not deviate from existing
 58327  59541   ** commenting and indentation practices when changing or adding code.
 58328  59542   */
 58329  59543   
        59544  +/*
        59545  +** Invoke this macro on memory cells just prior to changing the
        59546  +** value of the cell.  This macro verifies that shallow copies are
        59547  +** not misused.
        59548  +*/
        59549  +#ifdef SQLITE_DEBUG
        59550  +# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M)
        59551  +#else
        59552  +# define memAboutToChange(P,M)
        59553  +#endif
        59554  +
 58330  59555   /*
 58331  59556   ** The following global variable is incremented every time a cursor
 58332  59557   ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
 58333  59558   ** procedures use this information to make sure that indices are
 58334  59559   ** working correctly.  This variable has no function other than to
 58335  59560   ** help verify the correct operation of the library.
 58336  59561   */
................................................................................
 58515  59740   ** Try to convert a value into a numeric representation if we can
 58516  59741   ** do so without loss of information.  In other words, if the string
 58517  59742   ** looks like a number, convert it into a number.  If it does not
 58518  59743   ** look like a number, leave it alone.
 58519  59744   */
 58520  59745   static void applyNumericAffinity(Mem *pRec){
 58521  59746     if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
 58522         -    int realnum;
        59747  +    double rValue;
        59748  +    i64 iValue;
 58523  59749       u8 enc = pRec->enc;
 58524         -    sqlite3VdbeMemNulTerminate(pRec);
 58525         -    if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){
 58526         -      i64 value;
 58527         -      char *zUtf8 = pRec->z;
 58528         -#ifndef SQLITE_OMIT_UTF16
 58529         -      if( enc!=SQLITE_UTF8 ){
 58530         -        assert( pRec->db );
 58531         -        zUtf8 = sqlite3Utf16to8(pRec->db, pRec->z, pRec->n, enc);
 58532         -        if( !zUtf8 ) return;
 58533         -      }
 58534         -#endif
 58535         -      if( !realnum && sqlite3Atoi64(zUtf8, &value) ){
 58536         -        pRec->u.i = value;
 58537         -        MemSetTypeFlag(pRec, MEM_Int);
 58538         -      }else{
 58539         -        sqlite3AtoF(zUtf8, &pRec->r);
 58540         -        MemSetTypeFlag(pRec, MEM_Real);
 58541         -      }
 58542         -#ifndef SQLITE_OMIT_UTF16
 58543         -      if( enc!=SQLITE_UTF8 ){
 58544         -        sqlite3DbFree(pRec->db, zUtf8);
 58545         -      }
 58546         -#endif
        59750  +    if( (pRec->flags&MEM_Str)==0 ) return;
        59751  +    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
        59752  +    if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
        59753  +      pRec->u.i = iValue;
        59754  +      pRec->flags |= MEM_Int;
        59755  +    }else{
        59756  +      pRec->r = rValue;
        59757  +      pRec->flags |= MEM_Real;
 58547  59758       }
 58548  59759     }
 58549  59760   }
 58550  59761   
 58551  59762   /*
 58552  59763   ** Processing is determine by the affinity parameter:
 58553  59764   **
................................................................................
 59432  60643       ** value or convert mem[p2] to a different type.
 59433  60644       */
 59434  60645       assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
 59435  60646       if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
 59436  60647         assert( pOp->p2>0 );
 59437  60648         assert( pOp->p2<=p->nMem );
 59438  60649         pOut = &aMem[pOp->p2];
        60650  +      memAboutToChange(p, pOut);
 59439  60651         sqlite3VdbeMemReleaseExternal(pOut);
 59440  60652         pOut->flags = MEM_Int;
 59441  60653       }
 59442  60654   
 59443  60655       /* Sanity checking on other operands */
 59444  60656   #ifdef SQLITE_DEBUG
 59445  60657       if( (pOp->opflags & OPFLG_IN1)!=0 ){
 59446  60658         assert( pOp->p1>0 );
 59447  60659         assert( pOp->p1<=p->nMem );
        60660  +      assert( memIsValid(&aMem[pOp->p1]) );
 59448  60661         REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
 59449  60662       }
 59450  60663       if( (pOp->opflags & OPFLG_IN2)!=0 ){
 59451  60664         assert( pOp->p2>0 );
 59452  60665         assert( pOp->p2<=p->nMem );
        60666  +      assert( memIsValid(&aMem[pOp->p2]) );
 59453  60667         REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
 59454  60668       }
 59455  60669       if( (pOp->opflags & OPFLG_IN3)!=0 ){
 59456  60670         assert( pOp->p3>0 );
 59457  60671         assert( pOp->p3<=p->nMem );
        60672  +      assert( memIsValid(&aMem[pOp->p3]) );
 59458  60673         REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
 59459  60674       }
 59460  60675       if( (pOp->opflags & OPFLG_OUT2)!=0 ){
 59461  60676         assert( pOp->p2>0 );
 59462  60677         assert( pOp->p2<=p->nMem );
        60678  +      memAboutToChange(p, &aMem[pOp->p2]);
 59463  60679       }
 59464  60680       if( (pOp->opflags & OPFLG_OUT3)!=0 ){
 59465  60681         assert( pOp->p3>0 );
 59466  60682         assert( pOp->p3<=p->nMem );
        60683  +      memAboutToChange(p, &aMem[pOp->p3]);
 59467  60684       }
 59468  60685   #endif
 59469  60686     
 59470  60687       switch( pOp->opcode ){
 59471  60688   
 59472  60689   /*****************************************************************************
 59473  60690   ** What follows is a massive switch statement where each case implements a
................................................................................
 59521  60738   **
 59522  60739   ** Write the current address onto register P1
 59523  60740   ** and then jump to address P2.
 59524  60741   */
 59525  60742   case OP_Gosub: {            /* jump, in1 */
 59526  60743     pIn1 = &aMem[pOp->p1];
 59527  60744     assert( (pIn1->flags & MEM_Dyn)==0 );
        60745  +  memAboutToChange(p, pIn1);
 59528  60746     pIn1->flags = MEM_Int;
 59529  60747     pIn1->u.i = pc;
 59530  60748     REGISTER_TRACE(pOp->p1, pIn1);
 59531  60749     pc = pOp->p2 - 1;
 59532  60750     break;
 59533  60751   }
 59534  60752   
................................................................................
 59728  60946     break;
 59729  60947   }
 59730  60948   
 59731  60949   
 59732  60950   /* Opcode: Blob P1 P2 * P4
 59733  60951   **
 59734  60952   ** P4 points to a blob of data P1 bytes long.  Store this
 59735         -** blob in register P2. This instruction is not coded directly
 59736         -** by the compiler. Instead, the compiler layer specifies
 59737         -** an OP_HexBlob opcode, with the hex string representation of
 59738         -** the blob as P4. This opcode is transformed to an OP_Blob
 59739         -** the first time it is executed.
        60953  +** blob in register P2.
 59740  60954   */
 59741  60955   case OP_Blob: {                /* out2-prerelease */
 59742  60956     assert( pOp->p1 <= SQLITE_MAX_LENGTH );
 59743  60957     sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
 59744  60958     pOut->enc = encoding;
 59745  60959     UPDATE_MAX_BLOBSIZE(pOut);
 59746  60960     break;
................................................................................
 59790  61004     assert( u.ac.p1+u.ac.n<=u.ac.p2 || u.ac.p2+u.ac.n<=u.ac.p1 );
 59791  61005   
 59792  61006     pIn1 = &aMem[u.ac.p1];
 59793  61007     pOut = &aMem[u.ac.p2];
 59794  61008     while( u.ac.n-- ){
 59795  61009       assert( pOut<=&aMem[p->nMem] );
 59796  61010       assert( pIn1<=&aMem[p->nMem] );
        61011  +    assert( memIsValid(pIn1) );
        61012  +    memAboutToChange(p, pOut);
 59797  61013       u.ac.zMalloc = pOut->zMalloc;
 59798  61014       pOut->zMalloc = 0;
 59799  61015       sqlite3VdbeMemMove(pOut, pIn1);
 59800  61016       pIn1->zMalloc = u.ac.zMalloc;
 59801  61017       REGISTER_TRACE(u.ac.p2++, pOut);
 59802  61018       pIn1++;
 59803  61019       pOut++;
................................................................................
 59835  61051   ** copy.
 59836  61052   */
 59837  61053   case OP_SCopy: {            /* in1, out2 */
 59838  61054     pIn1 = &aMem[pOp->p1];
 59839  61055     pOut = &aMem[pOp->p2];
 59840  61056     assert( pOut!=pIn1 );
 59841  61057     sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
        61058  +#ifdef SQLITE_DEBUG
        61059  +  if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
        61060  +#endif
 59842  61061     REGISTER_TRACE(pOp->p2, pOut);
 59843  61062     break;
 59844  61063   }
 59845  61064   
 59846  61065   /* Opcode: ResultRow P1 P2 * * *
 59847  61066   **
 59848  61067   ** The registers P1 through P1+P2-1 contain a single row of
................................................................................
 59895  61114   
 59896  61115     /* Make sure the results of the current row are \000 terminated
 59897  61116     ** and have an assigned type.  The results are de-ephemeralized as
 59898  61117     ** as side effect.
 59899  61118     */
 59900  61119     u.ad.pMem = p->pResultSet = &aMem[pOp->p1];
 59901  61120     for(u.ad.i=0; u.ad.i<pOp->p2; u.ad.i++){
        61121  +    assert( memIsValid(&u.ad.pMem[u.ad.i]) );
        61122  +    Deephemeralize(&u.ad.pMem[u.ad.i]);
        61123  +    assert( (u.ad.pMem[u.ad.i].flags & MEM_Ephem)==0
        61124  +            || (u.ad.pMem[u.ad.i].flags & (MEM_Str|MEM_Blob))==0 );
 59902  61125       sqlite3VdbeMemNulTerminate(&u.ad.pMem[u.ad.i]);
 59903  61126       sqlite3VdbeMemStoreType(&u.ad.pMem[u.ad.i]);
 59904  61127       REGISTER_TRACE(pOp->p1+u.ad.i, &u.ad.pMem[u.ad.i]);
 59905  61128     }
 59906  61129     if( db->mallocFailed ) goto no_mem;
 59907  61130   
 59908  61131     /* Return SQLITE_ROW
................................................................................
 60126  61349     sqlite3_value **apVal;
 60127  61350     int n;
 60128  61351   #endif /* local variables moved into u.ag */
 60129  61352   
 60130  61353     u.ag.n = pOp->p5;
 60131  61354     u.ag.apVal = p->apArg;
 60132  61355     assert( u.ag.apVal || u.ag.n==0 );
        61356  +  assert( pOp->p3>0 && pOp->p3<=p->nMem );
        61357  +  pOut = &aMem[pOp->p3];
        61358  +  memAboutToChange(p, pOut);
 60133  61359   
 60134  61360     assert( u.ag.n==0 || (pOp->p2>0 && pOp->p2+u.ag.n<=p->nMem+1) );
 60135  61361     assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ag.n );
 60136  61362     u.ag.pArg = &aMem[pOp->p2];
 60137  61363     for(u.ag.i=0; u.ag.i<u.ag.n; u.ag.i++, u.ag.pArg++){
        61364  +    assert( memIsValid(u.ag.pArg) );
 60138  61365       u.ag.apVal[u.ag.i] = u.ag.pArg;
        61366  +    Deephemeralize(u.ag.pArg);
 60139  61367       sqlite3VdbeMemStoreType(u.ag.pArg);
 60140  61368       REGISTER_TRACE(pOp->p2+u.ag.i, u.ag.pArg);
 60141  61369     }
 60142  61370   
 60143  61371     assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
 60144  61372     if( pOp->p4type==P4_FUNCDEF ){
 60145  61373       u.ag.ctx.pFunc = pOp->p4.pFunc;
 60146  61374       u.ag.ctx.pVdbeFunc = 0;
 60147  61375     }else{
 60148  61376       u.ag.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
 60149  61377       u.ag.ctx.pFunc = u.ag.ctx.pVdbeFunc->pFunc;
 60150  61378     }
 60151  61379   
 60152         -  assert( pOp->p3>0 && pOp->p3<=p->nMem );
 60153         -  pOut = &aMem[pOp->p3];
 60154  61380     u.ag.ctx.s.flags = MEM_Null;
 60155  61381     u.ag.ctx.s.db = db;
 60156  61382     u.ag.ctx.s.xDel = 0;
 60157  61383     u.ag.ctx.s.zMalloc = 0;
 60158  61384   
 60159  61385     /* The output cell may already have a buffer allocated. Move
 60160  61386     ** the pointer to u.ag.ctx.s so in case the user-function can use
................................................................................
 60166  61392     u.ag.ctx.isError = 0;
 60167  61393     if( u.ag.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
 60168  61394       assert( pOp>aOp );
 60169  61395       assert( pOp[-1].p4type==P4_COLLSEQ );
 60170  61396       assert( pOp[-1].opcode==OP_CollSeq );
 60171  61397       u.ag.ctx.pColl = pOp[-1].p4.pColl;
 60172  61398     }
 60173         -  (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal);
        61399  +  (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal); /* IMP: R-24505-23230 */
 60174  61400     if( db->mallocFailed ){
 60175  61401       /* Even though a malloc() has failed, the implementation of the
 60176  61402       ** user function may have called an sqlite3_result_XXX() function
 60177  61403       ** to return a value. The following call releases any resources
 60178  61404       ** associated with such a value.
 60179  61405       */
 60180  61406       sqlite3VdbeMemRelease(&u.ag.ctx.s);
................................................................................
 60218  61444   ** Take the bit-wise OR of the values in register P1 and P2 and
 60219  61445   ** store the result in register P3.
 60220  61446   ** If either input is NULL, the result is NULL.
 60221  61447   */
 60222  61448   /* Opcode: ShiftLeft P1 P2 P3 * *
 60223  61449   **
 60224  61450   ** Shift the integer value in register P2 to the left by the
 60225         -** number of bits specified by the integer in regiser P1.
        61451  +** number of bits specified by the integer in register P1.
 60226  61452   ** Store the result in register P3.
 60227  61453   ** If either input is NULL, the result is NULL.
 60228  61454   */
 60229  61455   /* Opcode: ShiftRight P1 P2 P3 * *
 60230  61456   **
 60231  61457   ** Shift the integer value in register P2 to the right by the
 60232  61458   ** number of bits specified by the integer in register P1.
................................................................................
 60268  61494   ** Add the constant P2 to the value in register P1.
 60269  61495   ** The result is always an integer.
 60270  61496   **
 60271  61497   ** To force any register to be an integer, just add 0.
 60272  61498   */
 60273  61499   case OP_AddImm: {            /* in1 */
 60274  61500     pIn1 = &aMem[pOp->p1];
        61501  +  memAboutToChange(p, pIn1);
 60275  61502     sqlite3VdbeMemIntegerify(pIn1);
 60276  61503     pIn1->u.i += pOp->p2;
 60277  61504     break;
 60278  61505   }
 60279  61506   
 60280  61507   /* Opcode: MustBeInt P1 P2 * * *
 60281  61508   ** 
................................................................................
 60282  61509   ** Force the value in register P1 to be an integer.  If the value
 60283  61510   ** in P1 is not an integer and cannot be converted into an integer
 60284  61511   ** without data loss, then jump immediately to P2, or if P2==0
 60285  61512   ** raise an SQLITE_MISMATCH exception.
 60286  61513   */
 60287  61514   case OP_MustBeInt: {            /* jump, in1 */
 60288  61515     pIn1 = &aMem[pOp->p1];
        61516  +  memAboutToChange(p, pIn1);
 60289  61517     applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
 60290  61518     if( (pIn1->flags & MEM_Int)==0 ){
 60291  61519       if( pOp->p2==0 ){
 60292  61520         rc = SQLITE_MISMATCH;
 60293  61521         goto abort_due_to_error;
 60294  61522       }else{
 60295  61523         pc = pOp->p2 - 1;
................................................................................
 60327  61555   ** equivalent of printf().  Blob values are unchanged and
 60328  61556   ** are afterwards simply interpreted as text.
 60329  61557   **
 60330  61558   ** A NULL value is not changed by this routine.  It remains NULL.
 60331  61559   */
 60332  61560   case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
 60333  61561     pIn1 = &aMem[pOp->p1];
        61562  +  memAboutToChange(p, pIn1);
 60334  61563     if( pIn1->flags & MEM_Null ) break;
 60335  61564     assert( MEM_Str==(MEM_Blob>>3) );
 60336  61565     pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
 60337  61566     applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
 60338  61567     rc = ExpandBlob(pIn1);
 60339  61568     assert( pIn1->flags & MEM_Str || db->mallocFailed );
 60340  61569     pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
................................................................................
 60373  61602   ** equivalent of atoi() or atof() and store 0 if no such conversion 
 60374  61603   ** is possible.
 60375  61604   **
 60376  61605   ** A NULL value is not changed by this routine.  It remains NULL.
 60377  61606   */
 60378  61607   case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, in1 */
 60379  61608     pIn1 = &aMem[pOp->p1];
 60380         -  if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){
 60381         -    sqlite3VdbeMemNumerify(pIn1);
 60382         -  }
        61609  +  sqlite3VdbeMemNumerify(pIn1);
 60383  61610     break;
 60384  61611   }
 60385  61612   #endif /* SQLITE_OMIT_CAST */
 60386  61613   
 60387  61614   /* Opcode: ToInt P1 * * * *
 60388  61615   **
 60389         -** Force the value in register P1 be an integer.  If
        61616  +** Force the value in register P1 to be an integer.  If
 60390  61617   ** The value is currently a real number, drop its fractional part.
 60391  61618   ** If the value is text or blob, try to convert it to an integer using the
 60392  61619   ** equivalent of atoi() and store 0 if no such conversion is possible.
 60393  61620   **
 60394  61621   ** A NULL value is not changed by this routine.  It remains NULL.
 60395  61622   */
 60396  61623   case OP_ToInt: {                  /* same as TK_TO_INT, in1 */
................................................................................
 60409  61636   ** If the value is text or blob, try to convert it to an integer using the
 60410  61637   ** equivalent of atoi() and store 0.0 if no such conversion is possible.
 60411  61638   **
 60412  61639   ** A NULL value is not changed by this routine.  It remains NULL.
 60413  61640   */
 60414  61641   case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */
 60415  61642     pIn1 = &aMem[pOp->p1];
        61643  +  memAboutToChange(p, pIn1);
 60416  61644     if( (pIn1->flags & MEM_Null)==0 ){
 60417  61645       sqlite3VdbeMemRealify(pIn1);
 60418  61646     }
 60419  61647     break;
 60420  61648   }
 60421  61649   #endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
 60422  61650   
................................................................................
 60423  61651   /* Opcode: Lt P1 P2 P3 P4 P5
 60424  61652   **
 60425  61653   ** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then
 60426  61654   ** jump to address P2.  
 60427  61655   **
 60428  61656   ** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
 60429  61657   ** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL 
 60430         -** bit is clear then fall thru if either operand is NULL.
        61658  +** bit is clear then fall through if either operand is NULL.
 60431  61659   **
 60432  61660   ** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
 60433  61661   ** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
 60434  61662   ** to coerce both inputs according to this affinity before the
 60435  61663   ** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
 60436  61664   ** affinity is used. Note that the affinity conversions are stored
 60437  61665   ** back into the input registers P1 and P3.  So this opcode can cause
................................................................................
 60553  61781       case OP_Le:    u.ai.res = u.ai.res<=0;     break;
 60554  61782       case OP_Gt:    u.ai.res = u.ai.res>0;      break;
 60555  61783       default:       u.ai.res = u.ai.res>=0;     break;
 60556  61784     }
 60557  61785   
 60558  61786     if( pOp->p5 & SQLITE_STOREP2 ){
 60559  61787       pOut = &aMem[pOp->p2];
        61788  +    memAboutToChange(p, pOut);
 60560  61789       MemSetTypeFlag(pOut, MEM_Int);
 60561  61790       pOut->u.i = u.ai.res;
 60562  61791       REGISTER_TRACE(pOp->p2, pOut);
 60563  61792     }else if( u.ai.res ){
 60564  61793       pc = pOp->p2-1;
 60565  61794     }
 60566  61795   
................................................................................
 60584  61813     assert( pOp->p4.ai );
 60585  61814     aPermute = pOp->p4.ai;
 60586  61815     break;
 60587  61816   }
 60588  61817   
 60589  61818   /* Opcode: Compare P1 P2 P3 P4 *
 60590  61819   **
 60591         -** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this
 60592         -** one "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
        61820  +** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
        61821  +** vector "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
 60593  61822   ** the comparison for use by the next OP_Jump instruct.
 60594  61823   **
 60595  61824   ** P4 is a KeyInfo structure that defines collating sequences and sort
 60596  61825   ** orders for the comparison.  The permutation applies to registers
 60597  61826   ** only.  The KeyInfo elements are used sequentially.
 60598  61827   **
 60599  61828   ** The comparison is a sort comparison, so NULLs compare equal,
................................................................................
 60627  61856     }else{
 60628  61857       assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 );
 60629  61858       assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 );
 60630  61859     }
 60631  61860   #endif /* SQLITE_DEBUG */
 60632  61861     for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++){
 60633  61862       u.aj.idx = aPermute ? aPermute[u.aj.i] : u.aj.i;
        61863  +    assert( memIsValid(&aMem[u.aj.p1+u.aj.idx]) );
        61864  +    assert( memIsValid(&aMem[u.aj.p2+u.aj.idx]) );
 60634  61865       REGISTER_TRACE(u.aj.p1+u.aj.idx, &aMem[u.aj.p1+u.aj.idx]);
 60635  61866       REGISTER_TRACE(u.aj.p2+u.aj.idx, &aMem[u.aj.p2+u.aj.idx]);
 60636  61867       assert( u.aj.i<u.aj.pKeyInfo->nField );
 60637  61868       u.aj.pColl = u.aj.pKeyInfo->aColl[u.aj.i];
 60638  61869       u.aj.bRev = u.aj.pKeyInfo->aSortOrder[u.aj.i];
 60639  61870       iCompare = sqlite3MemCompare(&aMem[u.aj.p1+u.aj.idx], &aMem[u.aj.p2+u.aj.idx], u.aj.pColl);
 60640  61871       if( iCompare ){
................................................................................
 60858  62089     u.am.p1 = pOp->p1;
 60859  62090     u.am.p2 = pOp->p2;
 60860  62091     u.am.pC = 0;
 60861  62092     memset(&u.am.sMem, 0, sizeof(u.am.sMem));
 60862  62093     assert( u.am.p1<p->nCursor );
 60863  62094     assert( pOp->p3>0 && pOp->p3<=p->nMem );
 60864  62095     u.am.pDest = &aMem[pOp->p3];
        62096  +  memAboutToChange(p, u.am.pDest);
 60865  62097     MemSetTypeFlag(u.am.pDest, MEM_Null);
 60866  62098     u.am.zRec = 0;
 60867  62099   
 60868  62100     /* This block sets the variable u.am.payloadSize to be the total number of
 60869  62101     ** bytes in the record.
 60870  62102     **
 60871  62103     ** u.am.zRec is set to be the complete text of the record if it is available.
................................................................................
 60905  62137         assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
 60906  62138         rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
 60907  62139         assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
 60908  62140       }
 60909  62141     }else if( u.am.pC->pseudoTableReg>0 ){
 60910  62142       u.am.pReg = &aMem[u.am.pC->pseudoTableReg];
 60911  62143       assert( u.am.pReg->flags & MEM_Blob );
        62144  +    assert( memIsValid(u.am.pReg) );
 60912  62145       u.am.payloadSize = u.am.pReg->n;
 60913  62146       u.am.zRec = u.am.pReg->z;
 60914  62147       u.am.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
 60915  62148       assert( u.am.payloadSize==0 || u.am.zRec!=0 );
 60916  62149     }else{
 60917  62150       /* Consider the row to be NULL */
 60918  62151       u.am.payloadSize = 0;
................................................................................
 61129  62362   
 61130  62363     u.an.zAffinity = pOp->p4.z;
 61131  62364     assert( u.an.zAffinity!=0 );
 61132  62365     assert( u.an.zAffinity[pOp->p2]==0 );
 61133  62366     pIn1 = &aMem[pOp->p1];
 61134  62367     while( (u.an.cAff = *(u.an.zAffinity++))!=0 ){
 61135  62368       assert( pIn1 <= &p->aMem[p->nMem] );
        62369  +    assert( memIsValid(pIn1) );
 61136  62370       ExpandBlob(pIn1);
 61137  62371       applyAffinity(pIn1, u.an.cAff, encoding);
 61138  62372       pIn1++;
 61139  62373     }
 61140  62374     break;
 61141  62375   }
 61142  62376   
 61143  62377   /* Opcode: MakeRecord P1 P2 P3 P4 *
 61144  62378   **
 61145         -** Convert P2 registers beginning with P1 into a single entry
 61146         -** suitable for use as a data record in a database table or as a key
 61147         -** in an index.  The details of the format are irrelevant as long as
 61148         -** the OP_Column opcode can decode the record later.
 61149         -** Refer to source code comments for the details of the record
 61150         -** format.
        62379  +** Convert P2 registers beginning with P1 into the [record format]
        62380  +** use as a data record in a database table or as a key
        62381  +** in an index.  The OP_Column opcode can decode the record later.
 61151  62382   **
 61152  62383   ** P4 may be a string that is P2 characters long.  The nth character of the
 61153  62384   ** string indicates the column affinity that should be used for the nth
 61154  62385   ** field of the index key.
 61155  62386   **
 61156  62387   ** The mapping from character to affinity is given by the SQLITE_AFF_
 61157  62388   ** macros defined in sqliteInt.h.
................................................................................
 61199  62430     u.ao.nField = pOp->p1;
 61200  62431     u.ao.zAffinity = pOp->p4.z;
 61201  62432     assert( u.ao.nField>0 && pOp->p2>0 && pOp->p2+u.ao.nField<=p->nMem+1 );
 61202  62433     u.ao.pData0 = &aMem[u.ao.nField];
 61203  62434     u.ao.nField = pOp->p2;
 61204  62435     u.ao.pLast = &u.ao.pData0[u.ao.nField-1];
 61205  62436     u.ao.file_format = p->minWriteFileFormat;
        62437  +
        62438  +  /* Identify the output register */
        62439  +  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
        62440  +  pOut = &aMem[pOp->p3];
        62441  +  memAboutToChange(p, pOut);
 61206  62442   
 61207  62443     /* Loop through the elements that will make up the record to figure
 61208  62444     ** out how much space is required for the new record.
 61209  62445     */
 61210  62446     for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){
        62447  +    assert( memIsValid(u.ao.pRec) );
 61211  62448       if( u.ao.zAffinity ){
 61212  62449         applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding);
 61213  62450       }
 61214  62451       if( u.ao.pRec->flags&MEM_Zero && u.ao.pRec->n>0 ){
 61215  62452         sqlite3VdbeMemExpandBlob(u.ao.pRec);
 61216  62453       }
 61217  62454       u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format);
................................................................................
 61238  62475     }
 61239  62476   
 61240  62477     /* Make sure the output register has a buffer large enough to store
 61241  62478     ** the new record. The output register (pOp->p3) is not allowed to
 61242  62479     ** be one of the input registers (because the following call to
 61243  62480     ** sqlite3VdbeMemGrow() could clobber the value before it is used).
 61244  62481     */
 61245         -  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
 61246         -  pOut = &aMem[pOp->p3];
 61247  62482     if( sqlite3VdbeMemGrow(pOut, (int)u.ao.nByte, 0) ){
 61248  62483       goto no_mem;
 61249  62484     }
 61250  62485     u.ao.zNewRecord = (u8 *)pOut->z;
 61251  62486   
 61252  62487     /* Write the record */
 61253  62488     u.ao.i = putVarint32(u.ao.zNewRecord, u.ao.nHdr);
................................................................................
 61412  62647             if( rc!=SQLITE_OK ){
 61413  62648               goto abort_due_to_error;
 61414  62649             }
 61415  62650           }
 61416  62651           if( u.aq.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
 61417  62652             sqlite3ExpirePreparedStatements(db);
 61418  62653             sqlite3ResetInternalSchema(db, 0);
        62654  +          db->flags = (db->flags | SQLITE_InternChanges);
 61419  62655           }
 61420  62656         }
 61421  62657   
 61422  62658         /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
 61423  62659         ** savepoints nested inside of the savepoint being operated on. */
 61424  62660         while( db->pSavepoint!=u.aq.pSavepoint ){
 61425  62661           u.aq.pTmp = db->pSavepoint;
................................................................................
 61802  63038     }else{
 61803  63039       u.aw.wrFlag = 0;
 61804  63040     }
 61805  63041     if( pOp->p5 ){
 61806  63042       assert( u.aw.p2>0 );
 61807  63043       assert( u.aw.p2<=p->nMem );
 61808  63044       pIn2 = &aMem[u.aw.p2];
        63045  +    assert( memIsValid(pIn2) );
        63046  +    assert( (pIn2->flags & MEM_Int)!=0 );
 61809  63047       sqlite3VdbeMemIntegerify(pIn2);
 61810  63048       u.aw.p2 = (int)pIn2->u.i;
 61811  63049       /* The u.aw.p2 value always comes from a prior OP_CreateTable opcode and
 61812  63050       ** that opcode will always set the u.aw.p2 value to 2 or more or else fail.
 61813  63051       ** If there were a failure, the prepared statement would have halted
 61814  63052       ** before reaching this instruction. */
 61815  63053       if( NEVER(u.aw.p2<2) ) {
................................................................................
 61824  63062     }else if( pOp->p4type==P4_INT32 ){
 61825  63063       u.aw.nField = pOp->p4.i;
 61826  63064     }
 61827  63065     assert( pOp->p1>=0 );
 61828  63066     u.aw.pCur = allocateCursor(p, pOp->p1, u.aw.nField, u.aw.iDb, 1);
 61829  63067     if( u.aw.pCur==0 ) goto no_mem;
 61830  63068     u.aw.pCur->nullRow = 1;
        63069  +  u.aw.pCur->isOrdered = 1;
 61831  63070     rc = sqlite3BtreeCursor(u.aw.pX, u.aw.p2, u.aw.wrFlag, u.aw.pKeyInfo, u.aw.pCur->pCursor);
 61832  63071     u.aw.pCur->pKeyInfo = u.aw.pKeyInfo;
 61833  63072   
 61834  63073     /* Since it performs no memory allocation or IO, the only values that
 61835  63074     ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK.
 61836  63075     ** SQLITE_EMPTY is only returned when attempting to open the table
 61837  63076     ** rooted at page 1 of a zero-byte database.  */
................................................................................
 61876  63115   ** indices in joins.
 61877  63116   */
 61878  63117   case OP_OpenAutoindex: 
 61879  63118   case OP_OpenEphemeral: {
 61880  63119   #if 0  /* local variables moved into u.ax */
 61881  63120     VdbeCursor *pCx;
 61882  63121   #endif /* local variables moved into u.ax */
 61883         -  static const int openFlags =
        63122  +  static const int vfsFlags =
 61884  63123         SQLITE_OPEN_READWRITE |
 61885  63124         SQLITE_OPEN_CREATE |
 61886  63125         SQLITE_OPEN_EXCLUSIVE |
 61887  63126         SQLITE_OPEN_DELETEONCLOSE |
 61888  63127         SQLITE_OPEN_TRANSIENT_DB;
 61889  63128   
 61890  63129     assert( pOp->p1>=0 );
 61891  63130     u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
 61892  63131     if( u.ax.pCx==0 ) goto no_mem;
 61893  63132     u.ax.pCx->nullRow = 1;
 61894         -  rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
 61895         -                           &u.ax.pCx->pBt);
        63133  +  rc = sqlite3BtreeOpen(0, db, &u.ax.pCx->pBt,
        63134  +                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
 61896  63135     if( rc==SQLITE_OK ){
 61897  63136       rc = sqlite3BtreeBeginTrans(u.ax.pCx->pBt, 1);
 61898  63137     }
 61899  63138     if( rc==SQLITE_OK ){
 61900  63139       /* If a transient index is required, create it by calling
 61901         -    ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
        63140  +    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
 61902  63141       ** opening it. If a transient table is required, just use the
 61903         -    ** automatically created table with root-page 1 (an INTKEY table).
        63142  +    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
 61904  63143       */
 61905  63144       if( pOp->p4.pKeyInfo ){
 61906  63145         int pgno;
 61907  63146         assert( pOp->p4type==P4_KEYINFO );
 61908         -      rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_ZERODATA);
        63147  +      rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_BLOBKEY);
 61909  63148         if( rc==SQLITE_OK ){
 61910  63149           assert( pgno==MASTER_ROOT+1 );
 61911  63150           rc = sqlite3BtreeCursor(u.ax.pCx->pBt, pgno, 1,
 61912  63151                                   (KeyInfo*)pOp->p4.z, u.ax.pCx->pCursor);
 61913  63152           u.ax.pCx->pKeyInfo = pOp->p4.pKeyInfo;
 61914  63153           u.ax.pCx->pKeyInfo->enc = ENC(p->db);
 61915  63154         }
 61916  63155         u.ax.pCx->isTable = 0;
 61917  63156       }else{
 61918  63157         rc = sqlite3BtreeCursor(u.ax.pCx->pBt, MASTER_ROOT, 1, 0, u.ax.pCx->pCursor);
 61919  63158         u.ax.pCx->isTable = 1;
 61920  63159       }
 61921  63160     }
        63161  +  u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
 61922  63162     u.ax.pCx->isIndex = !u.ax.pCx->isTable;
 61923  63163     break;
 61924  63164   }
 61925  63165   
 61926  63166   /* Opcode: OpenPseudo P1 P2 P3 * *
 61927  63167   **
 61928  63168   ** Open a new cursor that points to a fake table that contains a single
................................................................................
 62034  63274     assert( pOp->p2!=0 );
 62035  63275     u.az.pC = p->apCsr[pOp->p1];
 62036  63276     assert( u.az.pC!=0 );
 62037  63277     assert( u.az.pC->pseudoTableReg==0 );
 62038  63278     assert( OP_SeekLe == OP_SeekLt+1 );
 62039  63279     assert( OP_SeekGe == OP_SeekLt+2 );
 62040  63280     assert( OP_SeekGt == OP_SeekLt+3 );
        63281  +  assert( u.az.pC->isOrdered );
 62041  63282     if( u.az.pC->pCursor!=0 ){
 62042  63283       u.az.oc = pOp->opcode;
 62043  63284       u.az.pC->nullRow = 0;
 62044  63285       if( u.az.pC->isTable ){
 62045  63286         /* The input value in P3 might be of any type: integer, real, string,
 62046  63287         ** blob, or NULL.  But it needs to be an integer before we can do
 62047  63288         ** the seek, so covert it. */
................................................................................
 62116  63357         u.az.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.az.oc - OP_SeekLt)));
 62117  63358         assert( u.az.oc!=OP_SeekGt || u.az.r.flags==UNPACKED_INCRKEY );
 62118  63359         assert( u.az.oc!=OP_SeekLe || u.az.r.flags==UNPACKED_INCRKEY );
 62119  63360         assert( u.az.oc!=OP_SeekGe || u.az.r.flags==0 );
 62120  63361         assert( u.az.oc!=OP_SeekLt || u.az.r.flags==0 );
 62121  63362   
 62122  63363         u.az.r.aMem = &aMem[pOp->p3];
        63364  +#ifdef SQLITE_DEBUG
        63365  +      { int i; for(i=0; i<u.az.r.nField; i++) assert( memIsValid(&u.az.r.aMem[i]) ); }
        63366  +#endif
 62123  63367         ExpandBlob(u.az.r.aMem);
 62124  63368         rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res);
 62125  63369         if( rc!=SQLITE_OK ){
 62126  63370           goto abort_due_to_error;
 62127  63371         }
 62128  63372         u.az.pC->rowidIsValid = 0;
 62129  63373       }
................................................................................
 62244  63488     if( ALWAYS(u.bb.pC->pCursor!=0) ){
 62245  63489   
 62246  63490       assert( u.bb.pC->isTable==0 );
 62247  63491       if( pOp->p4.i>0 ){
 62248  63492         u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo;
 62249  63493         u.bb.r.nField = (u16)pOp->p4.i;
 62250  63494         u.bb.r.aMem = pIn3;
        63495  +#ifdef SQLITE_DEBUG
        63496  +      { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); }
        63497  +#endif
 62251  63498         u.bb.r.flags = UNPACKED_PREFIX_MATCH;
 62252  63499         u.bb.pIdxKey = &u.bb.r;
 62253  63500       }else{
 62254  63501         assert( pIn3->flags & MEM_Blob );
 62255         -      ExpandBlob(pIn3);
        63502  +      assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
 62256  63503         u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z,
 62257  63504                                           u.bb.aTempRec, sizeof(u.bb.aTempRec));
 62258  63505         if( u.bb.pIdxKey==0 ){
 62259  63506           goto no_mem;
 62260  63507         }
 62261  63508         u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
 62262  63509       }
................................................................................
 62343  63590   
 62344  63591     if( u.bc.pCrsr!=0 ){
 62345  63592       /* Populate the index search key. */
 62346  63593       u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo;
 62347  63594       u.bc.r.nField = u.bc.nField + 1;
 62348  63595       u.bc.r.flags = UNPACKED_PREFIX_SEARCH;
 62349  63596       u.bc.r.aMem = u.bc.aMx;
        63597  +#ifdef SQLITE_DEBUG
        63598  +    { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); }
        63599  +#endif
 62350  63600   
 62351  63601       /* Extract the value of u.bc.R from register P3. */
 62352  63602       sqlite3VdbeMemIntegerify(pIn3);
 62353  63603       u.bc.R = pIn3->u.i;
 62354  63604   
 62355  63605       /* Search the B-Tree index. If no conflicting record is found, jump
 62356  63606       ** to P2. Otherwise, copy the rowid of the conflicting record to
................................................................................
 62365  63615     break;
 62366  63616   }
 62367  63617   
 62368  63618   /* Opcode: NotExists P1 P2 P3 * *
 62369  63619   **
 62370  63620   ** Use the content of register P3 as a integer key.  If a record 
 62371  63621   ** with that key does not exist in table of P1, then jump to P2. 
 62372         -** If the record does exist, then fall thru.  The cursor is left 
        63622  +** If the record does exist, then fall through.  The cursor is left 
 62373  63623   ** pointing to the record if it exists.
 62374  63624   **
 62375  63625   ** The difference between this operation and NotFound is that this
 62376  63626   ** operation assumes the key is an integer and that P1 is a table whereas
 62377  63627   ** NotFound assumes key is a blob constructed from MakeRecord and
 62378  63628   ** P1 is an index.
 62379  63629   **
................................................................................
 62523  63773             /* Assert that P3 is a valid memory cell. */
 62524  63774             assert( pOp->p3<=u.be.pFrame->nMem );
 62525  63775             u.be.pMem = &u.be.pFrame->aMem[pOp->p3];
 62526  63776           }else{
 62527  63777             /* Assert that P3 is a valid memory cell. */
 62528  63778             assert( pOp->p3<=p->nMem );
 62529  63779             u.be.pMem = &aMem[pOp->p3];
        63780  +          memAboutToChange(p, u.be.pMem);
 62530  63781           }
        63782  +        assert( memIsValid(u.be.pMem) );
 62531  63783   
 62532  63784           REGISTER_TRACE(pOp->p3, u.be.pMem);
 62533  63785           sqlite3VdbeMemIntegerify(u.be.pMem);
 62534  63786           assert( (u.be.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
 62535  63787           if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){
 62536  63788             rc = SQLITE_FULL;   /* IMP: R-12275-61338 */
 62537  63789             goto abort_due_to_error;
................................................................................
 62542  63794           u.be.pMem->u.i = u.be.v;
 62543  63795         }
 62544  63796   #endif
 62545  63797   
 62546  63798         sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0);
 62547  63799       }
 62548  63800       if( u.be.pC->useRandomRowid ){
 62549         -      /* IMPLEMENTATION-OF: R-48598-02938 If the largest ROWID is equal to the
        63801  +      /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
 62550  63802         ** largest possible integer (9223372036854775807) then the database
 62551         -      ** engine starts picking candidate ROWIDs at random until it finds one
 62552         -      ** that is not previously used.
 62553         -      */
        63803  +      ** engine starts picking positive candidate ROWIDs at random until
        63804  +      ** it finds one that is not previously used. */
 62554  63805         assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
 62555  63806                                ** an AUTOINCREMENT table. */
        63807  +      /* on the first attempt, simply do one more than previous */
 62556  63808         u.be.v = db->lastRowid;
        63809  +      u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
        63810  +      u.be.v++; /* ensure non-zero */
 62557  63811         u.be.cnt = 0;
 62558         -      do{
 62559         -        if( u.be.cnt==0 && (u.be.v&0xffffff)==u.be.v ){
 62560         -          u.be.v++;
        63812  +      while(   ((rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v,
        63813  +                                                 0, &u.be.res))==SQLITE_OK)
        63814  +            && (u.be.res==0)
        63815  +            && (++u.be.cnt<100)){
        63816  +        /* collision - try another random rowid */
        63817  +        sqlite3_randomness(sizeof(u.be.v), &u.be.v);
        63818  +        if( u.be.cnt<5 ){
        63819  +          /* try "small" random rowids for the initial attempts */
        63820  +          u.be.v &= 0xffffff;
 62561  63821           }else{
 62562         -          sqlite3_randomness(sizeof(u.be.v), &u.be.v);
 62563         -          if( u.be.cnt<5 ) u.be.v &= 0xffffff;
        63822  +          u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
 62564  63823           }
 62565         -        rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, 0, &u.be.res);
 62566         -        u.be.cnt++;
 62567         -      }while( u.be.cnt<100 && rc==SQLITE_OK && u.be.res==0 );
        63824  +        u.be.v++; /* ensure non-zero */
        63825  +      }
 62568  63826         if( rc==SQLITE_OK && u.be.res==0 ){
 62569  63827           rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
 62570  63828           goto abort_due_to_error;
 62571  63829         }
        63830  +      assert( u.be.v>0 );  /* EV: R-40812-03570 */
 62572  63831       }
 62573  63832       u.be.pC->rowidIsValid = 0;
 62574  63833       u.be.pC->deferredMoveto = 0;
 62575  63834       u.be.pC->cacheStatus = CACHE_STALE;
 62576  63835     }
 62577  63836     pOut->u.i = u.be.v;
 62578  63837     break;
................................................................................
 62634  63893     const char *zDb;  /* database name - used by the update hook */
 62635  63894     const char *zTbl; /* Table name - used by the opdate hook */
 62636  63895     int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
 62637  63896   #endif /* local variables moved into u.bf */
 62638  63897   
 62639  63898     u.bf.pData = &aMem[pOp->p2];
 62640  63899     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
        63900  +  assert( memIsValid(u.bf.pData) );
 62641  63901     u.bf.pC = p->apCsr[pOp->p1];
 62642  63902     assert( u.bf.pC!=0 );
 62643  63903     assert( u.bf.pC->pCursor!=0 );
 62644  63904     assert( u.bf.pC->pseudoTableReg==0 );
 62645  63905     assert( u.bf.pC->isTable );
 62646  63906     REGISTER_TRACE(pOp->p2, u.bf.pData);
 62647  63907   
 62648  63908     if( pOp->opcode==OP_Insert ){
 62649  63909       u.bf.pKey = &aMem[pOp->p3];
 62650  63910       assert( u.bf.pKey->flags & MEM_Int );
        63911  +    assert( memIsValid(u.bf.pKey) );
 62651  63912       REGISTER_TRACE(pOp->p3, u.bf.pKey);
 62652  63913       u.bf.iKey = u.bf.pKey->u.i;
 62653  63914     }else{
 62654  63915       assert( pOp->opcode==OP_InsertInt );
 62655  63916       u.bf.iKey = pOp->p3;
 62656  63917     }
 62657  63918   
................................................................................
 62795  64056     VdbeCursor *pC;
 62796  64057     BtCursor *pCrsr;
 62797  64058     u32 n;
 62798  64059     i64 n64;
 62799  64060   #endif /* local variables moved into u.bh */
 62800  64061   
 62801  64062     pOut = &aMem[pOp->p2];
        64063  +  memAboutToChange(p, pOut);
 62802  64064   
 62803  64065     /* Note that RowKey and RowData are really exactly the same instruction */
 62804  64066     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 62805  64067     u.bh.pC = p->apCsr[pOp->p1];
 62806  64068     assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey );
 62807  64069     assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData );
 62808  64070     assert( u.bh.pC!=0 );
................................................................................
 63137  64399     assert( u.bo.pC!=0 );
 63138  64400     u.bo.pCrsr = u.bo.pC->pCursor;
 63139  64401     if( ALWAYS(u.bo.pCrsr!=0) ){
 63140  64402       u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo;
 63141  64403       u.bo.r.nField = (u16)pOp->p3;
 63142  64404       u.bo.r.flags = 0;
 63143  64405       u.bo.r.aMem = &aMem[pOp->p2];
        64406  +#ifdef SQLITE_DEBUG
        64407  +    { int i; for(i=0; i<u.bo.r.nField; i++) assert( memIsValid(&u.bo.r.aMem[i]) ); }
        64408  +#endif
 63144  64409       rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res);
 63145  64410       if( rc==SQLITE_OK && u.bo.res==0 ){
 63146  64411         rc = sqlite3BtreeDelete(u.bo.pCrsr);
 63147  64412       }
 63148  64413       assert( u.bo.pC->deferredMoveto==0 );
 63149  64414       u.bo.pC->cacheStatus = CACHE_STALE;
 63150  64415     }
................................................................................
 63198  64463   ** then jump to P2.  Otherwise fall through to the next instruction.
 63199  64464   **
 63200  64465   ** If P5 is non-zero then the key value is increased by an epsilon 
 63201  64466   ** prior to the comparison.  This make the opcode work like IdxGT except
 63202  64467   ** that if the key from register P3 is a prefix of the key in the cursor,
 63203  64468   ** the result is false whereas it would be true with IdxGT.
 63204  64469   */
 63205         -/* Opcode: IdxLT P1 P2 P3 * P5
        64470  +/* Opcode: IdxLT P1 P2 P3 P4 P5
 63206  64471   **
 63207  64472   ** The P4 register values beginning with P3 form an unpacked index 
 63208  64473   ** key that omits the ROWID.  Compare this key value against the index 
 63209  64474   ** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
 63210  64475   **
 63211  64476   ** If the P1 index entry is less than the key value then jump to P2.
 63212  64477   ** Otherwise fall through to the next instruction.
................................................................................
 63221  64486     int res;
 63222  64487     UnpackedRecord r;
 63223  64488   #endif /* local variables moved into u.bq */
 63224  64489   
 63225  64490     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 63226  64491     u.bq.pC = p->apCsr[pOp->p1];
 63227  64492     assert( u.bq.pC!=0 );
        64493  +  assert( u.bq.pC->isOrdered );
 63228  64494     if( ALWAYS(u.bq.pC->pCursor!=0) ){
 63229  64495       assert( u.bq.pC->deferredMoveto==0 );
 63230  64496       assert( pOp->p5==0 || pOp->p5==1 );
 63231  64497       assert( pOp->p4type==P4_INT32 );
 63232  64498       u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo;
 63233  64499       u.bq.r.nField = (u16)pOp->p4.i;
 63234  64500       if( pOp->p5 ){
 63235  64501         u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
 63236  64502       }else{
 63237  64503         u.bq.r.flags = UNPACKED_IGNORE_ROWID;
 63238  64504       }
 63239  64505       u.bq.r.aMem = &aMem[pOp->p3];
        64506  +#ifdef SQLITE_DEBUG
        64507  +    { int i; for(i=0; i<u.bq.r.nField; i++) assert( memIsValid(&u.bq.r.aMem[i]) ); }
        64508  +#endif
 63240  64509       rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res);
 63241  64510       if( pOp->opcode==OP_IdxLT ){
 63242  64511         u.bq.res = -u.bq.res;
 63243  64512       }else{
 63244  64513         assert( pOp->opcode==OP_IdxGE );
 63245  64514         u.bq.res++;
 63246  64515       }
................................................................................
 63336  64605     assert( (p->btreeMask & (1<<pOp->p2))!=0 );
 63337  64606     rc = sqlite3BtreeClearTable(
 63338  64607         db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0)
 63339  64608     );
 63340  64609     if( pOp->p3 ){
 63341  64610       p->nChange += u.bs.nChange;
 63342  64611       if( pOp->p3>0 ){
        64612  +      assert( memIsValid(&aMem[pOp->p3]) );
        64613  +      memAboutToChange(p, &aMem[pOp->p3]);
 63343  64614         aMem[pOp->p3].u.i += u.bs.nChange;
 63344  64615       }
 63345  64616     }
 63346  64617     break;
 63347  64618   }
 63348  64619   
 63349  64620   /* Opcode: CreateTable P1 P2 * * *
................................................................................
 63379  64650     u.bt.pgno = 0;
 63380  64651     assert( pOp->p1>=0 && pOp->p1<db->nDb );
 63381  64652     assert( (p->btreeMask & (1<<pOp->p1))!=0 );
 63382  64653     u.bt.pDb = &db->aDb[pOp->p1];
 63383  64654     assert( u.bt.pDb->pBt!=0 );
 63384  64655     if( pOp->opcode==OP_CreateTable ){
 63385  64656       /* u.bt.flags = BTREE_INTKEY; */
 63386         -    u.bt.flags = BTREE_LEAFDATA|BTREE_INTKEY;
        64657  +    u.bt.flags = BTREE_INTKEY;
 63387  64658     }else{
 63388         -    u.bt.flags = BTREE_ZERODATA;
        64659  +    u.bt.flags = BTREE_BLOBKEY;
 63389  64660     }
 63390  64661     rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags);
 63391  64662     pOut->u.i = u.bt.pgno;
 63392  64663     break;
 63393  64664   }
 63394  64665   
 63395  64666   /* Opcode: ParseSchema P1 P2 * P4 *
................................................................................
 63710  64981     VdbeFrame *pFrame;      /* New vdbe frame to execute in */
 63711  64982     SubProgram *pProgram;   /* Sub-program to execute */
 63712  64983     void *t;                /* Token identifying trigger */
 63713  64984   #endif /* local variables moved into u.by */
 63714  64985   
 63715  64986     u.by.pProgram = pOp->p4.pProgram;
 63716  64987     u.by.pRt = &aMem[pOp->p3];
        64988  +  assert( memIsValid(u.by.pRt) );
 63717  64989     assert( u.by.pProgram->nOp>0 );
 63718  64990   
 63719  64991     /* If the p5 flag is clear, then recursive invocation of triggers is
 63720  64992     ** disabled for backwards compatibility (p5 is set if this sub-program
 63721  64993     ** is really a trigger, not a foreign key action, and the flag set
 63722  64994     ** and cleared by the "PRAGMA recursive_triggers" command is clear).
 63723  64995     **
................................................................................
 63883  65155   #endif /* local variables moved into u.ca */
 63884  65156     if( p->pFrame ){
 63885  65157       for(u.ca.pFrame=p->pFrame; u.ca.pFrame->pParent; u.ca.pFrame=u.ca.pFrame->pParent);
 63886  65158       u.ca.pIn1 = &u.ca.pFrame->aMem[pOp->p1];
 63887  65159     }else{
 63888  65160       u.ca.pIn1 = &aMem[pOp->p1];
 63889  65161     }
        65162  +  assert( memIsValid(u.ca.pIn1) );
 63890  65163     sqlite3VdbeMemIntegerify(u.ca.pIn1);
 63891  65164     pIn2 = &aMem[pOp->p2];
 63892  65165     sqlite3VdbeMemIntegerify(pIn2);
 63893  65166     if( u.ca.pIn1->u.i<pIn2->u.i){
 63894  65167       u.ca.pIn1->u.i = pIn2->u.i;
 63895  65168     }
 63896  65169     break;
................................................................................
 63969  65242   
 63970  65243     u.cb.n = pOp->p5;
 63971  65244     assert( u.cb.n>=0 );
 63972  65245     u.cb.pRec = &aMem[pOp->p2];
 63973  65246     u.cb.apVal = p->apArg;
 63974  65247     assert( u.cb.apVal || u.cb.n==0 );
 63975  65248     for(u.cb.i=0; u.cb.i<u.cb.n; u.cb.i++, u.cb.pRec++){
        65249  +    assert( memIsValid(u.cb.pRec) );
 63976  65250       u.cb.apVal[u.cb.i] = u.cb.pRec;
        65251  +    memAboutToChange(p, u.cb.pRec);
 63977  65252       sqlite3VdbeMemStoreType(u.cb.pRec);
 63978  65253     }
 63979  65254     u.cb.ctx.pFunc = pOp->p4.pFunc;
 63980  65255     assert( pOp->p3>0 && pOp->p3<=p->nMem );
 63981  65256     u.cb.ctx.pMem = u.cb.pMem = &aMem[pOp->p3];
 63982  65257     u.cb.pMem->n++;
 63983  65258     u.cb.ctx.s.flags = MEM_Null;
................................................................................
 63989  65264     u.cb.ctx.pColl = 0;
 63990  65265     if( u.cb.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
 63991  65266       assert( pOp>p->aOp );
 63992  65267       assert( pOp[-1].p4type==P4_COLLSEQ );
 63993  65268       assert( pOp[-1].opcode==OP_CollSeq );
 63994  65269       u.cb.ctx.pColl = pOp[-1].p4.pColl;
 63995  65270     }
 63996         -  (u.cb.ctx.pFunc->xStep)(&u.cb.ctx, u.cb.n, u.cb.apVal);
        65271  +  (u.cb.ctx.pFunc->xStep)(&u.cb.ctx, u.cb.n, u.cb.apVal); /* IMP: R-24505-23230 */
 63997  65272     if( u.cb.ctx.isError ){
 63998  65273       sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cb.ctx.s));
 63999  65274       rc = u.cb.ctx.isError;
 64000  65275     }
 64001  65276     sqlite3VdbeMemRelease(&u.cb.ctx.s);
 64002  65277     break;
 64003  65278   }
................................................................................
 64376  65651     int i;
 64377  65652     Mem **apArg;
 64378  65653   #endif /* local variables moved into u.ch */
 64379  65654   
 64380  65655     u.ch.pQuery = &aMem[pOp->p3];
 64381  65656     u.ch.pArgc = &u.ch.pQuery[1];
 64382  65657     u.ch.pCur = p->apCsr[pOp->p1];
        65658  +  assert( memIsValid(u.ch.pQuery) );
 64383  65659     REGISTER_TRACE(pOp->p3, u.ch.pQuery);
 64384  65660     assert( u.ch.pCur->pVtabCursor );
 64385  65661     u.ch.pVtabCursor = u.ch.pCur->pVtabCursor;
 64386  65662     u.ch.pVtab = u.ch.pVtabCursor->pVtab;
 64387  65663     u.ch.pModule = u.ch.pVtab->pModule;
 64388  65664   
 64389  65665     /* Grab the index number and argc parameters */
................................................................................
 64433  65709     sqlite3_context sContext;
 64434  65710   #endif /* local variables moved into u.ci */
 64435  65711   
 64436  65712     VdbeCursor *pCur = p->apCsr[pOp->p1];
 64437  65713     assert( pCur->pVtabCursor );
 64438  65714     assert( pOp->p3>0 && pOp->p3<=p->nMem );
 64439  65715     u.ci.pDest = &aMem[pOp->p3];
        65716  +  memAboutToChange(p, u.ci.pDest);
 64440  65717     if( pCur->nullRow ){
 64441  65718       sqlite3VdbeMemSetNull(u.ci.pDest);
 64442  65719       break;
 64443  65720     }
 64444  65721     u.ci.pVtab = pCur->pVtabCursor->pVtab;
 64445  65722     u.ci.pModule = u.ci.pVtab->pModule;
 64446  65723     assert( u.ci.pModule->xColumn );
................................................................................
 64535  65812     sqlite3_vtab *pVtab;
 64536  65813     Mem *pName;
 64537  65814   #endif /* local variables moved into u.ck */
 64538  65815   
 64539  65816     u.ck.pVtab = pOp->p4.pVtab->pVtab;
 64540  65817     u.ck.pName = &aMem[pOp->p1];
 64541  65818     assert( u.ck.pVtab->pModule->xRename );
        65819  +  assert( memIsValid(u.ck.pName) );
 64542  65820     REGISTER_TRACE(pOp->p1, u.ck.pName);
 64543  65821     assert( u.ck.pName->flags & MEM_Str );
 64544  65822     rc = u.ck.pVtab->pModule->xRename(u.ck.pVtab, u.ck.pName->z);
 64545  65823     importVtabErrMsg(p, u.ck.pVtab);
        65824  +  p->expired = 0;
 64546  65825   
 64547  65826     break;
 64548  65827   }
 64549  65828   #endif
 64550  65829   
 64551  65830   #ifndef SQLITE_OMIT_VIRTUALTABLE
 64552  65831   /* Opcode: VUpdate P1 P2 P3 P4 *
................................................................................
 64587  65866     u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule;
 64588  65867     u.cl.nArg = pOp->p2;
 64589  65868     assert( pOp->p4type==P4_VTAB );
 64590  65869     if( ALWAYS(u.cl.pModule->xUpdate) ){
 64591  65870       u.cl.apArg = p->apArg;
 64592  65871       u.cl.pX = &aMem[pOp->p3];
 64593  65872       for(u.cl.i=0; u.cl.i<u.cl.nArg; u.cl.i++){
        65873  +      assert( memIsValid(u.cl.pX) );
        65874  +      memAboutToChange(p, u.cl.pX);
 64594  65875         sqlite3VdbeMemStoreType(u.cl.pX);
 64595  65876         u.cl.apArg[u.cl.i] = u.cl.pX;
 64596  65877         u.cl.pX++;
 64597  65878       }
 64598  65879       rc = u.cl.pModule->xUpdate(u.cl.pVtab, u.cl.nArg, u.cl.apArg, &u.cl.rowid);
 64599  65880       importVtabErrMsg(p, u.cl.pVtab);
 64600  65881       if( rc==SQLITE_OK && pOp->p1 ){
................................................................................
 65641  66922   ** an in-memory journal 
 65642  66923   */
 65643  66924   SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){
 65644  66925     return pJfd->pMethods==&MemJournalMethods;
 65645  66926   }
 65646  66927   
 65647  66928   /* 
 65648         -** Return the number of bytes required to store a MemJournal that uses vfs
 65649         -** pVfs to create the underlying on-disk files.
        66929  +** Return the number of bytes required to store a MemJournal file descriptor.
 65650  66930   */
 65651  66931   SQLITE_PRIVATE int sqlite3MemJournalSize(void){
 65652  66932     return sizeof(MemJournal);
 65653  66933   }
 65654  66934   
 65655  66935   /************** End of memjournal.c ******************************************/
 65656  66936   /************** Begin file walker.c ******************************************/
................................................................................
 67545  68825     if( z[1]==0 ){
 67546  68826       /* Wildcard of the form "?".  Assign the next variable number */
 67547  68827       assert( z[0]=='?' );
 67548  68828       pExpr->iColumn = (ynVar)(++pParse->nVar);
 67549  68829     }else if( z[0]=='?' ){
 67550  68830       /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
 67551  68831       ** use it as the variable number */
 67552         -    int i = atoi((char*)&z[1]);
        68832  +    i64 i;
        68833  +    int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8);
 67553  68834       pExpr->iColumn = (ynVar)i;
 67554  68835       testcase( i==0 );
 67555  68836       testcase( i==1 );
 67556  68837       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
 67557  68838       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
 67558         -    if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
        68839  +    if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
 67559  68840         sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
 67560  68841             db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
 67561  68842       }
 67562  68843       if( i>pParse->nVar ){
 67563         -      pParse->nVar = i;
        68844  +      pParse->nVar = (int)i;
 67564  68845       }
 67565  68846     }else{
 67566  68847       /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
 67567  68848       ** number as the prior appearance of the same name, or if the name
 67568  68849       ** has never appeared before, reuse the same variable number
 67569  68850       */
 67570  68851       int i;
................................................................................
 68525  69806       pX->iTable = iTab;
 68526  69807     }
 68527  69808     return eType;
 68528  69809   }
 68529  69810   #endif
 68530  69811   
 68531  69812   /*
 68532         -** Generate code for scalar subqueries used as an expression
 68533         -** and IN operators.  Examples:
        69813  +** Generate code for scalar subqueries used as a subquery expression, EXISTS,
        69814  +** or IN operators.  Examples:
 68534  69815   **
 68535  69816   **     (SELECT a FROM b)          -- subquery
 68536  69817   **     EXISTS (SELECT a FROM b)   -- EXISTS subquery
 68537  69818   **     x IN (4,5,11)              -- IN operator with list on right-hand side
 68538  69819   **     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
 68539  69820   **
 68540  69821   ** The pExpr parameter describes the expression that contains the IN
................................................................................
 68589  69870       sqlite3VdbeAddOp1(v, OP_If, mem);
 68590  69871       testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
 68591  69872       assert( testAddr>0 || pParse->db->mallocFailed );
 68592  69873     }
 68593  69874   
 68594  69875     switch( pExpr->op ){
 68595  69876       case TK_IN: {
 68596         -      char affinity;
 68597         -      KeyInfo keyInfo;
 68598         -      int addr;        /* Address of OP_OpenEphemeral instruction */
 68599         -      Expr *pLeft = pExpr->pLeft;
        69877  +      char affinity;              /* Affinity of the LHS of the IN */
        69878  +      KeyInfo keyInfo;            /* Keyinfo for the generated table */
        69879  +      int addr;                   /* Address of OP_OpenEphemeral instruction */
        69880  +      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
 68600  69881   
 68601  69882         if( rMayHaveNull ){
 68602  69883           sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
 68603  69884         }
 68604  69885   
 68605  69886         affinity = sqlite3ExprAffinity(pLeft);
 68606  69887   
................................................................................
 68615  69896         ** SELECT... statement are columns, then numeric affinity is used
 68616  69897         ** if either column has NUMERIC or INTEGER affinity. If neither
 68617  69898         ** 'x' nor the SELECT... statement are columns, then numeric affinity
 68618  69899         ** is used.
 68619  69900         */
 68620  69901         pExpr->iTable = pParse->nTab++;
 68621  69902         addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
        69903  +      if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
 68622  69904         memset(&keyInfo, 0, sizeof(keyInfo));
 68623  69905         keyInfo.nField = 1;
 68624  69906   
 68625  69907         if( ExprHasProperty(pExpr, EP_xIsSelect) ){
 68626  69908           /* Case 1:     expr IN (SELECT ...)
 68627  69909           **
 68628  69910           ** Generate code to write the results of the select into the temporary
................................................................................
 68907  70189   ** z[n] character is guaranteed to be something that does not look
 68908  70190   ** like the continuation of the number.
 68909  70191   */
 68910  70192   static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
 68911  70193     if( ALWAYS(z!=0) ){
 68912  70194       double value;
 68913  70195       char *zV;
 68914         -    sqlite3AtoF(z, &value);
        70196  +    sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
 68915  70197       assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
 68916  70198       if( negateFlag ) value = -value;
 68917  70199       zV = dup8bytes(v, (char*)&value);
 68918  70200       sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
 68919  70201     }
 68920  70202   }
 68921  70203   #endif
 68922  70204   
 68923  70205   
 68924  70206   /*
 68925  70207   ** Generate an instruction that will put the integer describe by
 68926  70208   ** text z[0..n-1] into register iMem.
 68927  70209   **
 68928         -** The z[] string will probably not be zero-terminated.  But the 
 68929         -** z[n] character is guaranteed to be something that does not look
 68930         -** like the continuation of the number.
        70210  +** Expr.u.zToken is always UTF8 and zero-terminated.
 68931  70211   */
 68932  70212   static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
 68933  70213     Vdbe *v = pParse->pVdbe;
 68934  70214     if( pExpr->flags & EP_IntValue ){
 68935  70215       int i = pExpr->u.iValue;
 68936  70216       if( negFlag ) i = -i;
 68937  70217       sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
 68938  70218     }else{
        70219  +    int c;
        70220  +    i64 value;
 68939  70221       const char *z = pExpr->u.zToken;
 68940  70222       assert( z!=0 );
 68941         -    if( sqlite3FitsIn64Bits(z, negFlag) ){
 68942         -      i64 value;
        70223  +    c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
        70224  +    if( c==0 || (c==2 && negFlag) ){
 68943  70225         char *zV;
 68944         -      sqlite3Atoi64(z, &value);
 68945         -      if( negFlag ) value = -value;
        70226  +      if( negFlag ){ value = -value; }
 68946  70227         zV = dup8bytes(v, (char*)&value);
 68947  70228         sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
 68948  70229       }else{
 68949  70230   #ifdef SQLITE_OMIT_FLOATING_POINT
 68950  70231         sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
 68951  70232   #else
 68952  70233         codeReal(v, z, negFlag, iMem);
................................................................................
 69223  70504       int r = p->iReg;
 69224  70505       if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
 69225  70506     }
 69226  70507     return 0;
 69227  70508   }
 69228  70509   #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
 69229  70510   
 69230         -/*
 69231         -** If the last instruction coded is an ephemeral copy of any of
 69232         -** the registers in the nReg registers beginning with iReg, then
 69233         -** convert the last instruction from OP_SCopy to OP_Copy.
 69234         -*/
 69235         -SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
 69236         -  VdbeOp *pOp;
 69237         -  Vdbe *v;
 69238         -
 69239         -  assert( pParse->db->mallocFailed==0 );
 69240         -  v = pParse->pVdbe;
 69241         -  assert( v!=0 );
 69242         -  pOp = sqlite3VdbeGetOp(v, -1);
 69243         -  assert( pOp!=0 );
 69244         -  if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
 69245         -    pOp->opcode = OP_Copy;
 69246         -  }
 69247         -}
 69248         -
 69249         -/*
 69250         -** Generate code to store the value of the iAlias-th alias in register
 69251         -** target.  The first time this is called, pExpr is evaluated to compute
 69252         -** the value of the alias.  The value is stored in an auxiliary register
 69253         -** and the number of that register is returned.  On subsequent calls,
 69254         -** the register number is returned without generating any code.
 69255         -**
 69256         -** Note that in order for this to work, code must be generated in the
 69257         -** same order that it is executed.
 69258         -**
 69259         -** Aliases are numbered starting with 1.  So iAlias is in the range
 69260         -** of 1 to pParse->nAlias inclusive.  
 69261         -**
 69262         -** pParse->aAlias[iAlias-1] records the register number where the value
 69263         -** of the iAlias-th alias is stored.  If zero, that means that the
 69264         -** alias has not yet been computed.
 69265         -*/
 69266         -static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){
 69267         -#if 0
 69268         -  sqlite3 *db = pParse->db;
 69269         -  int iReg;
 69270         -  if( pParse->nAliasAlloc<pParse->nAlias ){
 69271         -    pParse->aAlias = sqlite3DbReallocOrFree(db, pParse->aAlias,
 69272         -                                 sizeof(pParse->aAlias[0])*pParse->nAlias );
 69273         -    testcase( db->mallocFailed && pParse->nAliasAlloc>0 );
 69274         -    if( db->mallocFailed ) return 0;
 69275         -    memset(&pParse->aAlias[pParse->nAliasAlloc], 0,
 69276         -           (pParse->nAlias-pParse->nAliasAlloc)*sizeof(pParse->aAlias[0]));
 69277         -    pParse->nAliasAlloc = pParse->nAlias;
 69278         -  }
 69279         -  assert( iAlias>0 && iAlias<=pParse->nAlias );
 69280         -  iReg = pParse->aAlias[iAlias-1];
 69281         -  if( iReg==0 ){
 69282         -    if( pParse->iCacheLevel>0 ){
 69283         -      iReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
 69284         -    }else{
 69285         -      iReg = ++pParse->nMem;
 69286         -      sqlite3ExprCode(pParse, pExpr, iReg);
 69287         -      pParse->aAlias[iAlias-1] = iReg;
 69288         -    }
 69289         -  }
 69290         -  return iReg;
 69291         -#else
 69292         -  UNUSED_PARAMETER(iAlias);
 69293         -  return sqlite3ExprCodeTarget(pParse, pExpr, target);
 69294         -#endif
 69295         -}
 69296         -
 69297  70511   /*
 69298  70512   ** Generate code into the current Vdbe to evaluate the given
 69299  70513   ** expression.  Attempt to store the results in register "target".
 69300  70514   ** Return the register where results are stored.
 69301  70515   **
 69302  70516   ** With this routine, there is no guarantee that results will
 69303  70517   ** be stored in target.  The result might be stored in some other
................................................................................
 69398  70612         break;
 69399  70613       }
 69400  70614       case TK_REGISTER: {
 69401  70615         inReg = pExpr->iTable;
 69402  70616         break;
 69403  70617       }
 69404  70618       case TK_AS: {
 69405         -      inReg = codeAlias(pParse, pExpr->iTable, pExpr->pLeft, target);
        70619  +      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
 69406  70620         break;
 69407  70621       }
 69408  70622   #ifndef SQLITE_OMIT_CAST
 69409  70623       case TK_CAST: {
 69410  70624         /* Expressions of the form:   CAST(pLeft AS token) */
 69411  70625         int aff, to_op;
 69412  70626         inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
................................................................................
 69830  71044           testcase( pX->op==TK_REGISTER );
 69831  71045           cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
 69832  71046           testcase( regFree1==0 );
 69833  71047           cacheX.op = TK_REGISTER;
 69834  71048           opCompare.op = TK_EQ;
 69835  71049           opCompare.pLeft = &cacheX;
 69836  71050           pTest = &opCompare;
        71051  +        /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
        71052  +        ** The value in regFree1 might get SCopy-ed into the file result.
        71053  +        ** So make sure that the regFree1 register is not reused for other
        71054  +        ** purposes and possibly overwritten.  */
        71055  +        regFree1 = 0;
 69837  71056         }
 69838  71057         for(i=0; i<nExpr; i=i+2){
 69839  71058           sqlite3ExprCachePush(pParse);
 69840  71059           if( pX ){
 69841  71060             assert( pTest!=0 );
 69842  71061             opCompare.pRight = aListelem[i].pExpr;
 69843  71062           }else{
................................................................................
 69923  71142   ** results in register target.  The results are guaranteed to appear
 69924  71143   ** in register target.
 69925  71144   */
 69926  71145   SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
 69927  71146     int inReg;
 69928  71147   
 69929  71148     assert( target>0 && target<=pParse->nMem );
 69930         -  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
 69931         -  assert( pParse->pVdbe || pParse->db->mallocFailed );
 69932         -  if( inReg!=target && pParse->pVdbe ){
 69933         -    sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
        71149  +  if( pExpr && pExpr->op==TK_REGISTER ){
        71150  +    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
        71151  +  }else{
        71152  +    inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
        71153  +    assert( pParse->pVdbe || pParse->db->mallocFailed );
        71154  +    if( inReg!=target && pParse->pVdbe ){
        71155  +      sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
        71156  +    }
 69934  71157     }
 69935  71158     return target;
 69936  71159   }
 69937  71160   
 69938  71161   /*
 69939  71162   ** Generate code that evalutes the given expression and puts the result
 69940  71163   ** in register target.
................................................................................
 70099  71322     int target,        /* Where to write results */
 70100  71323     int doHardCopy     /* Make a hard copy of every element */
 70101  71324   ){
 70102  71325     struct ExprList_item *pItem;
 70103  71326     int i, n;
 70104  71327     assert( pList!=0 );
 70105  71328     assert( target>0 );
        71329  +  assert( pParse->pVdbe!=0 );  /* Never gets this far otherwise */
 70106  71330     n = pList->nExpr;
 70107  71331     for(pItem=pList->a, i=0; i<n; i++, pItem++){
 70108         -    if( pItem->iAlias ){
 70109         -      int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr, target+i);
 70110         -      Vdbe *v = sqlite3GetVdbe(pParse);
 70111         -      if( iReg!=target+i ){
 70112         -        sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
 70113         -      }
 70114         -    }else{
 70115         -      sqlite3ExprCode(pParse, pItem->pExpr, target+i);
 70116         -    }
 70117         -    if( doHardCopy && !pParse->db->mallocFailed ){
 70118         -      sqlite3ExprHardCopy(pParse, target, n);
        71332  +    Expr *pExpr = pItem->pExpr;
        71333  +    int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
        71334  +    if( inReg!=target+i ){
        71335  +      sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy,
        71336  +                        inReg, target+i);
 70119  71337       }
 70120  71338     }
 70121  71339     return n;
 70122  71340   }
 70123  71341   
 70124  71342   /*
 70125  71343   ** Generate code for a BETWEEN operator.
................................................................................
 71093  72311       sqlite3 *db = pParse->db;
 71094  72312       for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
 71095  72313         if( pTrig->pSchema==pTempSchema ){
 71096  72314           zWhere = whereOrName(db, zWhere, pTrig->zName);
 71097  72315         }
 71098  72316       }
 71099  72317     }
        72318  +  if( zWhere ){
        72319  +    char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
        72320  +    sqlite3DbFree(pParse->db, zWhere);
        72321  +    zWhere = zNew;
        72322  +  }
 71100  72323     return zWhere;
 71101  72324   }
 71102  72325   
 71103  72326   /*
 71104  72327   ** Generate code to drop and reload the internal representation of table
 71105  72328   ** pTab from the database, including triggers and temporary triggers.
 71106  72329   ** Argument zName is the name of the table in the database schema at
................................................................................
 71700  72923     sqlite3 *db = pParse->db;    /* Database handle */
 71701  72924     Index *pIdx;                 /* An index to being analyzed */
 71702  72925     int iIdxCur;                 /* Cursor open on index being analyzed */
 71703  72926     Vdbe *v;                     /* The virtual machine being built up */
 71704  72927     int i;                       /* Loop counter */
 71705  72928     int topOfLoop;               /* The top of the loop */
 71706  72929     int endOfLoop;               /* The end of the loop */
 71707         -  int addr;                    /* The address of an instruction */
        72930  +  int addr = 0;                /* The address of an instruction */
        72931  +  int jZeroRows = 0;           /* Jump from here if number of rows is zero */
 71708  72932     int iDb;                     /* Index of database containing pTab */
 71709  72933     int regTabname = iMem++;     /* Register containing table name */
 71710  72934     int regIdxname = iMem++;     /* Register containing index name */
 71711  72935     int regSampleno = iMem++;    /* Register containing next sample number */
 71712  72936     int regCol = iMem++;         /* Content of a column analyzed table */
 71713  72937     int regRec = iMem++;         /* Register holding completed record */
 71714  72938     int regTemp = iMem++;        /* Temporary use register */
................................................................................
 71719  72943     int regSamplerecno = iMem++; /* Index of next sample to record */
 71720  72944     int regRecno = iMem++;       /* Current sample index */
 71721  72945     int regLast = iMem++;        /* Index of last sample to record */
 71722  72946     int regFirst = iMem++;       /* Index of first sample to record */
 71723  72947   #endif
 71724  72948   
 71725  72949     v = sqlite3GetVdbe(pParse);
 71726         -  if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){
 71727         -    /* Do no analysis for tables that have no indices */
        72950  +  if( v==0 || NEVER(pTab==0) ){
        72951  +    return;
        72952  +  }
        72953  +  if( pTab->tnum==0 ){
        72954  +    /* Do not gather statistics on views or virtual tables */
        72955  +    return;
        72956  +  }
        72957  +  if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
        72958  +    /* Do not gather statistics on system tables */
 71728  72959       return;
 71729  72960     }
 71730  72961     assert( sqlite3BtreeHoldsAllMutexes(db) );
 71731  72962     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
 71732  72963     assert( iDb>=0 );
 71733  72964   #ifndef SQLITE_OMIT_AUTHORIZATION
 71734  72965     if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
................................................................................
 71737  72968     }
 71738  72969   #endif
 71739  72970   
 71740  72971     /* Establish a read-lock on the table at the shared-cache level. */
 71741  72972     sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
 71742  72973   
 71743  72974     iIdxCur = pParse->nTab++;
        72975  +  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
 71744  72976     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
 71745  72977       int nCol = pIdx->nColumn;
 71746  72978       KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
 71747  72979   
 71748  72980       if( iMem+1+(nCol*2)>pParse->nMem ){
 71749  72981         pParse->nMem = iMem+1+(nCol*2);
 71750  72982       }
................................................................................
 71751  72983   
 71752  72984       /* Open a cursor to the index to be analyzed. */
 71753  72985       assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
 71754  72986       sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
 71755  72987           (char *)pKey, P4_KEYINFO_HANDOFF);
 71756  72988       VdbeComment((v, "%s", pIdx->zName));
 71757  72989   
 71758         -    /* Populate the registers containing the table and index names. */
 71759         -    if( pTab->pIndex==pIdx ){
 71760         -      sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
 71761         -    }
        72990  +    /* Populate the register containing the index name. */
 71762  72991       sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
 71763  72992   
 71764  72993   #ifdef SQLITE_ENABLE_STAT2
 71765  72994   
 71766  72995       /* If this iteration of the loop is generating code to analyze the
 71767  72996       ** first index in the pTab->pIndex list, then register regLast has
 71768  72997       ** not been populated. In this case populate it now.  */
................................................................................
 71889  73118       **
 71890  73119       **        I = (K+D-1)/D
 71891  73120       **
 71892  73121       ** If K==0 then no entry is made into the sqlite_stat1 table.  
 71893  73122       ** If K>0 then it is always the case the D>0 so division by zero
 71894  73123       ** is never possible.
 71895  73124       */
 71896         -    addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
 71897  73125       sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
        73126  +    if( jZeroRows==0 ){
        73127  +      jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
        73128  +    }
 71898  73129       for(i=0; i<nCol; i++){
 71899  73130         sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
 71900  73131         sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
 71901  73132         sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
 71902  73133         sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
 71903  73134         sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
 71904  73135         sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
 71905  73136         sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
 71906  73137       }
 71907  73138       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
 71908  73139       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
 71909  73140       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
 71910  73141       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
        73142  +  }
        73143  +
        73144  +  /* If the table has no indices, create a single sqlite_stat1 entry
        73145  +  ** containing NULL as the index name and the row count as the content.
        73146  +  */
        73147  +  if( pTab->pIndex==0 ){
        73148  +    sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
        73149  +    VdbeComment((v, "%s", pTab->zName));
        73150  +    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno);
        73151  +    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
        73152  +  }else{
        73153  +    assert( jZeroRows>0 );
        73154  +    addr = sqlite3VdbeAddOp0(v, OP_Goto);
        73155  +    sqlite3VdbeJumpHere(v, jZeroRows);
        73156  +  }
        73157  +  sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
        73158  +  sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
        73159  +  sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
        73160  +  sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
        73161  +  sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
        73162  +  if( pParse->nMem<regRec ) pParse->nMem = regRec;
        73163  +  if( jZeroRows ){
 71911  73164       sqlite3VdbeJumpHere(v, addr);
 71912  73165     }
 71913  73166   }
 71914  73167   
 71915  73168   /*
 71916  73169   ** Generate code that will cause the most recent index analysis to
 71917         -** be laoded into internal hash tables where is can be used.
        73170  +** be loaded into internal hash tables where is can be used.
 71918  73171   */
 71919  73172   static void loadAnalysis(Parse *pParse, int iDb){
 71920  73173     Vdbe *v = sqlite3GetVdbe(pParse);
 71921  73174     if( v ){
 71922  73175       sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
 71923  73176     }
 71924  73177   }
................................................................................
 72040  73293     const char *zDatabase;
 72041  73294   };
 72042  73295   
 72043  73296   /*
 72044  73297   ** This callback is invoked once for each index when reading the
 72045  73298   ** sqlite_stat1 table.  
 72046  73299   **
 72047         -**     argv[0] = name of the index
 72048         -**     argv[1] = results of analysis - on integer for each column
        73300  +**     argv[0] = name of the table
        73301  +**     argv[1] = name of the index (might be NULL)
        73302  +**     argv[2] = results of analysis - on integer for each column
        73303  +**
        73304  +** Entries for which argv[1]==NULL simply record the number of rows in
        73305  +** the table.
 72049  73306   */
 72050  73307   static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
 72051  73308     analysisInfo *pInfo = (analysisInfo*)pData;
 72052  73309     Index *pIndex;
 72053         -  int i, c;
        73310  +  Table *pTable;
        73311  +  int i, c, n;
 72054  73312     unsigned int v;
 72055  73313     const char *z;
 72056  73314   
 72057         -  assert( argc==2 );
        73315  +  assert( argc==3 );
 72058  73316     UNUSED_PARAMETER2(NotUsed, argc);
 72059  73317   
 72060         -  if( argv==0 || argv[0]==0 || argv[1]==0 ){
        73318  +  if( argv==0 || argv[0]==0 || argv[2]==0 ){
 72061  73319       return 0;
 72062  73320     }
 72063         -  pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase);
 72064         -  if( pIndex==0 ){
        73321  +  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
        73322  +  if( pTable==0 ){
 72065  73323       return 0;
 72066  73324     }
 72067         -  z = argv[1];
 72068         -  for(i=0; *z && i<=pIndex->nColumn; i++){
        73325  +  if( argv[1] ){
        73326  +    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
        73327  +  }else{
        73328  +    pIndex = 0;
        73329  +  }
        73330  +  n = pIndex ? pIndex->nColumn : 0;
        73331  +  z = argv[2];
        73332  +  for(i=0; *z && i<=n; i++){
 72069  73333       v = 0;
 72070  73334       while( (c=z[0])>='0' && c<='9' ){
 72071  73335         v = v*10 + c - '0';
 72072  73336         z++;
 72073  73337       }
        73338  +    if( i==0 ) pTable->nRowEst = v;
        73339  +    if( pIndex==0 ) break;
 72074  73340       pIndex->aiRowEst[i] = v;
 72075  73341       if( *z==' ' ) z++;
 72076  73342     }
 72077  73343     return 0;
 72078  73344   }
 72079  73345   
 72080  73346   /*
................................................................................
 72090  73356         if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
 72091  73357           sqlite3DbFree(db, p->u.z);
 72092  73358         }
 72093  73359       }
 72094  73360       sqlite3DbFree(db, pIdx->aSample);
 72095  73361     }
 72096  73362   #else
        73363  +  UNUSED_PARAMETER(db);
 72097  73364     UNUSED_PARAMETER(pIdx);
 72098  73365   #endif
 72099  73366   }
 72100  73367   
 72101  73368   /*
 72102  73369   ** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
 72103  73370   ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
................................................................................
 72141  73408     sInfo.zDatabase = db->aDb[iDb].zName;
 72142  73409     if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
 72143  73410       return SQLITE_ERROR;
 72144  73411     }
 72145  73412   
 72146  73413     /* Load new statistics out of the sqlite_stat1 table */
 72147  73414     zSql = sqlite3MPrintf(db, 
 72148         -      "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
        73415  +      "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
 72149  73416     if( zSql==0 ){
 72150  73417       rc = SQLITE_NOMEM;
 72151  73418     }else{
 72152  73419       rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
 72153  73420       sqlite3DbFree(db, zSql);
 72154  73421     }
 72155  73422   
................................................................................
 72358  73625     aNew = &db->aDb[db->nDb];
 72359  73626     memset(aNew, 0, sizeof(*aNew));
 72360  73627   
 72361  73628     /* Open the database file. If the btree is successfully opened, use
 72362  73629     ** it to obtain the database schema. At this point the schema may
 72363  73630     ** or may not be initialised.
 72364  73631     */
 72365         -  rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
 72366         -                           db->openFlags | SQLITE_OPEN_MAIN_DB,
 72367         -                           &aNew->pBt);
        73632  +  rc = sqlite3BtreeOpen(zFile, db, &aNew->pBt, 0,
        73633  +                        db->openFlags | SQLITE_OPEN_MAIN_DB);
 72368  73634     db->nDb++;
 72369  73635     if( rc==SQLITE_CONSTRAINT ){
 72370  73636       rc = SQLITE_ERROR;
 72371  73637       zErrDyn = sqlite3MPrintf(db, "database is already attached");
 72372  73638     }else if( rc==SQLITE_OK ){
 72373  73639       Pager *pPager;
 72374  73640       aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
................................................................................
 72601  73867       0,                /* flags */
 72602  73868       0,                /* pUserData */
 72603  73869       0,                /* pNext */
 72604  73870       detachFunc,       /* xFunc */
 72605  73871       0,                /* xStep */
 72606  73872       0,                /* xFinalize */
 72607  73873       "sqlite_detach",  /* zName */
 72608         -    0                 /* pHash */
        73874  +    0,                /* pHash */
        73875  +    0                 /* pDestructor */
 72609  73876     };
 72610  73877     codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
 72611  73878   }
 72612  73879   
 72613  73880   /*
 72614  73881   ** Called by the parser to compile an ATTACH statement.
 72615  73882   **
................................................................................
 72622  73889       0,                /* flags */
 72623  73890       0,                /* pUserData */
 72624  73891       0,                /* pNext */
 72625  73892       attachFunc,       /* xFunc */
 72626  73893       0,                /* xStep */
 72627  73894       0,                /* xFinalize */
 72628  73895       "sqlite_attach",  /* zName */
 72629         -    0                 /* pHash */
        73896  +    0,                /* pHash */
        73897  +    0                 /* pDestructor */
 72630  73898     };
 72631  73899     codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
 72632  73900   }
 72633  73901   #endif /* SQLITE_OMIT_ATTACH */
 72634  73902   
 72635  73903   /*
 72636  73904   ** Initialize a DbFixer structure.  This routine must be called prior
................................................................................
 73751  75019     ** The call below sets the pName pointer to point at the token (pName1 or
 73752  75020     ** pName2) that stores the unqualified table name. The variable iDb is
 73753  75021     ** set to the index of the database that the table or view is to be
 73754  75022     ** created in.
 73755  75023     */
 73756  75024     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
 73757  75025     if( iDb<0 ) return;
 73758         -  if( !OMIT_TEMPDB && isTemp && iDb>1 ){
 73759         -    /* If creating a temp table, the name may not be qualified */
        75026  +  if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
        75027  +    /* If creating a temp table, the name may not be qualified. Unless 
        75028  +    ** the database name is "temp" anyway.  */
 73760  75029       sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
 73761  75030       return;
 73762  75031     }
 73763  75032     if( !OMIT_TEMPDB && isTemp ) iDb = 1;
 73764  75033   
 73765  75034     pParse->sNameToken = *pName;
 73766  75035     zName = sqlite3NameFromToken(db, pName);
................................................................................
 73800  75069     ** index or table name in the same database.  Issue an error message if
 73801  75070     ** it does. The exception is if the statement being parsed was passed
 73802  75071     ** to an sqlite3_declare_vtab() call. In that case only the column names
 73803  75072     ** and types will be used, so there is no need to test for namespace
 73804  75073     ** collisions.
 73805  75074     */
 73806  75075     if( !IN_DECLARE_VTAB ){
        75076  +    char *zDb = db->aDb[iDb].zName;
 73807  75077       if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
 73808  75078         goto begin_table_error;
 73809  75079       }
 73810         -    pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
        75080  +    pTable = sqlite3FindTable(db, zName, zDb);
 73811  75081       if( pTable ){
 73812  75082         if( !noErr ){
 73813  75083           sqlite3ErrorMsg(pParse, "table %T already exists", pName);
 73814  75084         }
 73815  75085         goto begin_table_error;
 73816  75086       }
 73817         -    if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
        75087  +    if( sqlite3FindIndex(db, zName, zDb)!=0 ){
 73818  75088         sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
 73819  75089         goto begin_table_error;
 73820  75090       }
 73821  75091     }
 73822  75092   
 73823  75093     pTable = sqlite3DbMallocZero(db, sizeof(Table));
 73824  75094     if( pTable==0 ){
................................................................................
 73827  75097       pParse->nErr++;
 73828  75098       goto begin_table_error;
 73829  75099     }
 73830  75100     pTable->zName = zName;
 73831  75101     pTable->iPKey = -1;
 73832  75102     pTable->pSchema = db->aDb[iDb].pSchema;
 73833  75103     pTable->nRef = 1;
        75104  +  pTable->nRowEst = 1000000;
 73834  75105     assert( pParse->pNewTable==0 );
 73835  75106     pParse->pNewTable = pTable;
 73836  75107   
 73837  75108     /* If this is the magic sqlite_sequence table used by autoincrement,
 73838  75109     ** then record a pointer to this table in the main database structure
 73839  75110     ** so that INSERT can find the table easily.
 73840  75111     */
................................................................................
 74673  75944     if( pParse->nVar>0 ){
 74674  75945       sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
 74675  75946       sqlite3SelectDelete(db, pSelect);
 74676  75947       return;
 74677  75948     }
 74678  75949     sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
 74679  75950     p = pParse->pNewTable;
 74680         -  if( p==0 ){
        75951  +  if( p==0 || pParse->nErr ){
 74681  75952       sqlite3SelectDelete(db, pSelect);
 74682  75953       return;
 74683  75954     }
 74684         -  assert( pParse->nErr==0 ); /* If sqlite3StartTable return non-NULL then
 74685         -                             ** there could not have been an error */
 74686  75955     sqlite3TwoPartName(pParse, pName1, pName2, &pName);
 74687  75956     iDb = sqlite3SchemaToIndex(db, p->pSchema);
 74688  75957     if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
 74689  75958       && sqlite3FixSelect(&sFix, pSelect)
 74690  75959     ){
 74691  75960       sqlite3SelectDelete(db, pSelect);
 74692  75961       return;
................................................................................
 75796  77065       /* Fill the index with data and reparse the schema. Code an OP_Expire
 75797  77066       ** to invalidate all pre-compiled statements.
 75798  77067       */
 75799  77068       if( pTblName ){
 75800  77069         sqlite3RefillIndex(pParse, pIndex, iMem);
 75801  77070         sqlite3ChangeCookie(pParse, iDb);
 75802  77071         sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0,
 75803         -         sqlite3MPrintf(db, "name='%q'", pIndex->zName), P4_DYNAMIC);
        77072  +         sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 
        77073  +         P4_DYNAMIC);
 75804  77074         sqlite3VdbeAddOp1(v, OP_Expire, 0);
 75805  77075       }
 75806  77076     }
 75807  77077   
 75808  77078     /* When adding an index to the list of indices for a table, make
 75809  77079     ** sure all indices labeled OE_Replace come after all those labeled
 75810  77080     ** OE_Ignore.  This is necessary for the correct constraint check
................................................................................
 75857  77127   ** Apart from that, we have little to go on besides intuition as to
 75858  77128   ** how aiRowEst[] should be initialized.  The numbers generated here
 75859  77129   ** are based on typical values found in actual indices.
 75860  77130   */
 75861  77131   SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
 75862  77132     unsigned *a = pIdx->aiRowEst;
 75863  77133     int i;
        77134  +  unsigned n;
 75864  77135     assert( a!=0 );
 75865         -  a[0] = 1000000;
 75866         -  for(i=pIdx->nColumn; i>=5; i--){
 75867         -    a[i] = 5;
 75868         -  }
 75869         -  while( i>=1 ){
 75870         -    a[i] = 11 - i;
 75871         -    i--;
        77136  +  a[0] = pIdx->pTable->nRowEst;
        77137  +  if( a[0]<10 ) a[0] = 10;
        77138  +  n = 10;
        77139  +  for(i=1; i<=pIdx->nColumn; i++){
        77140  +    a[i] = n;
        77141  +    if( n>5 ) n--;
 75872  77142     }
 75873  77143     if( pIdx->onError!=OE_None ){
 75874  77144       a[pIdx->nColumn] = 1;
 75875  77145     }
 75876  77146   }
 75877  77147   
 75878  77148   /*
................................................................................
 75924  77194   #endif
 75925  77195   
 75926  77196     /* Generate code to remove the index and from the master table */
 75927  77197     v = sqlite3GetVdbe(pParse);
 75928  77198     if( v ){
 75929  77199       sqlite3BeginWriteOperation(pParse, 1, iDb);
 75930  77200       sqlite3NestedParse(pParse,
 75931         -       "DELETE FROM %Q.%s WHERE name=%Q",
        77201  +       "DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
 75932  77202          db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
 75933  77203          pIndex->zName
 75934  77204       );
 75935  77205       if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){
 75936  77206         sqlite3NestedParse(pParse,
 75937  77207           "DELETE FROM %Q.sqlite_stat1 WHERE idx=%Q",
 75938  77208           db->aDb[iDb].zName, pIndex->zName
................................................................................
 76416  77686       static const int flags = 
 76417  77687             SQLITE_OPEN_READWRITE |
 76418  77688             SQLITE_OPEN_CREATE |
 76419  77689             SQLITE_OPEN_EXCLUSIVE |
 76420  77690             SQLITE_OPEN_DELETEONCLOSE |
 76421  77691             SQLITE_OPEN_TEMP_DB;
 76422  77692   
 76423         -    rc = sqlite3BtreeFactory(db, 0, 0, SQLITE_DEFAULT_CACHE_SIZE, flags, &pBt);
        77693  +    rc = sqlite3BtreeOpen(0, db, &pBt, 0, flags);
 76424  77694       if( rc!=SQLITE_OK ){
 76425  77695         sqlite3ErrorMsg(pParse, "unable to open a temporary database "
 76426  77696           "file for storing temporary tables");
 76427  77697         pParse->rc = rc;
 76428  77698         return 1;
 76429  77699       }
 76430  77700       db->aDb[1].pBt = pBt;
................................................................................
 77073  78343     /* If no match is found, search the built-in functions.
 77074  78344     **
 77075  78345     ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
 77076  78346     ** functions even if a prior app-defined function was found.  And give
 77077  78347     ** priority to built-in functions.
 77078  78348     **
 77079  78349     ** Except, if createFlag is true, that means that we are trying to
 77080         -  ** install a new function.  Whatever FuncDef structure is returned will
        78350  +  ** install a new function.  Whatever FuncDef structure is returned it will
 77081  78351     ** have fields overwritten with new information appropriate for the
 77082  78352     ** new function.  But the FuncDefs for built-in functions are read-only.
 77083  78353     ** So we must not search for built-ins when creating a new function.
 77084  78354     */ 
 77085  78355     if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
 77086  78356       FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
 77087  78357       bestScore = 0;
................................................................................
 78089  79359       r = -(double)((sqlite_int64)((-r)+0.5));
 78090  79360     }else{
 78091  79361       zBuf = sqlite3_mprintf("%.*f",n,r);
 78092  79362       if( zBuf==0 ){
 78093  79363         sqlite3_result_error_nomem(context);
 78094  79364         return;
 78095  79365       }
 78096         -    sqlite3AtoF(zBuf, &r);
        79366  +    sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
 78097  79367       sqlite3_free(zBuf);
 78098  79368     }
 78099  79369     sqlite3_result_double(context, r);
 78100  79370   }
 78101  79371   #endif
 78102  79372   
 78103  79373   /*
................................................................................
 79254  80524   SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
 79255  80525     struct compareInfo *pInfo;
 79256  80526     if( caseSensitive ){
 79257  80527       pInfo = (struct compareInfo*)&likeInfoAlt;
 79258  80528     }else{
 79259  80529       pInfo = (struct compareInfo*)&likeInfoNorm;
 79260  80530     }
 79261         -  sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0);
 79262         -  sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0);
        80531  +  sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0, 0);
        80532  +  sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0, 0);
 79263  80533     sqlite3CreateFunc(db, "glob", 2, SQLITE_ANY, 
 79264         -      (struct compareInfo*)&globInfo, likeFunc, 0,0);
        80534  +      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
 79265  80535     setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
 79266  80536     setLikeOptFlag(db, "like", 
 79267  80537         caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
 79268  80538   }
 79269  80539   
 79270  80540   /*
 79271  80541   ** pExpr points to an expression which implements a function.  If
................................................................................
 79341  80611       FUNCTION(round,              2, 0, 0, roundFunc        ),
 79342  80612   #endif
 79343  80613       FUNCTION(upper,              1, 0, 0, upperFunc        ),
 79344  80614       FUNCTION(lower,              1, 0, 0, lowerFunc        ),
 79345  80615       FUNCTION(coalesce,           1, 0, 0, 0                ),
 79346  80616       FUNCTION(coalesce,           0, 0, 0, 0                ),
 79347  80617   /*  FUNCTION(coalesce,          -1, 0, 0, ifnullFunc       ), */
 79348         -    {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0},
        80618  +    {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0,0},
 79349  80619       FUNCTION(hex,                1, 0, 0, hexFunc          ),
 79350  80620   /*  FUNCTION(ifnull,             2, 0, 0, ifnullFunc       ), */
 79351         -    {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0},
        80621  +    {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0},
 79352  80622       FUNCTION(random,             0, 0, 0, randomFunc       ),
 79353  80623       FUNCTION(randomblob,         1, 0, 0, randomBlob       ),
 79354  80624       FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
 79355  80625       FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),
 79356  80626       FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
 79357  80627   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 79358  80628       FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
................................................................................
 79371  80641       FUNCTION(load_extension,     1, 0, 0, loadExt          ),
 79372  80642       FUNCTION(load_extension,     2, 0, 0, loadExt          ),
 79373  80643     #endif
 79374  80644       AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
 79375  80645       AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
 79376  80646       AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
 79377  80647    /* AGGREGATE(count,             0, 0, 0, countStep,       countFinalize  ), */
 79378         -    {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0},
        80648  +    {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
 79379  80649       AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
 79380  80650       AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
 79381  80651       AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
 79382  80652     
 79383  80653       LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
 79384  80654     #ifdef SQLITE_CASE_SENSITIVE_LIKE
 79385  80655       LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
................................................................................
 79782  81052         int regTemp = sqlite3GetTempRange(pParse, nCol);
 79783  81053         int regRec = sqlite3GetTempReg(pParse);
 79784  81054         KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
 79785  81055     
 79786  81056         sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
 79787  81057         sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
 79788  81058         for(i=0; i<nCol; i++){
 79789         -        sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i);
        81059  +        sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
 79790  81060         }
 79791  81061     
 79792  81062         /* If the parent table is the same as the child table, and we are about
 79793  81063         ** to increment the constraint-counter (i.e. this is an INSERT operation),
 79794  81064         ** then check if the row being inserted matches itself. If so, do not
 79795  81065         ** increment the constraint-counter.  */
 79796  81066         if( pTab==pFKey->pFrom && nIncr==1 ){
................................................................................
 84147  85417     **
 84148  85418     ** Get or set the size limit on rollback journal files.
 84149  85419     */
 84150  85420     if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
 84151  85421       Pager *pPager = sqlite3BtreePager(pDb->pBt);
 84152  85422       i64 iLimit = -2;
 84153  85423       if( zRight ){
 84154         -      sqlite3Atoi64(zRight, &iLimit);
        85424  +      sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
 84155  85425         if( iLimit<-1 ) iLimit = -1;
 84156  85426       }
 84157  85427       iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
 84158  85428       returnSingleInt(pParse, "journal_size_limit", iLimit);
 84159  85429     }else
 84160  85430   
 84161  85431   #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
................................................................................
 86380  87650       addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
 86381  87651       sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
 86382  87652       addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
 86383  87653       sqlite3VdbeJumpHere(v, addr1);
 86384  87654       sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
 86385  87655       sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
 86386  87656       sqlite3VdbeJumpHere(v, addr2);
 86387         -    pSelect->iLimit = 0;
 86388  87657     }
 86389  87658   }
 86390  87659   
 86391  87660   /*
 86392  87661   ** Add code to implement the OFFSET
 86393  87662   */
 86394  87663   static void codeOffset(
................................................................................
 86429  87698     r1 = sqlite3GetTempReg(pParse);
 86430  87699     sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
 86431  87700     sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
 86432  87701     sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
 86433  87702     sqlite3ReleaseTempReg(pParse, r1);
 86434  87703   }
 86435  87704   
        87705  +#ifndef SQLITE_OMIT_SUBQUERY
 86436  87706   /*
 86437  87707   ** Generate an error message when a SELECT is used within a subexpression
 86438  87708   ** (example:  "a IN (SELECT * FROM table)") but it has more than 1 result
 86439         -** column.  We do this in a subroutine because the error occurs in multiple
 86440         -** places.
        87709  +** column.  We do this in a subroutine because the error used to occur
        87710  +** in multiple places.  (The error only occurs in one place now, but we
        87711  +** retain the subroutine to minimize code disruption.)
 86441  87712   */
 86442  87713   static int checkForMultiColumnSelectError(
 86443  87714     Parse *pParse,       /* Parse context. */
 86444  87715     SelectDest *pDest,   /* Destination of SELECT results */
 86445  87716     int nExpr            /* Number of result columns returned by SELECT */
 86446  87717   ){
 86447  87718     int eDest = pDest->eDest;
................................................................................
 86449  87720       sqlite3ErrorMsg(pParse, "only a single result allowed for "
 86450  87721          "a SELECT that is part of an expression");
 86451  87722       return 1;
 86452  87723     }else{
 86453  87724       return 0;
 86454  87725     }
 86455  87726   }
        87727  +#endif
 86456  87728   
 86457  87729   /*
 86458  87730   ** This routine generates the code for the inside of the inner loop
 86459  87731   ** of a SELECT.
 86460  87732   **
 86461  87733   ** If srcTab and nColumn are both zero, then the pEList expressions
 86462  87734   ** are evaluated in order to get the data for this row.  If nColumn>0
................................................................................
 86528  87800       assert( pEList->nExpr==nColumn );
 86529  87801       codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
 86530  87802       if( pOrderBy==0 ){
 86531  87803         codeOffset(v, p, iContinue);
 86532  87804       }
 86533  87805     }
 86534  87806   
 86535         -  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
 86536         -    return;
 86537         -  }
 86538         -
 86539  87807     switch( eDest ){
 86540  87808       /* In this mode, write each query result to the key of the temporary
 86541  87809       ** table iParm.
 86542  87810       */
 86543  87811   #ifndef SQLITE_OMIT_COMPOUND_SELECT
 86544  87812       case SRT_Union: {
 86545  87813         int r1;
................................................................................
 86660  87928       default: {
 86661  87929         assert( eDest==SRT_Discard );
 86662  87930         break;
 86663  87931       }
 86664  87932   #endif
 86665  87933     }
 86666  87934   
 86667         -  /* Jump to the end of the loop if the LIMIT is reached.
        87935  +  /* Jump to the end of the loop if the LIMIT is reached.  Except, if
        87936  +  ** there is a sorter, in which case the sorter has already limited
        87937  +  ** the output for us.
 86668  87938     */
 86669         -  if( p->iLimit ){
 86670         -    assert( pOrderBy==0 );  /* If there is an ORDER BY, the call to
 86671         -                            ** pushOntoSorter() would have cleared p->iLimit */
        87939  +  if( pOrderBy==0 && p->iLimit ){
 86672  87940       sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
 86673  87941     }
 86674  87942   }
 86675  87943   
 86676  87944   /*
 86677  87945   ** Given an expression list, generate a KeyInfo structure that records
 86678  87946   ** the collating sequence for each expression in that expression list.
................................................................................
 86799  88067         }
 86800  88068         break;
 86801  88069       }
 86802  88070     }
 86803  88071     sqlite3ReleaseTempReg(pParse, regRow);
 86804  88072     sqlite3ReleaseTempReg(pParse, regRowid);
 86805  88073   
 86806         -  /* LIMIT has been implemented by the pushOntoSorter() routine.
 86807         -  */
 86808         -  assert( p->iLimit==0 );
 86809         -
 86810  88074     /* The bottom of the loop
 86811  88075     */
 86812  88076     sqlite3VdbeResolveLabel(v, addrContinue);
 86813  88077     sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
 86814  88078     sqlite3VdbeResolveLabel(v, addrBreak);
 86815  88079     if( eDest==SRT_Output || eDest==SRT_Coroutine ){
 86816  88080       sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
................................................................................
 87441  88705     assert( v!=0 );  /* The VDBE already created by calling function */
 87442  88706   
 87443  88707     /* Create the destination temporary table if necessary
 87444  88708     */
 87445  88709     if( dest.eDest==SRT_EphemTab ){
 87446  88710       assert( p->pEList );
 87447  88711       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
        88712  +    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
 87448  88713       dest.eDest = SRT_Table;
 87449  88714     }
 87450  88715   
 87451  88716     /* Make sure all SELECTs in the statement have the same number of elements
 87452  88717     ** in their result sets.
 87453  88718     */
 87454  88719     assert( p->pEList && pPrior->pEList );
................................................................................
 87736  89001   ** The data to be output is contained in pIn->iMem.  There are
 87737  89002   ** pIn->nMem columns to be output.  pDest is where the output should
 87738  89003   ** be sent.
 87739  89004   **
 87740  89005   ** regReturn is the number of the register holding the subroutine
 87741  89006   ** return address.
 87742  89007   **
 87743         -** If regPrev>0 then it is a the first register in a vector that
        89008  +** If regPrev>0 then it is the first register in a vector that
 87744  89009   ** records the previous output.  mem[regPrev] is a flag that is false
 87745  89010   ** if there has been no previous output.  If regPrev>0 then code is
 87746  89011   ** generated to suppress duplicates.  pKeyInfo is used for comparing
 87747  89012   ** keys.
 87748  89013   **
 87749  89014   ** If the LIMIT found in p->iLimit is reached, jump immediately to
 87750  89015   ** iBreak.
................................................................................
 88119  89384         }
 88120  89385       }
 88121  89386     }
 88122  89387    
 88123  89388     /* Separate the left and the right query from one another
 88124  89389     */
 88125  89390     p->pPrior = 0;
 88126         -  pPrior->pRightmost = 0;
 88127  89391     sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
 88128  89392     if( pPrior->pPrior==0 ){
 88129  89393       sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
 88130  89394     }
 88131  89395   
 88132  89396     /* Compute the limit registers */
 88133  89397     computeLimitRegisters(pParse, p, labelEnd);
................................................................................
 88433  89697   ** Flattening is only attempted if all of the following are true:
 88434  89698   **
 88435  89699   **   (1)  The subquery and the outer query do not both use aggregates.
 88436  89700   **
 88437  89701   **   (2)  The subquery is not an aggregate or the outer query is not a join.
 88438  89702   **
 88439  89703   **   (3)  The subquery is not the right operand of a left outer join
 88440         -**        (Originally ticket #306.  Strenghtened by ticket #3300)
        89704  +**        (Originally ticket #306.  Strengthened by ticket #3300)
 88441  89705   **
 88442         -**   (4)  The subquery is not DISTINCT or the outer query is not a join.
        89706  +**   (4)  The subquery is not DISTINCT.
 88443  89707   **
 88444         -**   (5)  The subquery is not DISTINCT or the outer query does not use
 88445         -**        aggregates.
        89708  +**  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
        89709  +**        sub-queries that were excluded from this optimization. Restriction 
        89710  +**        (4) has since been expanded to exclude all DISTINCT subqueries.
 88446  89711   **
 88447  89712   **   (6)  The subquery does not use aggregates or the outer query is not
 88448  89713   **        DISTINCT.
 88449  89714   **
 88450  89715   **   (7)  The subquery has a FROM clause.
 88451  89716   **
 88452  89717   **   (8)  The subquery does not use LIMIT or the outer query is not a join.
................................................................................
 88458  89723   **        use LIMIT.
 88459  89724   **
 88460  89725   **  (11)  The subquery and the outer query do not both have ORDER BY clauses.
 88461  89726   **
 88462  89727   **  (**)  Not implemented.  Subsumed into restriction (3).  Was previously
 88463  89728   **        a separate restriction deriving from ticket #350.
 88464  89729   **
 88465         -**  (13)  The subquery and outer query do not both use LIMIT
        89730  +**  (13)  The subquery and outer query do not both use LIMIT.
 88466  89731   **
 88467         -**  (14)  The subquery does not use OFFSET
        89732  +**  (14)  The subquery does not use OFFSET.
 88468  89733   **
 88469  89734   **  (15)  The outer query is not part of a compound select or the
 88470  89735   **        subquery does not have a LIMIT clause.
 88471  89736   **        (See ticket #2339 and ticket [02a8e81d44]).
 88472  89737   **
 88473  89738   **  (16)  The outer query is not an aggregate or the subquery does
 88474  89739   **        not contain ORDER BY.  (Ticket #2942)  This used to not matter
................................................................................
 88551  89816     ** and (14). */
 88552  89817     if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
 88553  89818     if( pSub->pOffset ) return 0;                          /* Restriction (14) */
 88554  89819     if( p->pRightmost && pSub->pLimit ){
 88555  89820       return 0;                                            /* Restriction (15) */
 88556  89821     }
 88557  89822     if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
 88558         -  if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit) 
 88559         -         && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
 88560         -     return 0;       
        89823  +  if( pSub->selFlags & SF_Distinct ) return 0;           /* Restriction (5)  */
        89824  +  if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
        89825  +     return 0;         /* Restrictions (8)(9) */
 88561  89826     }
 88562  89827     if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
 88563  89828        return 0;         /* Restriction (6)  */
 88564  89829     }
 88565  89830     if( p->pOrderBy && pSub->pOrderBy ){
 88566  89831        return 0;                                           /* Restriction (11) */
 88567  89832     }
................................................................................
 89402  90667       int addrNext = 0;
 89403  90668       int regAgg;
 89404  90669       ExprList *pList = pF->pExpr->x.pList;
 89405  90670       assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
 89406  90671       if( pList ){
 89407  90672         nArg = pList->nExpr;
 89408  90673         regAgg = sqlite3GetTempRange(pParse, nArg);
 89409         -      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0);
        90674  +      sqlite3ExprCodeExprList(pParse, pList, regAgg, 1);
 89410  90675       }else{
 89411  90676         nArg = 0;
 89412  90677         regAgg = 0;
 89413  90678       }
 89414  90679       if( pF->iDistinct>=0 ){
 89415  90680         addrNext = sqlite3VdbeMakeLabel(v);
 89416  90681         assert( nArg==1 );
................................................................................
 89561  90826     isAgg = (p->selFlags & SF_Aggregate)!=0;
 89562  90827     assert( pEList!=0 );
 89563  90828   
 89564  90829     /* Begin generating code.
 89565  90830     */
 89566  90831     v = sqlite3GetVdbe(pParse);
 89567  90832     if( v==0 ) goto select_end;
        90833  +
        90834  +  /* If writing to memory or generating a set
        90835  +  ** only a single column may be output.
        90836  +  */
        90837  +#ifndef SQLITE_OMIT_SUBQUERY
        90838  +  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
        90839  +    goto select_end;
        90840  +  }
        90841  +#endif
 89568  90842   
 89569  90843     /* Generate code for all sub-queries in the FROM clause
 89570  90844     */
 89571  90845   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
 89572  90846     for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
 89573  90847       struct SrcList_item *pItem = &pTabList->a[i];
 89574  90848       SelectDest dest;
................................................................................
 89635  90909           return 1;
 89636  90910         }
 89637  90911       }
 89638  90912       return multiSelect(pParse, p, pDest);
 89639  90913     }
 89640  90914   #endif
 89641  90915   
 89642         -  /* If writing to memory or generating a set
 89643         -  ** only a single column may be output.
 89644         -  */
 89645         -#ifndef SQLITE_OMIT_SUBQUERY
 89646         -  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
 89647         -    goto select_end;
 89648         -  }
 89649         -#endif
 89650         -
 89651  90916     /* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
 89652  90917     ** GROUP BY might use an index, DISTINCT never does.
 89653  90918     */
 89654  90919     assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 );
 89655  90920     if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){
 89656  90921       p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
 89657  90922       pGroupBy = p->pGroupBy;
................................................................................
 89706  90971     if( isDistinct ){
 89707  90972       KeyInfo *pKeyInfo;
 89708  90973       assert( isAgg || pGroupBy );
 89709  90974       distinct = pParse->nTab++;
 89710  90975       pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
 89711  90976       sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
 89712  90977                           (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
        90978  +    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
 89713  90979     }else{
 89714  90980       distinct = -1;
 89715  90981     }
 89716  90982   
 89717  90983     /* Aggregate and non-aggregate queries are handled differently */
 89718  90984     if( !isAgg && pGroupBy==0 ){
 89719  90985       /* This case is for non-aggregate queries
................................................................................
 92181  93447     
 92182  93448     /* Create the ephemeral table into which the update results will
 92183  93449     ** be stored.
 92184  93450     */
 92185  93451     assert( v );
 92186  93452     ephemTab = pParse->nTab++;
 92187  93453     sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
        93454  +  sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
 92188  93455   
 92189  93456     /* fill the ephemeral table 
 92190  93457     */
 92191  93458     sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
 92192  93459     sqlite3Select(pParse, pSelect, &dest);
 92193  93460   
 92194  93461     /* Generate code to scan the ephemeral table and call VUpdate. */
................................................................................
 92319  93586     int isMemDb;            /* True if vacuuming a :memory: database */
 92320  93587     int nRes;               /* Bytes of reserved space at the end of each page */
 92321  93588     int nDb;                /* Number of attached databases */
 92322  93589   
 92323  93590     if( !db->autoCommit ){
 92324  93591       sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
 92325  93592       return SQLITE_ERROR;
        93593  +  }
        93594  +  if( db->activeVdbeCnt>1 ){
        93595  +    sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
        93596  +    return SQLITE_ERROR;
 92326  93597     }
 92327  93598   
 92328  93599     /* Save the current value of the database flags so that it can be 
 92329  93600     ** restored before returning. Then set the writable-schema flag, and
 92330  93601     ** disable CHECK and foreign key constraints.  */
 92331  93602     saved_flags = db->flags;
 92332  93603     saved_nChange = db->nChange;
................................................................................
 92921  94192         pParse->regRowid
 92922  94193       );
 92923  94194       sqlite3DbFree(db, zStmt);
 92924  94195       v = sqlite3GetVdbe(pParse);
 92925  94196       sqlite3ChangeCookie(pParse, iDb);
 92926  94197   
 92927  94198       sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
 92928         -    zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
        94199  +    zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
 92929  94200       sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC);
 92930  94201       sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, 
 92931  94202                            pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
 92932  94203     }
 92933  94204   
 92934  94205     /* If we are rereading the sqlite_master table create the in-memory
 92935  94206     ** record of the table. The xConnect() method is not called until
................................................................................
 93223  94494           pTab->nCol = pParse->pNewTable->nCol;
 93224  94495           pParse->pNewTable->nCol = 0;
 93225  94496           pParse->pNewTable->aCol = 0;
 93226  94497         }
 93227  94498         db->pVTab = 0;
 93228  94499       }else{
 93229  94500         sqlite3Error(db, SQLITE_ERROR, zErr);
 93230         -      sqlite3_free(zErr);
        94501  +      sqlite3DbFree(db, zErr);
 93231  94502         rc = SQLITE_ERROR;
 93232  94503       }
 93233  94504       pParse->declareVtab = 0;
 93234  94505     
 93235  94506       if( pParse->pVdbe ){
 93236  94507         sqlite3VdbeFinalize(pParse->pVdbe);
 93237  94508       }
................................................................................
 94161  95432     pRight = pList->a[0].pExpr;
 94162  95433     op = pRight->op;
 94163  95434     if( op==TK_REGISTER ){
 94164  95435       op = pRight->op2;
 94165  95436     }
 94166  95437     if( op==TK_VARIABLE ){
 94167  95438       Vdbe *pReprepare = pParse->pReprepare;
 94168         -    pVal = sqlite3VdbeGetValue(pReprepare, pRight->iColumn, SQLITE_AFF_NONE);
        95439  +    int iCol = pRight->iColumn;
        95440  +    pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
 94169  95441       if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
 94170  95442         z = (char *)sqlite3_value_text(pVal);
 94171  95443       }
 94172         -    sqlite3VdbeSetVarmask(pParse->pVdbe, pRight->iColumn);
        95444  +    sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */
 94173  95445       assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
 94174  95446     }else if( op==TK_STRING ){
 94175  95447       z = pRight->u.zToken;
 94176  95448     }
 94177  95449     if( z ){
 94178  95450       cnt = 0;
 94179  95451       while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
................................................................................
 94183  95455         Expr *pPrefix;
 94184  95456         *pisComplete = c==wc[0] && z[cnt+1]==0;
 94185  95457         pPrefix = sqlite3Expr(db, TK_STRING, z);
 94186  95458         if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
 94187  95459         *ppPrefix = pPrefix;
 94188  95460         if( op==TK_VARIABLE ){
 94189  95461           Vdbe *v = pParse->pVdbe;
 94190         -        sqlite3VdbeSetVarmask(v, pRight->iColumn);
        95462  +        sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */
 94191  95463           if( *pisComplete && pRight->u.zToken[1] ){
 94192  95464             /* If the rhs of the LIKE expression is a variable, and the current
 94193  95465             ** value of the variable means there is no need to invoke the LIKE
 94194  95466             ** function, then no OP_Variable will be added to the program.
 94195  95467             ** This causes problems for the sqlite3_bind_parameter_name()
 94196  95468             ** API. To workaround them, add a dummy OP_Variable here.
 94197  95469             */ 
................................................................................
 95047  96319   #define TRACE_IDX_OUTPUTS(A)
 95048  96320   #endif
 95049  96321   
 95050  96322   /* 
 95051  96323   ** Required because bestIndex() is called by bestOrClauseIndex() 
 95052  96324   */
 95053  96325   static void bestIndex(
 95054         -    Parse*, WhereClause*, struct SrcList_item*, Bitmask, ExprList*, WhereCost*);
        96326  +    Parse*, WhereClause*, struct SrcList_item*,
        96327  +    Bitmask, Bitmask, ExprList*, WhereCost*);
 95055  96328   
 95056  96329   /*
 95057  96330   ** This routine attempts to find an scanning strategy that can be used 
 95058  96331   ** to optimize an 'OR' expression that is part of a WHERE clause. 
 95059  96332   **
 95060  96333   ** The table associated with FROM clause term pSrc may be either a
 95061  96334   ** regular B-Tree table or a virtual table.
 95062  96335   */
 95063  96336   static void bestOrClauseIndex(
 95064  96337     Parse *pParse,              /* The parsing context */
 95065  96338     WhereClause *pWC,           /* The WHERE clause */
 95066  96339     struct SrcList_item *pSrc,  /* The FROM clause term to search */
 95067         -  Bitmask notReady,           /* Mask of cursors that are not available */
        96340  +  Bitmask notReady,           /* Mask of cursors not available for indexing */
        96341  +  Bitmask notValid,           /* Cursors not available for any purpose */
 95068  96342     ExprList *pOrderBy,         /* The ORDER BY clause */
 95069  96343     WhereCost *pCost            /* Lowest cost query plan */
 95070  96344   ){
 95071  96345   #ifndef SQLITE_OMIT_OR_OPTIMIZATION
 95072  96346     const int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
 95073  96347     const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur);  /* Bitmask for pSrc */
 95074  96348     WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm];        /* End of pWC->a[] */
................................................................................
 95096  96370         for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
 95097  96371           WhereCost sTermCost;
 95098  96372           WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
 95099  96373             (pOrTerm - pOrWC->a), (pTerm - pWC->a)
 95100  96374           ));
 95101  96375           if( pOrTerm->eOperator==WO_AND ){
 95102  96376             WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
 95103         -          bestIndex(pParse, pAndWC, pSrc, notReady, 0, &sTermCost);
        96377  +          bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
 95104  96378           }else if( pOrTerm->leftCursor==iCur ){
 95105  96379             WhereClause tempWC;
 95106  96380             tempWC.pParse = pWC->pParse;
 95107  96381             tempWC.pMaskSet = pWC->pMaskSet;
 95108  96382             tempWC.op = TK_AND;
 95109  96383             tempWC.a = pOrTerm;
 95110  96384             tempWC.nTerm = 1;
 95111         -          bestIndex(pParse, &tempWC, pSrc, notReady, 0, &sTermCost);
        96385  +          bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
 95112  96386           }else{
 95113  96387             continue;
 95114  96388           }
 95115  96389           rTotal += sTermCost.rCost;
 95116  96390           nRow += sTermCost.nRow;
 95117  96391           used |= sTermCost.used;
 95118  96392           if( rTotal>=pCost->rCost ) break;
................................................................................
 95197  96471     if( pSrc->notIndexed ){
 95198  96472       /* The NOT INDEXED clause appears in the SQL. */
 95199  96473       return;
 95200  96474     }
 95201  96475   
 95202  96476     assert( pParse->nQueryLoop >= (double)1 );
 95203  96477     pTable = pSrc->pTab;
 95204         -  nTableRow = pTable->pIndex ? pTable->pIndex->aiRowEst[0] : 1000000;
        96478  +  nTableRow = pTable->nRowEst;
 95205  96479     logN = estLog(nTableRow);
 95206  96480     costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
 95207  96481     if( costTempIdx>=pCost->rCost ){
 95208  96482       /* The cost of creating the transient table would be greater than
 95209  96483       ** doing the full table scan */
 95210  96484       return;
 95211  96485     }
................................................................................
 95551  96825   ** routine takes care of freeing the sqlite3_index_info structure after
 95552  96826   ** everybody has finished with it.
 95553  96827   */
 95554  96828   static void bestVirtualIndex(
 95555  96829     Parse *pParse,                  /* The parsing context */
 95556  96830     WhereClause *pWC,               /* The WHERE clause */
 95557  96831     struct SrcList_item *pSrc,      /* The FROM clause term to search */
 95558         -  Bitmask notReady,               /* Mask of cursors that are not available */
        96832  +  Bitmask notReady,               /* Mask of cursors not available for index */
        96833  +  Bitmask notValid,               /* Cursors not valid for any purpose */
 95559  96834     ExprList *pOrderBy,             /* The order by clause */
 95560  96835     WhereCost *pCost,               /* Lowest cost query plan */
 95561  96836     sqlite3_index_info **ppIdxInfo  /* Index information passed to xBestIndex */
 95562  96837   ){
 95563  96838     Table *pTab = pSrc->pTab;
 95564  96839     sqlite3_index_info *pIdxInfo;
 95565  96840     struct sqlite3_index_constraint *pIdxCons;
................................................................................
 95681  96956     }
 95682  96957     pCost->plan.nEq = 0;
 95683  96958     pIdxInfo->nOrderBy = nOrderBy;
 95684  96959   
 95685  96960     /* Try to find a more efficient access pattern by using multiple indexes
 95686  96961     ** to optimize an OR expression within the WHERE clause. 
 95687  96962     */
 95688         -  bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
        96963  +  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
 95689  96964   }
 95690  96965   #endif /* SQLITE_OMIT_VIRTUALTABLE */
 95691  96966   
 95692  96967   /*
 95693  96968   ** Argument pIdx is a pointer to an index structure that has an array of
 95694  96969   ** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column
 95695  96970   ** stored in Index.aSample. The domain of values stored in said column
................................................................................
 95807  97082     sqlite3_value **pp
 95808  97083   ){
 95809  97084     /* The evalConstExpr() function will have already converted any TK_VARIABLE
 95810  97085     ** expression involved in an comparison into a TK_REGISTER. */
 95811  97086     assert( pExpr->op!=TK_VARIABLE );
 95812  97087     if( pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE ){
 95813  97088       int iVar = pExpr->iColumn;
 95814         -    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
        97089  +    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */
 95815  97090       *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
 95816  97091       return SQLITE_OK;
 95817  97092     }
 95818  97093     return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
 95819  97094   }
 95820  97095   #endif
 95821  97096   
................................................................................
 95962  97237   ** selected plan may still take advantage of the tables built-in rowid
 95963  97238   ** index.
 95964  97239   */
 95965  97240   static void bestBtreeIndex(
 95966  97241     Parse *pParse,              /* The parsing context */
 95967  97242     WhereClause *pWC,           /* The WHERE clause */
 95968  97243     struct SrcList_item *pSrc,  /* The FROM clause term to search */
 95969         -  Bitmask notReady,           /* Mask of cursors that are not available */
        97244  +  Bitmask notReady,           /* Mask of cursors not available for indexing */
        97245  +  Bitmask notValid,           /* Cursors not available for any purpose */
 95970  97246     ExprList *pOrderBy,         /* The ORDER BY clause */
 95971  97247     WhereCost *pCost            /* Lowest cost query plan */
 95972  97248   ){
 95973  97249     int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
 95974  97250     Index *pProbe;              /* An index we are evaluating */
 95975  97251     Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
 95976  97252     int eqTermMask;             /* Current mask of valid equality operators */
................................................................................
 96004  97280       /* There is no INDEXED BY clause.  Create a fake Index object to
 96005  97281       ** represent the primary key */
 96006  97282       Index *pFirst;                /* Any other index on the table */
 96007  97283       memset(&sPk, 0, sizeof(Index));
 96008  97284       sPk.nColumn = 1;
 96009  97285       sPk.aiColumn = &aiColumnPk;
 96010  97286       sPk.aiRowEst = aiRowEstPk;
 96011         -    aiRowEstPk[1] = 1;
 96012  97287       sPk.onError = OE_Replace;
 96013  97288       sPk.pTable = pSrc->pTab;
        97289  +    aiRowEstPk[0] = pSrc->pTab->nRowEst;
        97290  +    aiRowEstPk[1] = 1;
 96014  97291       pFirst = pSrc->pTab->pIndex;
 96015  97292       if( pSrc->notIndexed==0 ){
 96016  97293         sPk.pNext = pFirst;
 96017  97294       }
 96018         -    /* The aiRowEstPk[0] is an estimate of the total number of rows in the
 96019         -    ** table.  Get this information from the ANALYZE information if it is
 96020         -    ** available.  If not available, assume the table 1 million rows in size.
 96021         -    */
 96022         -    if( pFirst ){
 96023         -      assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */
 96024         -      aiRowEstPk[0] = pFirst->aiRowEst[0];
 96025         -    }else{
 96026         -      aiRowEstPk[0] = 1000000;
 96027         -    }
 96028  97295       pProbe = &sPk;
 96029  97296       wsFlagMask = ~(
 96030  97297           WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
 96031  97298       );
 96032  97299       eqTermMask = WO_EQ|WO_IN;
 96033  97300       pIdx = 0;
 96034  97301     }
................................................................................
 96233  97500       /* If there are additional constraints on this table that cannot
 96234  97501       ** be used with the current index, but which might lower the number
 96235  97502       ** of output rows, adjust the nRow value accordingly.  This only 
 96236  97503       ** matters if the current index is the least costly, so do not bother
 96237  97504       ** with this step if we already know this index will not be chosen.
 96238  97505       ** Also, never reduce the output row count below 2 using this step.
 96239  97506       **
 96240         -    ** Do not reduce the output row count if pSrc is the only table that
 96241         -    ** is notReady; if notReady is a power of two.  This will be the case
 96242         -    ** when the main sqlite3WhereBegin() loop is scanning for a table with
 96243         -    ** and "optimal" index, and on such a scan the output row count
 96244         -    ** reduction is not valid because it does not update the "pCost->used"
 96245         -    ** bitmap.  The notReady bitmap will also be a power of two when we
 96246         -    ** are scanning for the last table in a 64-way join.  We are willing
 96247         -    ** to bypass this optimization in that corner case.
        97507  +    ** It is critical that the notValid mask be used here instead of
        97508  +    ** the notReady mask.  When computing an "optimal" index, the notReady
        97509  +    ** mask will only have one bit set - the bit for the current table.
        97510  +    ** The notValid mask, on the other hand, always has all bits set for
        97511  +    ** tables that are not in outer loops.  If notReady is used here instead
        97512  +    ** of notValid, then a optimal index that depends on inner joins loops
        97513  +    ** might be selected even when there exists an optimal index that has
        97514  +    ** no such dependency.
 96248  97515       */
 96249         -    if( nRow>2 && cost<=pCost->rCost && (notReady & (notReady-1))!=0 ){
        97516  +    if( nRow>2 && cost<=pCost->rCost ){
 96250  97517         int k;                       /* Loop counter */
 96251  97518         int nSkipEq = nEq;           /* Number of == constraints to skip */
 96252  97519         int nSkipRange = nBound;     /* Number of < constraints to skip */
 96253  97520         Bitmask thisTab;             /* Bitmap for pSrc */
 96254  97521   
 96255  97522         thisTab = getMask(pWC->pMaskSet, iCur);
 96256  97523         for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){
 96257  97524           if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
 96258         -        if( (pTerm->prereqAll & notReady)!=thisTab ) continue;
        97525  +        if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
 96259  97526           if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
 96260  97527             if( nSkipEq ){
 96261  97528               /* Ignore the first nEq equality matches since the index
 96262  97529               ** has already accounted for these */
 96263  97530               nSkipEq--;
 96264  97531             }else{
 96265  97532               /* Assume each additional equality match reduces the result
................................................................................
 96333  97600     );
 96334  97601   
 96335  97602     WHERETRACE(("best index is: %s\n", 
 96336  97603       ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 
 96337  97604            pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
 96338  97605     ));
 96339  97606     
 96340         -  bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
        97607  +  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
 96341  97608     bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost);
 96342  97609     pCost->plan.wsFlags |= eqTermMask;
 96343  97610   }
 96344  97611   
 96345  97612   /*
 96346  97613   ** Find the query plan for accessing table pSrc->pTab. Write the
 96347  97614   ** best query plan and its cost into the WhereCost object supplied 
................................................................................
 96348  97615   ** as the last parameter. This function may calculate the cost of
 96349  97616   ** both real and virtual table scans.
 96350  97617   */
 96351  97618   static void bestIndex(
 96352  97619     Parse *pParse,              /* The parsing context */
 96353  97620     WhereClause *pWC,           /* The WHERE clause */
 96354  97621     struct SrcList_item *pSrc,  /* The FROM clause term to search */
 96355         -  Bitmask notReady,           /* Mask of cursors that are not available */
        97622  +  Bitmask notReady,           /* Mask of cursors not available for indexing */
        97623  +  Bitmask notValid,           /* Cursors not available for any purpose */
 96356  97624     ExprList *pOrderBy,         /* The ORDER BY clause */
 96357  97625     WhereCost *pCost            /* Lowest cost query plan */
 96358  97626   ){
 96359  97627   #ifndef SQLITE_OMIT_VIRTUALTABLE
 96360  97628     if( IsVirtual(pSrc->pTab) ){
 96361  97629       sqlite3_index_info *p = 0;
 96362         -    bestVirtualIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost, &p);
        97630  +    bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p);
 96363  97631       if( p->needToFreeIdxStr ){
 96364  97632         sqlite3_free(p->idxStr);
 96365  97633       }
 96366  97634       sqlite3DbFree(pParse->db, p);
 96367  97635     }else
 96368  97636   #endif
 96369  97637     {
 96370         -    bestBtreeIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
        97638  +    bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
 96371  97639     }
 96372  97640   }
 96373  97641   
 96374  97642   /*
 96375  97643   ** Disable a term in the WHERE clause.  Except, do not disable the term
 96376  97644   ** if it controls a LEFT OUTER JOIN and it did not originate in the ON
 96377  97645   ** or USING clause of that join.
................................................................................
 96857  98125       **         If there are no inequality constraints, then N is at
 96858  98126       **         least one.
 96859  98127       **
 96860  98128       **         This case is also used when there are no WHERE clause
 96861  98129       **         constraints but an index is selected anyway, in order
 96862  98130       **         to force the output order to conform to an ORDER BY.
 96863  98131       */  
 96864         -    int aStartOp[] = {
        98132  +    static const u8 aStartOp[] = {
 96865  98133         0,
 96866  98134         0,
 96867  98135         OP_Rewind,           /* 2: (!start_constraints && startEq &&  !bRev) */
 96868  98136         OP_Last,             /* 3: (!start_constraints && startEq &&   bRev) */
 96869  98137         OP_SeekGt,           /* 4: (start_constraints  && !startEq && !bRev) */
 96870  98138         OP_SeekLt,           /* 5: (start_constraints  && !startEq &&  bRev) */
 96871  98139         OP_SeekGe,           /* 6: (start_constraints  &&  startEq && !bRev) */
 96872  98140         OP_SeekLe            /* 7: (start_constraints  &&  startEq &&  bRev) */
 96873  98141       };
 96874         -    int aEndOp[] = {
        98142  +    static const u8 aEndOp[] = {
 96875  98143         OP_Noop,             /* 0: (!end_constraints) */
 96876  98144         OP_IdxGE,            /* 1: (end_constraints && !bRev) */
 96877  98145         OP_IdxLT             /* 2: (end_constraints && bRev) */
 96878  98146       };
 96879         -    int nEq = pLevel->plan.nEq;
        98147  +    int nEq = pLevel->plan.nEq;  /* Number of == or IN terms */
 96880  98148       int isMinQuery = 0;          /* If this is an optimized SELECT min(x).. */
 96881  98149       int regBase;                 /* Base register holding constraint values */
 96882  98150       int r1;                      /* Temp register */
 96883  98151       WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
 96884  98152       WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
 96885  98153       int startEq;                 /* True if range start uses ==, >= or <= */
 96886  98154       int endEq;                   /* True if range end uses ==, >= or <= */
 96887  98155       int start_constraints;       /* Start of range is constrained */
 96888  98156       int nConstraint;             /* Number of constraint terms */
 96889         -    Index *pIdx;         /* The index we will be using */
 96890         -    int iIdxCur;         /* The VDBE cursor for the index */
 96891         -    int nExtraReg = 0;   /* Number of extra registers needed */
 96892         -    int op;              /* Instruction opcode */
        98157  +    Index *pIdx;                 /* The index we will be using */
        98158  +    int iIdxCur;                 /* The VDBE cursor for the index */
        98159  +    int nExtraReg = 0;           /* Number of extra registers needed */
        98160  +    int op;                      /* Instruction opcode */
 96893  98161       char *zStartAff;             /* Affinity for start of range constraint */
 96894  98162       char *zEndAff;               /* Affinity for end of range constraint */
 96895  98163   
 96896  98164       pIdx = pLevel->plan.u.pIdx;
 96897  98165       iIdxCur = pLevel->iIdxCur;
 96898  98166       k = pIdx->aiColumn[nEq];     /* Column for inequality constraints */
 96899  98167   
................................................................................
 97578  98846       ** were used as the innermost nested loop.  In other words, a table
 97579  98847       ** is chosen such that the cost of running that table cannot be reduced
 97580  98848       ** by waiting for other tables to run first.  This "optimal" test works
 97581  98849       ** by first assuming that the FROM clause is on the inner loop and finding
 97582  98850       ** its query plan, then checking to see if that query plan uses any
 97583  98851       ** other FROM clause terms that are notReady.  If no notReady terms are
 97584  98852       ** used then the "optimal" query plan works.
        98853  +    **
        98854  +    ** Note that the WhereCost.nRow parameter for an optimal scan might
        98855  +    ** not be as small as it would be if the table really were the innermost
        98856  +    ** join.  The nRow value can be reduced by WHERE clause constraints
        98857  +    ** that do not use indices.  But this nRow reduction only happens if the
        98858  +    ** table really is the innermost join.  
 97585  98859       **
 97586  98860       ** The second loop iteration is only performed if no optimal scan
 97587         -    ** strategies were found by the first loop. This 2nd iteration is used to
 97588         -    ** search for the lowest cost scan overall.
        98861  +    ** strategies were found by the first iteration. This second iteration
        98862  +    ** is used to search for the lowest cost scan overall.
 97589  98863       **
 97590  98864       ** Previous versions of SQLite performed only the second iteration -
 97591  98865       ** the next outermost loop was always that with the lowest overall
 97592  98866       ** cost. However, this meant that SQLite could select the wrong plan
 97593  98867       ** for scripts such as the following:
 97594  98868       **   
 97595  98869       **   CREATE TABLE t1(a, b); 
 97596  98870       **   CREATE TABLE t2(c, d);
 97597  98871       **   SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
 97598  98872       **
 97599  98873       ** The best strategy is to iterate through table t1 first. However it
 97600  98874       ** is not possible to determine this with a simple greedy algorithm.
 97601         -    ** However, since the cost of a linear scan through table t2 is the same 
        98875  +    ** Since the cost of a linear scan through table t2 is the same 
 97602  98876       ** as the cost of a linear scan through table t1, a simple greedy 
 97603  98877       ** algorithm may choose to use t2 for the outer loop, which is a much
 97604  98878       ** costlier approach.
 97605  98879       */
 97606  98880       nUnconstrained = 0;
 97607  98881       notIndexed = 0;
 97608         -    for(isOptimal=(iFrom<nTabList-1); isOptimal>=0; isOptimal--){
        98882  +    for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
 97609  98883         Bitmask mask;             /* Mask of tables not yet ready */
 97610  98884         for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
 97611  98885           int doNotReorder;    /* True if this table should not be reordered */
 97612  98886           WhereCost sCost;     /* Cost information from best[Virtual]Index() */
 97613  98887           ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
 97614  98888     
 97615  98889           doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
................................................................................
 97623  98897           pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
 97624  98898           if( pTabItem->pIndex==0 ) nUnconstrained++;
 97625  98899     
 97626  98900           assert( pTabItem->pTab );
 97627  98901   #ifndef SQLITE_OMIT_VIRTUALTABLE
 97628  98902           if( IsVirtual(pTabItem->pTab) ){
 97629  98903             sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
 97630         -          bestVirtualIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost, pp);
        98904  +          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
        98905  +                           &sCost, pp);
 97631  98906           }else 
 97632  98907   #endif
 97633  98908           {
 97634         -          bestBtreeIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost);
        98909  +          bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
        98910  +                         &sCost);
 97635  98911           }
 97636  98912           assert( isOptimal || (sCost.used&notReady)==0 );
 97637  98913   
 97638  98914           /* If an INDEXED BY clause is present, then the plan must use that
 97639  98915           ** index if it uses any index at all */
 97640  98916           assert( pTabItem->pIndex==0 
 97641  98917                     || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
................................................................................
102663 103939   #endif  /* __cplusplus */
102664 103940   
102665 103941   
102666 103942   /************** End of sqliteicu.h *******************************************/
102667 103943   /************** Continuing where we left off in main.c ***********************/
102668 103944   #endif
102669 103945   
102670         -/*
102671         -** The version of the library
102672         -*/
102673 103946   #ifndef SQLITE_AMALGAMATION
       103947  +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
       103948  +** contains the text of SQLITE_VERSION macro. 
       103949  +*/
102674 103950   SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
102675 103951   #endif
       103952  +
       103953  +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
       103954  +** a pointer to the to the sqlite3_version[] string constant. 
       103955  +*/
102676 103956   SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
       103957  +
       103958  +/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
       103959  +** pointer to a string constant whose value is the same as the
       103960  +** SQLITE_SOURCE_ID C preprocessor macro. 
       103961  +*/
102677 103962   SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
       103963  +
       103964  +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
       103965  +** returns an integer equal to SQLITE_VERSION_NUMBER.
       103966  +*/
102678 103967   SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
       103968  +
       103969  +/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns
       103970  +** zero if and only if SQLite was compiled mutexing code omitted due to
       103971  +** the SQLITE_THREADSAFE compile-time option being set to 0.
       103972  +*/
102679 103973   SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
102680 103974   
102681 103975   #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
102682 103976   /*
102683 103977   ** If the following function pointer is not NULL and if
102684 103978   ** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
102685 103979   ** I/O active are written using this function.  These messages
................................................................................
102792 104086     }
102793 104087   
102794 104088     /* Do the rest of the initialization under the recursive mutex so
102795 104089     ** that we will be able to handle recursive calls into
102796 104090     ** sqlite3_initialize().  The recursive calls normally come through
102797 104091     ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
102798 104092     ** recursive calls might also be possible.
       104093  +  **
       104094  +  ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls
       104095  +  ** to the xInit method, so the xInit method need not be threadsafe.
       104096  +  **
       104097  +  ** The following mutex is what serializes access to the appdef pcache xInit
       104098  +  ** methods.  The sqlite3_pcache_methods.xInit() all is embedded in the
       104099  +  ** call to sqlite3PcacheInitialize().
102799 104100     */
102800 104101     sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
102801 104102     if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
102802 104103       FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
102803 104104       sqlite3GlobalConfig.inProgress = 1;
102804 104105       memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
102805 104106       sqlite3RegisterGlobalFunctions();
................................................................................
103072 104373     */
103073 104374     if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
103074 104375     if( cnt<0 ) cnt = 0;
103075 104376     if( sz==0 || cnt==0 ){
103076 104377       sz = 0;
103077 104378       pStart = 0;
103078 104379     }else if( pBuf==0 ){
103079         -    sz = ROUND8(sz);
       104380  +    sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
103080 104381       sqlite3BeginBenignMalloc();
103081         -    pStart = sqlite3Malloc( sz*cnt );
       104382  +    pStart = sqlite3Malloc( sz*cnt );  /* IMP: R-61949-35727 */
103082 104383       sqlite3EndBenignMalloc();
103083 104384     }else{
103084         -    sz = ROUNDDOWN8(sz);
       104385  +    sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
103085 104386       pStart = pBuf;
103086 104387     }
103087 104388     db->lookaside.pStart = pStart;
103088 104389     db->lookaside.pFree = 0;
103089 104390     db->lookaside.sz = (u16)sz;
103090 104391     if( pStart ){
103091 104392       int i;
................................................................................
103120 104421   */
103121 104422   SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
103122 104423     va_list ap;
103123 104424     int rc;
103124 104425     va_start(ap, op);
103125 104426     switch( op ){
103126 104427       case SQLITE_DBCONFIG_LOOKASIDE: {
103127         -      void *pBuf = va_arg(ap, void*);
103128         -      int sz = va_arg(ap, int);
103129         -      int cnt = va_arg(ap, int);
       104428  +      void *pBuf = va_arg(ap, void*); /* IMP: R-21112-12275 */
       104429  +      int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
       104430  +      int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
103130 104431         rc = setupLookaside(db, pBuf, sz, cnt);
103131 104432         break;
103132 104433       }
103133 104434       default: {
103134         -      rc = SQLITE_ERROR;
       104435  +      rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
103135 104436         break;
103136 104437       }
103137 104438     }
103138 104439     va_end(ap);
103139 104440     return rc;
103140 104441   }
103141 104442   
................................................................................
103231 104532       db->pSavepoint = pTmp->pNext;
103232 104533       sqlite3DbFree(db, pTmp);
103233 104534     }
103234 104535     db->nSavepoint = 0;
103235 104536     db->nStatement = 0;
103236 104537     db->isTransactionSavepoint = 0;
103237 104538   }
       104539  +
       104540  +/*
       104541  +** Invoke the destructor function associated with FuncDef p, if any. Except,
       104542  +** if this is not the last copy of the function, do not invoke it. Multiple
       104543  +** copies of a single function are created when create_function() is called
       104544  +** with SQLITE_ANY as the encoding.
       104545  +*/
       104546  +static void functionDestroy(sqlite3 *db, FuncDef *p){
       104547  +  FuncDestructor *pDestructor = p->pDestructor;
       104548  +  if( pDestructor ){
       104549  +    pDestructor->nRef--;
       104550  +    if( pDestructor->nRef==0 ){
       104551  +      pDestructor->xDestroy(pDestructor->pUserData);
       104552  +      sqlite3DbFree(db, pDestructor);
       104553  +    }
       104554  +  }
       104555  +}
103238 104556   
103239 104557   /*
103240 104558   ** Close an existing SQLite database
103241 104559   */
103242 104560   SQLITE_API int sqlite3_close(sqlite3 *db){
103243         -  HashElem *i;
       104561  +  HashElem *i;                    /* Hash table iterator */
103244 104562     int j;
103245 104563   
103246 104564     if( !db ){
103247 104565       return SQLITE_OK;
103248 104566     }
103249 104567     if( !sqlite3SafetyCheckSickOrOk(db) ){
103250 104568       return SQLITE_MISUSE_BKPT;
................................................................................
103304 104622     assert( db->nDb<=2 );
103305 104623     assert( db->aDb==db->aDbStatic );
103306 104624     for(j=0; j<ArraySize(db->aFunc.a); j++){
103307 104625       FuncDef *pNext, *pHash, *p;
103308 104626       for(p=db->aFunc.a[j]; p; p=pHash){
103309 104627         pHash = p->pHash;
103310 104628         while( p ){
       104629  +        functionDestroy(db, p);
103311 104630           pNext = p->pNext;
103312 104631           sqlite3DbFree(db, p);
103313 104632           p = pNext;
103314 104633         }
103315 104634       }
103316 104635     }
103317 104636     for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
................................................................................
103578 104897     sqlite3 *db,
103579 104898     const char *zFunctionName,
103580 104899     int nArg,
103581 104900     int enc,
103582 104901     void *pUserData,
103583 104902     void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
103584 104903     void (*xStep)(sqlite3_context*,int,sqlite3_value **),
103585         -  void (*xFinal)(sqlite3_context*)
       104904  +  void (*xFinal)(sqlite3_context*),
       104905  +  FuncDestructor *pDestructor
103586 104906   ){
103587 104907     FuncDef *p;
103588 104908     int nName;
103589 104909   
103590 104910     assert( sqlite3_mutex_held(db->mutex) );
103591 104911     if( zFunctionName==0 ||
103592 104912         (xFunc && (xFinal || xStep)) || 
................................................................................
103606 104926     ** to the hash table.
103607 104927     */
103608 104928     if( enc==SQLITE_UTF16 ){
103609 104929       enc = SQLITE_UTF16NATIVE;
103610 104930     }else if( enc==SQLITE_ANY ){
103611 104931       int rc;
103612 104932       rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
103613         -         pUserData, xFunc, xStep, xFinal);
       104933  +         pUserData, xFunc, xStep, xFinal, pDestructor);
103614 104934       if( rc==SQLITE_OK ){
103615 104935         rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
103616         -          pUserData, xFunc, xStep, xFinal);
       104936  +          pUserData, xFunc, xStep, xFinal, pDestructor);
103617 104937       }
103618 104938       if( rc!=SQLITE_OK ){
103619 104939         return rc;
103620 104940       }
103621 104941       enc = SQLITE_UTF16BE;
103622 104942     }
103623 104943   #else
................................................................................
103642 104962     }
103643 104963   
103644 104964     p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
103645 104965     assert(p || db->mallocFailed);
103646 104966     if( !p ){
103647 104967       return SQLITE_NOMEM;
103648 104968     }
       104969  +
       104970  +  /* If an older version of the function with a configured destructor is
       104971  +  ** being replaced invoke the destructor function here. */
       104972  +  functionDestroy(db, p);
       104973  +
       104974  +  if( pDestructor ){
       104975  +    pDestructor->nRef++;
       104976  +  }
       104977  +  p->pDestructor = pDestructor;
103649 104978     p->flags = 0;
103650 104979     p->xFunc = xFunc;
103651 104980     p->xStep = xStep;
103652 104981     p->xFinalize = xFinal;
103653 104982     p->pUserData = pUserData;
103654 104983     p->nArg = (u16)nArg;
103655 104984     return SQLITE_OK;
................................................................................
103656 104985   }
103657 104986   
103658 104987   /*
103659 104988   ** Create new user functions.
103660 104989   */
103661 104990   SQLITE_API int sqlite3_create_function(
103662 104991     sqlite3 *db,
103663         -  const char *zFunctionName,
       104992  +  const char *zFunc,
103664 104993     int nArg,
103665 104994     int enc,
103666 104995     void *p,
103667 104996     void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
103668 104997     void (*xStep)(sqlite3_context*,int,sqlite3_value **),
103669 104998     void (*xFinal)(sqlite3_context*)
103670 104999   ){
103671         -  int rc;
       105000  +  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
       105001  +                                    xFinal, 0);
       105002  +}
       105003  +
       105004  +SQLITE_API int sqlite3_create_function_v2(
       105005  +  sqlite3 *db,
       105006  +  const char *zFunc,
       105007  +  int nArg,
       105008  +  int enc,
       105009  +  void *p,
       105010  +  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
       105011  +  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
       105012  +  void (*xFinal)(sqlite3_context*),
       105013  +  void (*xDestroy)(void *)
       105014  +){
       105015  +  int rc = SQLITE_ERROR;
       105016  +  FuncDestructor *pArg = 0;
103672 105017     sqlite3_mutex_enter(db->mutex);
103673         -  rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal);
       105018  +  if( xDestroy ){
       105019  +    pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
       105020  +    if( !pArg ){
       105021  +      xDestroy(p);
       105022  +      goto out;
       105023  +    }
       105024  +    pArg->xDestroy = xDestroy;
       105025  +    pArg->pUserData = p;
       105026  +  }
       105027  +  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
       105028  +  if( pArg && pArg->nRef==0 ){
       105029  +    assert( rc!=SQLITE_OK );
       105030  +    xDestroy(p);
       105031  +    sqlite3DbFree(db, pArg);
       105032  +  }
       105033  +
       105034  + out:
103674 105035     rc = sqlite3ApiExit(db, rc);
103675 105036     sqlite3_mutex_leave(db->mutex);
103676 105037     return rc;
103677 105038   }
103678 105039   
103679 105040   #ifndef SQLITE_OMIT_UTF16
103680 105041   SQLITE_API int sqlite3_create_function16(
................................................................................
103688 105049     void (*xFinal)(sqlite3_context*)
103689 105050   ){
103690 105051     int rc;
103691 105052     char *zFunc8;
103692 105053     sqlite3_mutex_enter(db->mutex);
103693 105054     assert( !db->mallocFailed );
103694 105055     zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
103695         -  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
       105056  +  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
103696 105057     sqlite3DbFree(db, zFunc8);
103697 105058     rc = sqlite3ApiExit(db, rc);
103698 105059     sqlite3_mutex_leave(db->mutex);
103699 105060     return rc;
103700 105061   }
103701 105062   #endif
103702 105063   
................................................................................
103719 105080     int nArg
103720 105081   ){
103721 105082     int nName = sqlite3Strlen30(zName);
103722 105083     int rc;
103723 105084     sqlite3_mutex_enter(db->mutex);
103724 105085     if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
103725 105086       sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
103726         -                      0, sqlite3InvalidFunction, 0, 0);
       105087  +                      0, sqlite3InvalidFunction, 0, 0, 0);
103727 105088     }
103728 105089     rc = sqlite3ApiExit(db, SQLITE_OK);
103729 105090     sqlite3_mutex_leave(db->mutex);
103730 105091     return rc;
103731 105092   }
103732 105093   
103733 105094   #ifndef SQLITE_OMIT_TRACE
................................................................................
103857 105218   **
103858 105219   ** The callback registered by this function replaces any existing callback
103859 105220   ** registered using sqlite3_wal_hook(). Likewise, registering a callback
103860 105221   ** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
103861 105222   ** configured by this function.
103862 105223   */
103863 105224   SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
103864         -#ifndef SQLITE_OMIT_WAL
       105225  +#ifdef SQLITE_OMIT_WAL
       105226  +  UNUSED_PARAMETER(db);
       105227  +  UNUSED_PARAMETER(nFrame);
       105228  +#else
103865 105229     if( nFrame>0 ){
103866 105230       sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
103867 105231     }else{
103868 105232       sqlite3_wal_hook(db, 0, 0);
103869 105233     }
103870 105234   #endif
103871 105235     return SQLITE_OK;
................................................................................
103987 105351     return 1;
103988 105352   #endif
103989 105353   #if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
103990 105354     return 0;
103991 105355   #endif
103992 105356   }
103993 105357   
103994         -/*
103995         -** This routine is called to create a connection to a database BTree
103996         -** driver.  If zFilename is the name of a file, then that file is
103997         -** opened and used.  If zFilename is the magic name ":memory:" then
103998         -** the database is stored in memory (and is thus forgotten as soon as
103999         -** the connection is closed.)  If zFilename is NULL then the database
104000         -** is a "virtual" database for transient use only and is deleted as
104001         -** soon as the connection is closed.
104002         -**
104003         -** A virtual database can be either a disk file (that is automatically
104004         -** deleted when the file is closed) or it an be held entirely in memory.
104005         -** The sqlite3TempInMemory() function is used to determine which.
104006         -*/
104007         -SQLITE_PRIVATE int sqlite3BtreeFactory(
104008         -  sqlite3 *db,              /* Main database when opening aux otherwise 0 */
104009         -  const char *zFilename,    /* Name of the file containing the BTree database */
104010         -  int omitJournal,          /* if TRUE then do not journal this file */
104011         -  int nCache,               /* How many pages in the page cache */
104012         -  int vfsFlags,             /* Flags passed through to vfsOpen */
104013         -  Btree **ppBtree           /* Pointer to new Btree object written here */
104014         -){
104015         -  int btFlags = 0;
104016         -  int rc;
104017         -  
104018         -  assert( sqlite3_mutex_held(db->mutex) );
104019         -  assert( ppBtree != 0);
104020         -  if( omitJournal ){
104021         -    btFlags |= BTREE_OMIT_JOURNAL;
104022         -  }
104023         -  if( db->flags & SQLITE_NoReadlock ){
104024         -    btFlags |= BTREE_NO_READLOCK;
104025         -  }
104026         -#ifndef SQLITE_OMIT_MEMORYDB
104027         -  if( zFilename==0 && sqlite3TempInMemory(db) ){
104028         -    zFilename = ":memory:";
104029         -  }
104030         -#endif
104031         -
104032         -  if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){
104033         -    vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
104034         -  }
104035         -  rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
104036         -
104037         -  /* If the B-Tree was successfully opened, set the pager-cache size to the
104038         -  ** default value. Except, if the call to BtreeOpen() returned a handle
104039         -  ** open on an existing shared pager-cache, do not change the pager-cache 
104040         -  ** size.
104041         -  */
104042         -  if( rc==SQLITE_OK && 0==sqlite3BtreeSchema(*ppBtree, 0, 0) ){
104043         -    sqlite3BtreeSetCacheSize(*ppBtree, nCache);
104044         -  }
104045         -  return rc;
104046         -}
104047         -
104048 105358   /*
104049 105359   ** Return UTF-8 encoded English language explanation of the most recent
104050 105360   ** error.
104051 105361   */
104052 105362   SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
104053 105363     const char *z;
104054 105364     if( !db ){
................................................................................
104283 105593   **
104284 105594   ** A new lower limit does not shrink existing constructs.
104285 105595   ** It merely prevents new constructs that exceed the limit
104286 105596   ** from forming.
104287 105597   */
104288 105598   SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
104289 105599     int oldLimit;
       105600  +
       105601  +
       105602  +  /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
       105603  +  ** there is a hard upper bound set at compile-time by a C preprocessor
       105604  +  ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
       105605  +  ** "_MAX_".)
       105606  +  */
       105607  +  assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
       105608  +  assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
       105609  +  assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
       105610  +  assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
       105611  +  assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
       105612  +  assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
       105613  +  assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
       105614  +  assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
       105615  +  assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
       105616  +                                               SQLITE_MAX_LIKE_PATTERN_LENGTH );
       105617  +  assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
       105618  +  assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
       105619  +  assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) );
       105620  +
       105621  +
104290 105622     if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
104291 105623       return -1;
104292 105624     }
104293 105625     oldLimit = db->aLimit[limitId];
104294         -  if( newLimit>=0 ){
       105626  +  if( newLimit>=0 ){                   /* IMP: R-52476-28732 */
104295 105627       if( newLimit>aHardLimit[limitId] ){
104296         -      newLimit = aHardLimit[limitId];
       105628  +      newLimit = aHardLimit[limitId];  /* IMP: R-51463-25634 */
104297 105629       }
104298 105630       db->aLimit[limitId] = newLimit;
104299 105631     }
104300         -  return oldLimit;
       105632  +  return oldLimit;                     /* IMP: R-53341-35419 */
104301 105633   }
104302 105634   
104303 105635   /*
104304 105636   ** This routine does the work of opening a database on behalf of
104305 105637   ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
104306 105638   ** is UTF-8 encoded.
104307 105639   */
................................................................................
104316 105648     int isThreadsafe;
104317 105649   
104318 105650     *ppDb = 0;
104319 105651   #ifndef SQLITE_OMIT_AUTOINIT
104320 105652     rc = sqlite3_initialize();
104321 105653     if( rc ) return rc;
104322 105654   #endif
       105655  +
       105656  +  /* Only allow sensible combinations of bits in the flags argument.  
       105657  +  ** Throw an error if any non-sense combination is used.  If we
       105658  +  ** do not block illegal combinations here, it could trigger
       105659  +  ** assert() statements in deeper layers.  Sensible combinations
       105660  +  ** are:
       105661  +  **
       105662  +  **  1:  SQLITE_OPEN_READONLY
       105663  +  **  2:  SQLITE_OPEN_READWRITE
       105664  +  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
       105665  +  */
       105666  +  assert( SQLITE_OPEN_READONLY  == 0x01 );
       105667  +  assert( SQLITE_OPEN_READWRITE == 0x02 );
       105668  +  assert( SQLITE_OPEN_CREATE    == 0x04 );
       105669  +  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
       105670  +  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
       105671  +  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
       105672  +  if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE;
104323 105673   
104324 105674     if( sqlite3GlobalConfig.bCoreMutex==0 ){
104325 105675       isThreadsafe = 0;
104326 105676     }else if( flags & SQLITE_OPEN_NOMUTEX ){
104327 105677       isThreadsafe = 0;
104328 105678     }else if( flags & SQLITE_OPEN_FULLMUTEX ){
104329 105679       isThreadsafe = 1;
................................................................................
104350 105700                  SQLITE_OPEN_TEMP_DB | 
104351 105701                  SQLITE_OPEN_TRANSIENT_DB | 
104352 105702                  SQLITE_OPEN_MAIN_JOURNAL | 
104353 105703                  SQLITE_OPEN_TEMP_JOURNAL | 
104354 105704                  SQLITE_OPEN_SUBJOURNAL | 
104355 105705                  SQLITE_OPEN_MASTER_JOURNAL |
104356 105706                  SQLITE_OPEN_NOMUTEX |
104357         -               SQLITE_OPEN_FULLMUTEX
       105707  +               SQLITE_OPEN_FULLMUTEX |
       105708  +               SQLITE_OPEN_WAL
104358 105709                );
104359 105710   
104360 105711     /* Allocate the sqlite data structure */
104361 105712     db = sqlite3MallocZero( sizeof(sqlite3) );
104362 105713     if( db==0 ) goto opendb_out;
104363 105714     if( isThreadsafe ){
104364 105715       db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
................................................................................
104422 105773   
104423 105774     /* Also add a UTF-8 case-insensitive collation sequence. */
104424 105775     createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0,
104425 105776                     nocaseCollatingFunc, 0);
104426 105777   
104427 105778     /* Open the backend database driver */
104428 105779     db->openFlags = flags;
104429         -  rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, 
104430         -                           flags | SQLITE_OPEN_MAIN_DB,
104431         -                           &db->aDb[0].pBt);
       105780  +  rc = sqlite3BtreeOpen(zFilename, db, &db->aDb[0].pBt, 0,
       105781  +                        flags | SQLITE_OPEN_MAIN_DB);
104432 105782     if( rc!=SQLITE_OK ){
104433 105783       if( rc==SQLITE_IOERR_NOMEM ){
104434 105784         rc = SQLITE_NOMEM;
104435 105785       }
104436 105786       sqlite3Error(db, rc, 0);
104437 105787       goto opendb_out;
104438 105788     }
................................................................................
105130 106480       **
105131 106481       ** Return the size of a pcache header in bytes.
105132 106482       */
105133 106483       case SQLITE_TESTCTRL_PGHDRSZ: {
105134 106484         rc = sizeof(PgHdr);
105135 106485         break;
105136 106486       }
       106487  +
       106488  +    /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
       106489  +    **
       106490  +    ** Pass pFree into sqlite3ScratchFree(). 
       106491  +    ** If sz>0 then allocate a scratch buffer into pNew.  
       106492  +    */
       106493  +    case SQLITE_TESTCTRL_SCRATCHMALLOC: {
       106494  +      void *pFree, **ppNew;
       106495  +      int sz;
       106496  +      sz = va_arg(ap, int);
       106497  +      ppNew = va_arg(ap, void**);
       106498  +      pFree = va_arg(ap, void*);
       106499  +      if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
       106500  +      sqlite3ScratchFree(pFree);
       106501  +      break;
       106502  +    }
105137 106503   
105138 106504     }
105139 106505     va_end(ap);
105140 106506   #endif /* SQLITE_OMIT_BUILTIN_TEST */
105141 106507     return rc;
105142 106508   }
105143 106509   
................................................................................
106319 107685     Fts3Table *, Fts3SegReader **, int, Fts3SegFilter *,
106320 107686     int (*)(Fts3Table *, void *, char *, int, char *, int),  void *
106321 107687   );
106322 107688   SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char const**, int*);
106323 107689   SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, sqlite3_stmt **);
106324 107690   SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeLocal(Fts3Cursor*, u32*);
106325 107691   SQLITE_PRIVATE int sqlite3Fts3MatchinfoDocsizeGlobal(Fts3Cursor*, u32*);
       107692  +SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *);
106326 107693   
106327 107694   /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */
106328 107695   #define FTS3_SEGMENT_REQUIRE_POS   0x00000001
106329 107696   #define FTS3_SEGMENT_IGNORE_EMPTY  0x00000002
106330 107697   #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
106331 107698   #define FTS3_SEGMENT_PREFIX        0x00000008
106332 107699   
................................................................................
108268 109635         if( rc==SQLITE_ERROR ){
108269 109636           p->base.zErrMsg = sqlite3_mprintf("malformed MATCH expression: [%s]",
108270 109637                                             zQuery);
108271 109638         }
108272 109639         return rc;
108273 109640       }
108274 109641   
       109642  +    rc = sqlite3Fts3ReadLock(p);
       109643  +    if( rc!=SQLITE_OK ) return rc;
       109644  +
108275 109645       rc = evalFts3Expr(p, pCsr->pExpr, &pCsr->aDoclist, &pCsr->nDoclist, 0);
108276 109646       pCsr->pNextId = pCsr->aDoclist;
108277 109647       pCsr->iPrevId = 0;
108278 109648     }
108279 109649   
108280 109650     if( rc!=SQLITE_OK ) return rc;
108281 109651     return fts3NextMethod(pCursor);
................................................................................
108646 110016   ** Implementation of FTS3 xRename method. Rename an fts3 table.
108647 110017   */
108648 110018   static int fts3RenameMethod(
108649 110019     sqlite3_vtab *pVtab,            /* Virtual table handle */
108650 110020     const char *zName               /* New name of table */
108651 110021   ){
108652 110022     Fts3Table *p = (Fts3Table *)pVtab;
108653         -  sqlite3 *db;                    /* Database connection */
       110023  +  sqlite3 *db = p->db;            /* Database connection */
108654 110024     int rc;                         /* Return Code */
108655         - 
108656         -  db = p->db;
108657         -  rc = SQLITE_OK;
       110025  +
       110026  +  rc = sqlite3Fts3PendingTermsFlush(p);
       110027  +  if( rc!=SQLITE_OK ){
       110028  +    return rc;
       110029  +  }
       110030  +
108658 110031     fts3DbExec(&rc, db,
108659 110032       "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';",
108660 110033       p->zDb, p->zName, zName
108661 110034     );
108662 110035     if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
108663 110036     if( p->bHasDocsize ){
108664 110037       fts3DbExec(&rc, db,
................................................................................
108718 110091   /*
108719 110092   ** The fts3 built-in tokenizers - "simple" and "porter" - are implemented
108720 110093   ** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following
108721 110094   ** two forward declarations are for functions declared in these files
108722 110095   ** used to retrieve the respective implementations.
108723 110096   **
108724 110097   ** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
108725         -** to by the argument to point a the "simple" tokenizer implementation.
       110098  +** to by the argument to point to the "simple" tokenizer implementation.
108726 110099   ** Function ...PorterTokenizerModule() sets *pModule to point to the
108727 110100   ** porter tokenizer/stemmer implementation.
108728 110101   */
108729 110102   SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
108730 110103   SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
108731 110104   SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
108732 110105   
................................................................................
108920 110293   ** an integer that falls outside of the range of the unsigned char type
108921 110294   ** is undefined (and sometimes, "undefined" means segfault). This wrapper
108922 110295   ** is defined to accept an argument of type char, and always returns 0 for
108923 110296   ** any values that fall outside of the range of the unsigned char type (i.e.
108924 110297   ** negative values).
108925 110298   */
108926 110299   static int fts3isspace(char c){
108927         -  return (c&0x80)==0 ? isspace(c) : 0;
       110300  +  return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
108928 110301   }
108929 110302   
108930 110303   /*
108931 110304   ** Extract the next token from buffer z (length n) using the tokenizer
108932 110305   ** and other information (column names etc.) in pParse. Create an Fts3Expr
108933 110306   ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this
108934 110307   ** single token and set *ppExpr to point to it. If the end of the buffer is
................................................................................
111307 112680     int nTokenAllocated;         /* space allocated to zToken buffer */
111308 112681   } simple_tokenizer_cursor;
111309 112682   
111310 112683   
111311 112684   static int simpleDelim(simple_tokenizer *t, unsigned char c){
111312 112685     return c<0x80 && t->delim[c];
111313 112686   }
       112687  +static int fts3_isalnum(int x){
       112688  +  return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z');
       112689  +}
111314 112690   
111315 112691   /*
111316 112692   ** Create a new tokenizer instance.
111317 112693   */
111318 112694   static int simpleCreate(
111319 112695     int argc, const char * const *argv,
111320 112696     sqlite3_tokenizer **ppTokenizer
................................................................................
111341 112717         }
111342 112718         t->delim[ch] = 1;
111343 112719       }
111344 112720     } else {
111345 112721       /* Mark non-alphanumeric ASCII characters as delimiters */
111346 112722       int i;
111347 112723       for(i=1; i<0x80; i++){
111348         -      t->delim[i] = !isalnum(i) ? -1 : 0;
       112724  +      t->delim[i] = !fts3_isalnum(i) ? -1 : 0;
111349 112725       }
111350 112726     }
111351 112727   
111352 112728     *ppTokenizer = &t->base;
111353 112729     return SQLITE_OK;
111354 112730   }
111355 112731   
................................................................................
111447 112823           c->pToken = pNew;
111448 112824         }
111449 112825         for(i=0; i<n; i++){
111450 112826           /* TODO(shess) This needs expansion to handle UTF-8
111451 112827           ** case-insensitivity.
111452 112828           */
111453 112829           unsigned char ch = p[iStartOffset+i];
111454         -        c->pToken[i] = (char)(ch<0x80 ? tolower(ch) : ch);
       112830  +        c->pToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch);
111455 112831         }
111456 112832         *ppToken = c->pToken;
111457 112833         *pnBytes = n;
111458 112834         *piStartOffset = iStartOffset;
111459 112835         *piEndOffset = c->iOffset;
111460 112836         *piPosition = c->iToken++;
111461 112837   
................................................................................
111806 113182       *pzBlock = (char *)sqlite3_column_blob(pStmt, 0);
111807 113183       if( sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
111808 113184         return SQLITE_CORRUPT;
111809 113185       }
111810 113186     }
111811 113187     return SQLITE_OK;
111812 113188   }
       113189  +
       113190  +/*
       113191  +** This function ensures that the caller has obtained a shared-cache
       113192  +** table-lock on the %_content table. This is required before reading
       113193  +** data from the fts3 table. If this lock is not acquired first, then
       113194  +** the caller may end up holding read-locks on the %_segments and %_segdir
       113195  +** tables, but no read-lock on the %_content table. If this happens 
       113196  +** a second connection will be able to write to the fts3 table, but
       113197  +** attempting to commit those writes might return SQLITE_LOCKED or
       113198  +** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain 
       113199  +** write-locks on the %_segments and %_segdir ** tables). 
       113200  +**
       113201  +** We try to avoid this because if FTS3 returns any error when committing
       113202  +** a transaction, the whole transaction will be rolled back. And this is
       113203  +** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
       113204  +** still happen if the user reads data directly from the %_segments or
       113205  +** %_segdir tables instead of going through FTS3 though.
       113206  +*/
       113207  +SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
       113208  +  int rc;                         /* Return code */
       113209  +  sqlite3_stmt *pStmt;            /* Statement used to obtain lock */
       113210  +
       113211  +  rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
       113212  +  if( rc==SQLITE_OK ){
       113213  +    sqlite3_bind_null(pStmt, 1);
       113214  +    sqlite3_step(pStmt);
       113215  +    rc = sqlite3_reset(pStmt);
       113216  +  }
       113217  +  return rc;
       113218  +}
111813 113219   
111814 113220   /*
111815 113221   ** Set *ppStmt to a statement handle that may be used to iterate through
111816 113222   ** all rows in the %_segdir table, from oldest to newest. If successful,
111817 113223   ** return SQLITE_OK. If an error occurs while preparing the statement, 
111818 113224   ** return an SQLite error code.
111819 113225   **
................................................................................
115297 116703   **    May you find forgiveness for yourself and forgive others.
115298 116704   **    May you share freely, never taking more than you give.
115299 116705   **
115300 116706   *************************************************************************
115301 116707   ** This file contains code for implementations of the r-tree and r*-tree
115302 116708   ** algorithms packaged as an SQLite virtual table module.
115303 116709   */
       116710  +
       116711  +/*
       116712  +** Database Format of R-Tree Tables
       116713  +** --------------------------------
       116714  +**
       116715  +** The data structure for a single virtual r-tree table is stored in three 
       116716  +** native SQLite tables declared as follows. In each case, the '%' character
       116717  +** in the table name is replaced with the user-supplied name of the r-tree
       116718  +** table.
       116719  +**
       116720  +**   CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
       116721  +**   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
       116722  +**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
       116723  +**
       116724  +** The data for each node of the r-tree structure is stored in the %_node
       116725  +** table. For each node that is not the root node of the r-tree, there is
       116726  +** an entry in the %_parent table associating the node with its parent.
       116727  +** And for each row of data in the table, there is an entry in the %_rowid
       116728  +** table that maps from the entries rowid to the id of the node that it
       116729  +** is stored on.
       116730  +**
       116731  +** The root node of an r-tree always exists, even if the r-tree table is
       116732  +** empty. The nodeno of the root node is always 1. All other nodes in the
       116733  +** table must be the same size as the root node. The content of each node
       116734  +** is formatted as follows:
       116735  +**
       116736  +**   1. If the node is the root node (node 1), then the first 2 bytes
       116737  +**      of the node contain the tree depth as a big-endian integer.
       116738  +**      For non-root nodes, the first 2 bytes are left unused.
       116739  +**
       116740  +**   2. The next 2 bytes contain the number of entries currently 
       116741  +**      stored in the node.
       116742  +**
       116743  +**   3. The remainder of the node contains the node entries. Each entry
       116744  +**      consists of a single 8-byte integer followed by an even number
       116745  +**      of 4-byte coordinates. For leaf nodes the integer is the rowid
       116746  +**      of a record. For internal nodes it is the node number of a
       116747  +**      child page.
       116748  +*/
115304 116749   
115305 116750   #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
115306 116751   
115307 116752   /*
115308 116753   ** This file contains an implementation of a couple of different variants
115309 116754   ** of the r-tree algorithm. See the README file for further details. The 
115310 116755   ** same data-structure is used for all, but the algorithms for insert and
................................................................................
115338 116783     #define PickSeeds LinearPickSeeds
115339 116784     #define AssignCells splitNodeGuttman
115340 116785   #endif
115341 116786   #if VARIANT_RSTARTREE_SPLIT
115342 116787     #define AssignCells splitNodeStartree
115343 116788   #endif
115344 116789   
       116790  +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
       116791  +# define NDEBUG 1
       116792  +#endif
115345 116793   
115346 116794   #ifndef SQLITE_CORE
115347 116795     SQLITE_EXTENSION_INIT1
115348 116796   #else
115349 116797   #endif
115350 116798   
115351 116799   
115352 116800   #ifndef SQLITE_AMALGAMATION
       116801  +#include "sqlite3rtree.h"
115353 116802   typedef sqlite3_int64 i64;
115354 116803   typedef unsigned char u8;
115355 116804   typedef unsigned int u32;
115356 116805   #endif
115357 116806   
115358 116807   typedef struct Rtree Rtree;
115359 116808   typedef struct RtreeCursor RtreeCursor;
115360 116809   typedef struct RtreeNode RtreeNode;
115361 116810   typedef struct RtreeCell RtreeCell;
115362 116811   typedef struct RtreeConstraint RtreeConstraint;
       116812  +typedef struct RtreeMatchArg RtreeMatchArg;
       116813  +typedef struct RtreeGeomCallback RtreeGeomCallback;
115363 116814   typedef union RtreeCoord RtreeCoord;
115364 116815   
115365 116816   /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
115366 116817   #define RTREE_MAX_DIMENSIONS 5
115367 116818   
115368 116819   /* Size of hash table Rtree.aHash. This hash table is not expected to
115369 116820   ** ever contain very many entries, so a fixed number of buckets is 
................................................................................
115425 116876   ** If an R*-tree "Reinsert" operation is required, the same number of
115426 116877   ** cells are removed from the overfull node and reinserted into the tree.
115427 116878   */
115428 116879   #define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3)
115429 116880   #define RTREE_REINSERT(p) RTREE_MINCELLS(p)
115430 116881   #define RTREE_MAXCELLS 51
115431 116882   
       116883  +/*
       116884  +** The smallest possible node-size is (512-64)==448 bytes. And the largest
       116885  +** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
       116886  +** Therefore all non-root nodes must contain at least 3 entries. Since 
       116887  +** 2^40 is greater than 2^64, an r-tree structure always has a depth of
       116888  +** 40 or less.
       116889  +*/
       116890  +#define RTREE_MAX_DEPTH 40
       116891  +
115432 116892   /* 
115433 116893   ** An rtree cursor object.
115434 116894   */
115435 116895   struct RtreeCursor {
115436 116896     sqlite3_vtab_cursor base;
115437 116897     RtreeNode *pNode;                 /* Node cursor is currently pointing at */
115438 116898     int iCell;                        /* Index of current cell in pNode */
................................................................................
115457 116917       ((double)coord.i)                             \
115458 116918   )
115459 116919   
115460 116920   /*
115461 116921   ** A search constraint.
115462 116922   */
115463 116923   struct RtreeConstraint {
115464         -  int iCoord;                       /* Index of constrained coordinate */
115465         -  int op;                           /* Constraining operation */
115466         -  double rValue;                    /* Constraint value. */
       116924  +  int iCoord;                     /* Index of constrained coordinate */
       116925  +  int op;                         /* Constraining operation */
       116926  +  double rValue;                  /* Constraint value. */
       116927  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
       116928  +  sqlite3_rtree_geometry *pGeom;  /* Constraint callback argument for a MATCH */
115467 116929   };
115468 116930   
115469 116931   /* Possible values for RtreeConstraint.op */
115470         -#define RTREE_EQ 0x41
115471         -#define RTREE_LE 0x42
115472         -#define RTREE_LT 0x43
115473         -#define RTREE_GE 0x44
115474         -#define RTREE_GT 0x45
       116932  +#define RTREE_EQ    0x41
       116933  +#define RTREE_LE    0x42
       116934  +#define RTREE_LT    0x43
       116935  +#define RTREE_GE    0x44
       116936  +#define RTREE_GT    0x45
       116937  +#define RTREE_MATCH 0x46
115475 116938   
115476 116939   /* 
115477 116940   ** An rtree structure node.
115478         -**
115479         -** Data format (RtreeNode.zData):
115480         -**
115481         -**   1. If the node is the root node (node 1), then the first 2 bytes
115482         -**      of the node contain the tree depth as a big-endian integer.
115483         -**      For non-root nodes, the first 2 bytes are left unused.
115484         -**
115485         -**   2. The next 2 bytes contain the number of entries currently 
115486         -**      stored in the node.
115487         -**
115488         -**   3. The remainder of the node contains the node entries. Each entry
115489         -**      consists of a single 8-byte integer followed by an even number
115490         -**      of 4-byte coordinates. For leaf nodes the integer is the rowid
115491         -**      of a record. For internal nodes it is the node number of a
115492         -**      child page.
115493 116941   */
115494 116942   struct RtreeNode {
115495 116943     RtreeNode *pParent;               /* Parent node */
115496 116944     i64 iNode;
115497 116945     int nRef;
115498 116946     int isDirty;
115499 116947     u8 *zData;
................................................................................
115505 116953   ** Structure to store a deserialized rtree record.
115506 116954   */
115507 116955   struct RtreeCell {
115508 116956     i64 iRowid;
115509 116957     RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
115510 116958   };
115511 116959   
       116960  +
       116961  +/*
       116962  +** Value for the first field of every RtreeMatchArg object. The MATCH
       116963  +** operator tests that the first field of a blob operand matches this
       116964  +** value to avoid operating on invalid blobs (which could cause a segfault).
       116965  +*/
       116966  +#define RTREE_GEOMETRY_MAGIC 0x891245AB
       116967  +
       116968  +/*
       116969  +** An instance of this structure must be supplied as a blob argument to
       116970  +** the right-hand-side of an SQL MATCH operator used to constrain an
       116971  +** r-tree query.
       116972  +*/
       116973  +struct RtreeMatchArg {
       116974  +  u32 magic;                      /* Always RTREE_GEOMETRY_MAGIC */
       116975  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
       116976  +  void *pContext;
       116977  +  int nParam;
       116978  +  double aParam[1];
       116979  +};
       116980  +
       116981  +/*
       116982  +** When a geometry callback is created (see sqlite3_rtree_geometry_callback),
       116983  +** a single instance of the following structure is allocated. It is used
       116984  +** as the context for the user-function created by by s_r_g_c(). The object
       116985  +** is eventually deleted by the destructor mechanism provided by
       116986  +** sqlite3_create_function_v2() (which is called by s_r_g_c() to create
       116987  +** the geometry callback function).
       116988  +*/
       116989  +struct RtreeGeomCallback {
       116990  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
       116991  +  void *pContext;
       116992  +};
       116993  +
115512 116994   #ifndef MAX
115513 116995   # define MAX(x,y) ((x) < (y) ? (y) : (x))
115514 116996   #endif
115515 116997   #ifndef MIN
115516 116998   # define MIN(x,y) ((x) > (y) ? (y) : (x))
115517 116999   #endif
115518 117000   
................................................................................
115587 117069     }
115588 117070   }
115589 117071   
115590 117072   /*
115591 117073   ** Clear the content of node p (set all bytes to 0x00).
115592 117074   */
115593 117075   static void nodeZero(Rtree *pRtree, RtreeNode *p){
115594         -  if( p ){
115595         -    memset(&p->zData[2], 0, pRtree->iNodeSize-2);
115596         -    p->isDirty = 1;
115597         -  }
       117076  +  memset(&p->zData[2], 0, pRtree->iNodeSize-2);
       117077  +  p->isDirty = 1;
115598 117078   }
115599 117079   
115600 117080   /*
115601 117081   ** Given a node number iNode, return the corresponding key to use
115602 117082   ** in the Rtree.aHash table.
115603 117083   */
115604 117084   static int nodeHash(i64 iNode){
................................................................................
115610 117090   
115611 117091   /*
115612 117092   ** Search the node hash table for node iNode. If found, return a pointer
115613 117093   ** to it. Otherwise, return 0.
115614 117094   */
115615 117095   static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
115616 117096     RtreeNode *p;
115617         -  assert( iNode!=0 );
115618 117097     for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext);
115619 117098     return p;
115620 117099   }
115621 117100   
115622 117101   /*
115623 117102   ** Add node pNode to the node hash table.
115624 117103   */
115625 117104   static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){
115626         -  if( pNode ){
115627         -    int iHash;
115628         -    assert( pNode->pNext==0 );
115629         -    iHash = nodeHash(pNode->iNode);
115630         -    pNode->pNext = pRtree->aHash[iHash];
115631         -    pRtree->aHash[iHash] = pNode;
115632         -  }
       117105  +  int iHash;
       117106  +  assert( pNode->pNext==0 );
       117107  +  iHash = nodeHash(pNode->iNode);
       117108  +  pNode->pNext = pRtree->aHash[iHash];
       117109  +  pRtree->aHash[iHash] = pNode;
115633 117110   }
115634 117111   
115635 117112   /*
115636 117113   ** Remove node pNode from the node hash table.
115637 117114   */
115638 117115   static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
115639 117116     RtreeNode **pp;
................................................................................
115647 117124   
115648 117125   /*
115649 117126   ** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
115650 117127   ** indicating that node has not yet been assigned a node number. It is
115651 117128   ** assigned a node number when nodeWrite() is called to write the
115652 117129   ** node contents out to the database.
115653 117130   */
115654         -static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){
       117131  +static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
115655 117132     RtreeNode *pNode;
115656 117133     pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
115657 117134     if( pNode ){
115658         -    memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0));
       117135  +    memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
115659 117136       pNode->zData = (u8 *)&pNode[1];
115660 117137       pNode->nRef = 1;
115661 117138       pNode->pParent = pParent;
115662 117139       pNode->isDirty = 1;
115663 117140       nodeReference(pParent);
115664 117141     }
115665 117142     return pNode;
................................................................................
115672 117149   nodeAcquire(
115673 117150     Rtree *pRtree,             /* R-tree structure */
115674 117151     i64 iNode,                 /* Node number to load */
115675 117152     RtreeNode *pParent,        /* Either the parent node or NULL */
115676 117153     RtreeNode **ppNode         /* OUT: Acquired node */
115677 117154   ){
115678 117155     int rc;
       117156  +  int rc2 = SQLITE_OK;
115679 117157     RtreeNode *pNode;
115680 117158   
115681 117159     /* Check if the requested node is already in the hash table. If so,
115682 117160     ** increase its reference count and return it.
115683 117161     */
115684 117162     if( (pNode = nodeHashLookup(pRtree, iNode)) ){
115685 117163       assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
................................................................................
115688 117166         pNode->pParent = pParent;
115689 117167       }
115690 117168       pNode->nRef++;
115691 117169       *ppNode = pNode;
115692 117170       return SQLITE_OK;
115693 117171     }
115694 117172   
115695         -  pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
115696         -  if( !pNode ){
115697         -    *ppNode = 0;
115698         -    return SQLITE_NOMEM;
115699         -  }
115700         -  pNode->pParent = pParent;
115701         -  pNode->zData = (u8 *)&pNode[1];
115702         -  pNode->nRef = 1;
115703         -  pNode->iNode = iNode;
115704         -  pNode->isDirty = 0;
115705         -  pNode->pNext = 0;
115706         -
115707 117173     sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
115708 117174     rc = sqlite3_step(pRtree->pReadNode);
115709 117175     if( rc==SQLITE_ROW ){
115710 117176       const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
115711         -    assert( sqlite3_column_bytes(pRtree->pReadNode, 0)==pRtree->iNodeSize );
115712         -    memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
115713         -    nodeReference(pParent);
       117177  +    if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){
       117178  +      pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
       117179  +      if( !pNode ){
       117180  +        rc2 = SQLITE_NOMEM;
       117181  +      }else{
       117182  +        pNode->pParent = pParent;
       117183  +        pNode->zData = (u8 *)&pNode[1];
       117184  +        pNode->nRef = 1;
       117185  +        pNode->iNode = iNode;
       117186  +        pNode->isDirty = 0;
       117187  +        pNode->pNext = 0;
       117188  +        memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
       117189  +        nodeReference(pParent);
       117190  +      }
       117191  +    }
       117192  +  }
       117193  +  rc = sqlite3_reset(pRtree->pReadNode);
       117194  +  if( rc==SQLITE_OK ) rc = rc2;
       117195  +
       117196  +  /* If the root node was just loaded, set pRtree->iDepth to the height
       117197  +  ** of the r-tree structure. A height of zero means all data is stored on
       117198  +  ** the root node. A height of one means the children of the root node
       117199  +  ** are the leaves, and so on. If the depth as specified on the root node
       117200  +  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
       117201  +  */
       117202  +  if( pNode && iNode==1 ){
       117203  +    pRtree->iDepth = readInt16(pNode->zData);
       117204  +    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
       117205  +      rc = SQLITE_CORRUPT;
       117206  +    }
       117207  +  }
       117208  +
       117209  +  /* If no error has occurred so far, check if the "number of entries"
       117210  +  ** field on the node is too large. If so, set the return code to 
       117211  +  ** SQLITE_CORRUPT.
       117212  +  */
       117213  +  if( pNode && rc==SQLITE_OK ){
       117214  +    if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
       117215  +      rc = SQLITE_CORRUPT;
       117216  +    }
       117217  +  }
       117218  +
       117219  +  if( rc==SQLITE_OK ){
       117220  +    if( pNode!=0 ){
       117221  +      nodeHashInsert(pRtree, pNode);
       117222  +    }else{
       117223  +      rc = SQLITE_CORRUPT;
       117224  +    }
       117225  +    *ppNode = pNode;
115714 117226     }else{
115715 117227       sqlite3_free(pNode);
115716         -    pNode = 0;
       117228  +    *ppNode = 0;
115717 117229     }
115718 117230   
115719         -  *ppNode = pNode;
115720         -  rc = sqlite3_reset(pRtree->pReadNode);
115721         -
115722         -  if( rc==SQLITE_OK && iNode==1 ){
115723         -    pRtree->iDepth = readInt16(pNode->zData);
115724         -  }
115725         -
115726         -  assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) );
115727         -  nodeHashInsert(pRtree, pNode);
115728         -
115729 117231     return rc;
115730 117232   }
115731 117233   
115732 117234   /*
115733 117235   ** Overwrite cell iCell of node pNode with the contents of pCell.
115734 117236   */
115735 117237   static void nodeOverwriteCell(
................................................................................
115773 117275   ){
115774 117276     int nCell;                    /* Current number of cells in pNode */
115775 117277     int nMaxCell;                 /* Maximum number of cells for pNode */
115776 117278   
115777 117279     nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell;
115778 117280     nCell = NCELL(pNode);
115779 117281   
115780         -  assert(nCell<=nMaxCell);
115781         -
       117282  +  assert( nCell<=nMaxCell );
115782 117283     if( nCell<nMaxCell ){
115783 117284       nodeOverwriteCell(pRtree, pNode, pCell, nCell);
115784 117285       writeInt16(&pNode->zData[2], nCell+1);
115785 117286       pNode->isDirty = 1;
115786 117287     }
115787 117288   
115788 117289     return (nCell==nMaxCell);
................................................................................
115994 117495       rc = SQLITE_OK;
115995 117496     }
115996 117497     *ppCursor = (sqlite3_vtab_cursor *)pCsr;
115997 117498   
115998 117499     return rc;
115999 117500   }
116000 117501   
       117502  +
       117503  +/*
       117504  +** Free the RtreeCursor.aConstraint[] array and its contents.
       117505  +*/
       117506  +static void freeCursorConstraints(RtreeCursor *pCsr){
       117507  +  if( pCsr->aConstraint ){
       117508  +    int i;                        /* Used to iterate through constraint array */
       117509  +    for(i=0; i<pCsr->nConstraint; i++){
       117510  +      sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom;
       117511  +      if( pGeom ){
       117512  +        if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser);
       117513  +        sqlite3_free(pGeom);
       117514  +      }
       117515  +    }
       117516  +    sqlite3_free(pCsr->aConstraint);
       117517  +    pCsr->aConstraint = 0;
       117518  +  }
       117519  +}
       117520  +
116001 117521   /* 
116002 117522   ** Rtree virtual table module xClose method.
116003 117523   */
116004 117524   static int rtreeClose(sqlite3_vtab_cursor *cur){
116005 117525     Rtree *pRtree = (Rtree *)(cur->pVtab);
116006 117526     int rc;
116007 117527     RtreeCursor *pCsr = (RtreeCursor *)cur;
116008         -  sqlite3_free(pCsr->aConstraint);
       117528  +  freeCursorConstraints(pCsr);
116009 117529     rc = nodeRelease(pRtree, pCsr->pNode);
116010 117530     sqlite3_free(pCsr);
116011 117531     return rc;
116012 117532   }
116013 117533   
116014 117534   /*
116015 117535   ** Rtree virtual table module xEof method.
................................................................................
116017 117537   ** Return non-zero if the cursor does not currently point to a valid 
116018 117538   ** record (i.e if the scan has finished), or zero otherwise.
116019 117539   */
116020 117540   static int rtreeEof(sqlite3_vtab_cursor *cur){
116021 117541     RtreeCursor *pCsr = (RtreeCursor *)cur;
116022 117542     return (pCsr->pNode==0);
116023 117543   }
       117544  +
       117545  +/*
       117546  +** The r-tree constraint passed as the second argument to this function is
       117547  +** guaranteed to be a MATCH constraint.
       117548  +*/
       117549  +static int testRtreeGeom(
       117550  +  Rtree *pRtree,                  /* R-Tree object */
       117551  +  RtreeConstraint *pConstraint,   /* MATCH constraint to test */
       117552  +  RtreeCell *pCell,               /* Cell to test */
       117553  +  int *pbRes                      /* OUT: Test result */
       117554  +){
       117555  +  int i;
       117556  +  double aCoord[RTREE_MAX_DIMENSIONS*2];
       117557  +  int nCoord = pRtree->nDim*2;
       117558  +
       117559  +  assert( pConstraint->op==RTREE_MATCH );
       117560  +  assert( pConstraint->pGeom );
       117561  +
       117562  +  for(i=0; i<nCoord; i++){
       117563  +    aCoord[i] = DCOORD(pCell->aCoord[i]);
       117564  +  }
       117565  +  return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes);
       117566  +}
116024 117567   
116025 117568   /* 
116026 117569   ** Cursor pCursor currently points to a cell in a non-leaf page.
116027         -** Return true if the sub-tree headed by the cell is filtered
       117570  +** Set *pbEof to true if the sub-tree headed by the cell is filtered
116028 117571   ** (excluded) by the constraints in the pCursor->aConstraint[] 
116029 117572   ** array, or false otherwise.
       117573  +**
       117574  +** Return SQLITE_OK if successful or an SQLite error code if an error
       117575  +** occurs within a geometry callback.
116030 117576   */
116031         -static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){
       117577  +static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
116032 117578     RtreeCell cell;
116033 117579     int ii;
116034 117580     int bRes = 0;
116035 117581   
116036 117582     nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
116037 117583     for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
116038 117584       RtreeConstraint *p = &pCursor->aConstraint[ii];
116039 117585       double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
116040 117586       double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
116041 117587   
116042 117588       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
116043         -        || p->op==RTREE_GT || p->op==RTREE_EQ
       117589  +        || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
116044 117590       );
116045 117591   
116046 117592       switch( p->op ){
116047         -      case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break;
116048         -      case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break;
116049         -      case RTREE_EQ: 
       117593  +      case RTREE_LE: case RTREE_LT: 
       117594  +        bRes = p->rValue<cell_min; 
       117595  +        break;
       117596  +
       117597  +      case RTREE_GE: case RTREE_GT: 
       117598  +        bRes = p->rValue>cell_max; 
       117599  +        break;
       117600  +
       117601  +      case RTREE_EQ:
116050 117602           bRes = (p->rValue>cell_max || p->rValue<cell_min);
116051 117603           break;
       117604  +
       117605  +      default: {
       117606  +        int rc;
       117607  +        assert( p->op==RTREE_MATCH );
       117608  +        rc = testRtreeGeom(pRtree, p, &cell, &bRes);
       117609  +        if( rc!=SQLITE_OK ){
       117610  +          return rc;
       117611  +        }
       117612  +        bRes = !bRes;
       117613  +        break;
       117614  +      }
116052 117615       }
116053 117616     }
116054 117617   
116055         -  return bRes;
       117618  +  *pbEof = bRes;
       117619  +  return SQLITE_OK;
116056 117620   }
116057 117621   
116058 117622   /* 
116059         -** Return true if the cell that cursor pCursor currently points to
       117623  +** Test if the cell that cursor pCursor currently points to
116060 117624   ** would be filtered (excluded) by the constraints in the 
116061         -** pCursor->aConstraint[] array, or false otherwise.
       117625  +** pCursor->aConstraint[] array. If so, set *pbEof to true before
       117626  +** returning. If the cell is not filtered (excluded) by the constraints,
       117627  +** set pbEof to zero.
       117628  +**
       117629  +** Return SQLITE_OK if successful or an SQLite error code if an error
       117630  +** occurs within a geometry callback.
116062 117631   **
116063 117632   ** This function assumes that the cell is part of a leaf node.
116064 117633   */
116065         -static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){
       117634  +static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
116066 117635     RtreeCell cell;
116067 117636     int ii;
       117637  +  *pbEof = 0;
116068 117638   
116069 117639     nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
116070 117640     for(ii=0; ii<pCursor->nConstraint; ii++){
116071 117641       RtreeConstraint *p = &pCursor->aConstraint[ii];
116072 117642       double coord = DCOORD(cell.aCoord[p->iCoord]);
116073 117643       int res;
116074 117644       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
116075         -        || p->op==RTREE_GT || p->op==RTREE_EQ
       117645  +        || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
116076 117646       );
116077 117647       switch( p->op ){
116078 117648         case RTREE_LE: res = (coord<=p->rValue); break;
116079 117649         case RTREE_LT: res = (coord<p->rValue);  break;
116080 117650         case RTREE_GE: res = (coord>=p->rValue); break;
116081 117651         case RTREE_GT: res = (coord>p->rValue);  break;
116082 117652         case RTREE_EQ: res = (coord==p->rValue); break;
       117653  +      default: {
       117654  +        int rc;
       117655  +        assert( p->op==RTREE_MATCH );
       117656  +        rc = testRtreeGeom(pRtree, p, &cell, &res);
       117657  +        if( rc!=SQLITE_OK ){
       117658  +          return rc;
       117659  +        }
       117660  +        break;
       117661  +      }
116083 117662       }
116084 117663   
116085         -    if( !res ) return 1;
       117664  +    if( !res ){
       117665  +      *pbEof = 1;
       117666  +      return SQLITE_OK;
       117667  +    }
116086 117668     }
116087 117669   
116088         -  return 0;
       117670  +  return SQLITE_OK;
116089 117671   }
116090 117672   
116091 117673   /*
116092 117674   ** Cursor pCursor currently points at a node that heads a sub-tree of
116093 117675   ** height iHeight (if iHeight==0, then the node is a leaf). Descend
116094 117676   ** to point to the left-most cell of the sub-tree that matches the 
116095 117677   ** configured constraints.
................................................................................
116108 117690   
116109 117691     RtreeNode *pSavedNode = pCursor->pNode;
116110 117692     int iSavedCell = pCursor->iCell;
116111 117693   
116112 117694     assert( iHeight>=0 );
116113 117695   
116114 117696     if( iHeight==0 ){
116115         -    isEof = testRtreeEntry(pRtree, pCursor);
       117697  +    rc = testRtreeEntry(pRtree, pCursor, &isEof);
116116 117698     }else{
116117         -    isEof = testRtreeCell(pRtree, pCursor);
       117699  +    rc = testRtreeCell(pRtree, pCursor, &isEof);
116118 117700     }
116119         -  if( isEof || iHeight==0 ){
       117701  +  if( rc!=SQLITE_OK || isEof || iHeight==0 ){
116120 117702       *pEof = isEof;
116121         -    return SQLITE_OK;
       117703  +    return rc;
116122 117704     }
116123 117705   
116124 117706     iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell);
116125 117707     rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild);
116126 117708     if( rc!=SQLITE_OK ){
116127 117709       return rc;
116128 117710     }
................................................................................
116150 117732     return SQLITE_OK;
116151 117733   }
116152 117734   
116153 117735   /*
116154 117736   ** One of the cells in node pNode is guaranteed to have a 64-bit 
116155 117737   ** integer value equal to iRowid. Return the index of this cell.
116156 117738   */
116157         -static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){
       117739  +static int nodeRowidIndex(
       117740  +  Rtree *pRtree, 
       117741  +  RtreeNode *pNode, 
       117742  +  i64 iRowid,
       117743  +  int *piIndex
       117744  +){
116158 117745     int ii;
116159         -  for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){
116160         -    assert( ii<(NCELL(pNode)-1) );
       117746  +  int nCell = NCELL(pNode);
       117747  +  for(ii=0; ii<nCell; ii++){
       117748  +    if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
       117749  +      *piIndex = ii;
       117750  +      return SQLITE_OK;
       117751  +    }
116161 117752     }
116162         -  return ii;
       117753  +  return SQLITE_CORRUPT;
116163 117754   }
116164 117755   
116165 117756   /*
116166 117757   ** Return the index of the cell containing a pointer to node pNode
116167 117758   ** in its parent. If pNode is the root node, return -1.
116168 117759   */
116169         -static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){
       117760  +static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){
116170 117761     RtreeNode *pParent = pNode->pParent;
116171 117762     if( pParent ){
116172         -    return nodeRowidIndex(pRtree, pParent, pNode->iNode);
       117763  +    return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex);
116173 117764     }
116174         -  return -1;
       117765  +  *piIndex = -1;
       117766  +  return SQLITE_OK;
116175 117767   }
116176 117768   
116177 117769   /* 
116178 117770   ** Rtree virtual table module xNext method.
116179 117771   */
116180 117772   static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
116181 117773     Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
116182 117774     RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
116183 117775     int rc = SQLITE_OK;
       117776  +
       117777  +  /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is
       117778  +  ** already at EOF. It is against the rules to call the xNext() method of
       117779  +  ** a cursor that has already reached EOF.
       117780  +  */
       117781  +  assert( pCsr->pNode );
116184 117782   
116185 117783     if( pCsr->iStrategy==1 ){
116186 117784       /* This "scan" is a direct lookup by rowid. There is no next entry. */
116187 117785       nodeRelease(pRtree, pCsr->pNode);
116188 117786       pCsr->pNode = 0;
116189         -  }
116190         -
116191         -  else if( pCsr->pNode ){
       117787  +  }else{
116192 117788       /* Move to the next entry that matches the configured constraints. */
116193 117789       int iHeight = 0;
116194 117790       while( pCsr->pNode ){
116195 117791         RtreeNode *pNode = pCsr->pNode;
116196 117792         int nCell = NCELL(pNode);
116197 117793         for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){
116198 117794           int isEof;
116199 117795           rc = descendToCell(pRtree, pCsr, iHeight, &isEof);
116200 117796           if( rc!=SQLITE_OK || !isEof ){
116201 117797             return rc;
116202 117798           }
116203 117799         }
116204 117800         pCsr->pNode = pNode->pParent;
116205         -      pCsr->iCell = nodeParentIndex(pRtree, pNode);
       117801  +      rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell);
       117802  +      if( rc!=SQLITE_OK ){
       117803  +        return rc;
       117804  +      }
116206 117805         nodeReference(pCsr->pNode);
116207 117806         nodeRelease(pRtree, pNode);
116208 117807         iHeight++;
116209 117808       }
116210 117809     }
116211 117810   
116212 117811     return rc;
................................................................................
116266 117865       sqlite3_reset(pRtree->pReadRowid);
116267 117866     }else{
116268 117867       rc = sqlite3_reset(pRtree->pReadRowid);
116269 117868     }
116270 117869     return rc;
116271 117870   }
116272 117871   
       117872  +/*
       117873  +** This function is called to configure the RtreeConstraint object passed
       117874  +** as the second argument for a MATCH constraint. The value passed as the
       117875  +** first argument to this function is the right-hand operand to the MATCH
       117876  +** operator.
       117877  +*/
       117878  +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
       117879  +  RtreeMatchArg *p;
       117880  +  sqlite3_rtree_geometry *pGeom;
       117881  +  int nBlob;
       117882  +
       117883  +  /* Check that value is actually a blob. */
       117884  +  if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR;
       117885  +
       117886  +  /* Check that the blob is roughly the right size. */
       117887  +  nBlob = sqlite3_value_bytes(pValue);
       117888  +  if( nBlob<sizeof(RtreeMatchArg) 
       117889  +   || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0
       117890  +  ){
       117891  +    return SQLITE_ERROR;
       117892  +  }
       117893  +
       117894  +  pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
       117895  +      sizeof(sqlite3_rtree_geometry) + nBlob
       117896  +  );
       117897  +  if( !pGeom ) return SQLITE_NOMEM;
       117898  +  memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
       117899  +  p = (RtreeMatchArg *)&pGeom[1];
       117900  +
       117901  +  memcpy(p, sqlite3_value_blob(pValue), nBlob);
       117902  +  if( p->magic!=RTREE_GEOMETRY_MAGIC 
       117903  +   || nBlob!=(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double))
       117904  +  ){
       117905  +    sqlite3_free(pGeom);
       117906  +    return SQLITE_ERROR;
       117907  +  }
       117908  +
       117909  +  pGeom->pContext = p->pContext;
       117910  +  pGeom->nParam = p->nParam;
       117911  +  pGeom->aParam = p->aParam;
       117912  +
       117913  +  pCons->xGeom = p->xGeom;
       117914  +  pCons->pGeom = pGeom;
       117915  +  return SQLITE_OK;
       117916  +}
116273 117917   
116274 117918   /* 
116275 117919   ** Rtree virtual table module xFilter method.
116276 117920   */
116277 117921   static int rtreeFilter(
116278 117922     sqlite3_vtab_cursor *pVtabCursor, 
116279 117923     int idxNum, const char *idxStr,
................................................................................
116284 117928   
116285 117929     RtreeNode *pRoot = 0;
116286 117930     int ii;
116287 117931     int rc = SQLITE_OK;
116288 117932   
116289 117933     rtreeReference(pRtree);
116290 117934   
116291         -  sqlite3_free(pCsr->aConstraint);
116292         -  pCsr->aConstraint = 0;
       117935  +  freeCursorConstraints(pCsr);
116293 117936     pCsr->iStrategy = idxNum;
116294 117937   
116295 117938     if( idxNum==1 ){
116296 117939       /* Special case - lookup by rowid. */
116297 117940       RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
116298 117941       i64 iRowid = sqlite3_value_int64(argv[0]);
116299 117942       rc = findLeafNode(pRtree, iRowid, &pLeaf);
116300 117943       pCsr->pNode = pLeaf; 
116301         -    if( pLeaf && rc==SQLITE_OK ){
116302         -      pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid);
       117944  +    if( pLeaf ){
       117945  +      assert( rc==SQLITE_OK );
       117946  +      rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell);
116303 117947       }
116304 117948     }else{
116305 117949       /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array 
116306 117950       ** with the configured constraints. 
116307 117951       */
116308 117952       if( argc>0 ){
116309 117953         pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
116310 117954         pCsr->nConstraint = argc;
116311 117955         if( !pCsr->aConstraint ){
116312 117956           rc = SQLITE_NOMEM;
116313 117957         }else{
       117958  +        memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
116314 117959           assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 );
116315 117960           for(ii=0; ii<argc; ii++){
116316 117961             RtreeConstraint *p = &pCsr->aConstraint[ii];
116317 117962             p->op = idxStr[ii*2];
116318 117963             p->iCoord = idxStr[ii*2+1]-'a';
116319         -          p->rValue = sqlite3_value_double(argv[ii]);
       117964  +          if( p->op==RTREE_MATCH ){
       117965  +            /* A MATCH operator. The right-hand-side must be a blob that
       117966  +            ** can be cast into an RtreeMatchArg object. One created using
       117967  +            ** an sqlite3_rtree_geometry_callback() SQL user function.
       117968  +            */
       117969  +            rc = deserializeGeometry(argv[ii], p);
       117970  +            if( rc!=SQLITE_OK ){
       117971  +              break;
       117972  +            }
       117973  +          }else{
       117974  +            p->rValue = sqlite3_value_double(argv[ii]);
       117975  +          }
116320 117976           }
116321 117977         }
116322 117978       }
116323 117979     
116324 117980       if( rc==SQLITE_OK ){
116325 117981         pCsr->pNode = 0;
116326 117982         rc = nodeAcquire(pRtree, 1, 0, &pRoot);
................................................................................
116353 118009   ** Rtree virtual table module xBestIndex method. There are three
116354 118010   ** table scan strategies to choose from (in order from most to 
116355 118011   ** least desirable):
116356 118012   **
116357 118013   **   idxNum     idxStr        Strategy
116358 118014   **   ------------------------------------------------
116359 118015   **     1        Unused        Direct lookup by rowid.
116360         -**     2        See below     R-tree query.
116361         -**     3        Unused        Full table scan.
       118016  +**     2        See below     R-tree query or full-table scan.
116362 118017   **   ------------------------------------------------
116363 118018   **
116364         -** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy
       118019  +** If strategy 1 is used, then idxStr is not meaningful. If strategy
116365 118020   ** 2 is used, idxStr is formatted to contain 2 bytes for each 
116366 118021   ** constraint used. The first two bytes of idxStr correspond to 
116367 118022   ** the constraint in sqlite3_index_info.aConstraintUsage[] with
116368 118023   ** (argvIndex==1) etc.
116369 118024   **
116370 118025   ** The first of each pair of bytes in idxStr identifies the constraint
116371 118026   ** operator as follows:
................................................................................
116373 118028   **   Operator    Byte Value
116374 118029   **   ----------------------
116375 118030   **      =        0x41 ('A')
116376 118031   **     <=        0x42 ('B')
116377 118032   **      <        0x43 ('C')
116378 118033   **     >=        0x44 ('D')
116379 118034   **      >        0x45 ('E')
       118035  +**   MATCH       0x46 ('F')
116380 118036   **   ----------------------
116381 118037   **
116382 118038   ** The second of each pair of bytes identifies the coordinate column
116383 118039   ** to which the constraint applies. The leftmost coordinate column
116384 118040   ** is 'a', the second from the left 'b' etc.
116385 118041   */
116386 118042   static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
................................................................................
116411 118067         ** considered almost as quick as a direct rowid lookup (for which 
116412 118068         ** sqlite uses an internal cost of 0.0).
116413 118069         */ 
116414 118070         pIdxInfo->estimatedCost = 10.0;
116415 118071         return SQLITE_OK;
116416 118072       }
116417 118073   
116418         -    if( p->usable && p->iColumn>0 ){
       118074  +    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
       118075  +      int j, opmsk;
       118076  +      static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
116419 118077         u8 op = 0;
116420 118078         switch( p->op ){
116421 118079           case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
116422 118080           case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
116423 118081           case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
116424 118082           case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
116425 118083           case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
116426         -      }
116427         -      if( op ){
116428         -        /* Make sure this particular constraint has not been used before.
116429         -        ** If it has been used before, ignore it.
116430         -        **
116431         -        ** A <= or < can be used if there is a prior >= or >.
116432         -        ** A >= or > can be used if there is a prior < or <=.
116433         -        ** A <= or < is disqualified if there is a prior <=, <, or ==.
116434         -        ** A >= or > is disqualified if there is a prior >=, >, or ==.
116435         -        ** A == is disqualifed if there is any prior constraint.
116436         -        */
116437         -        int j, opmsk;
116438         -        static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
116439         -        assert( compatible[RTREE_EQ & 7]==0 );
116440         -        assert( compatible[RTREE_LT & 7]==1 );
116441         -        assert( compatible[RTREE_LE & 7]==1 );
116442         -        assert( compatible[RTREE_GT & 7]==2 );
116443         -        assert( compatible[RTREE_GE & 7]==2 );
116444         -        cCol = p->iColumn - 1 + 'a';
116445         -        opmsk = compatible[op & 7];
116446         -        for(j=0; j<iIdx; j+=2){
116447         -          if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
116448         -            op = 0;
116449         -            break;
116450         -          }
       118084  +        default:
       118085  +          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
       118086  +          op = RTREE_MATCH; 
       118087  +          break;
       118088  +      }
       118089  +      assert( op!=0 );
       118090  +
       118091  +      /* Make sure this particular constraint has not been used before.
       118092  +      ** If it has been used before, ignore it.
       118093  +      **
       118094  +      ** A <= or < can be used if there is a prior >= or >.
       118095  +      ** A >= or > can be used if there is a prior < or <=.
       118096  +      ** A <= or < is disqualified if there is a prior <=, <, or ==.
       118097  +      ** A >= or > is disqualified if there is a prior >=, >, or ==.
       118098  +      ** A == is disqualifed if there is any prior constraint.
       118099  +      */
       118100  +      assert( compatible[RTREE_EQ & 7]==0 );
       118101  +      assert( compatible[RTREE_LT & 7]==1 );
       118102  +      assert( compatible[RTREE_LE & 7]==1 );
       118103  +      assert( compatible[RTREE_GT & 7]==2 );
       118104  +      assert( compatible[RTREE_GE & 7]==2 );
       118105  +      cCol = p->iColumn - 1 + 'a';
       118106  +      opmsk = compatible[op & 7];
       118107  +      for(j=0; j<iIdx; j+=2){
       118108  +        if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
       118109  +          op = 0;
       118110  +          break;
116451 118111           }
116452 118112         }
116453 118113         if( op ){
116454 118114           assert( iIdx<sizeof(zIdxStr)-1 );
116455 118115           zIdxStr[iIdx++] = op;
116456 118116           zIdxStr[iIdx++] = cCol;
116457 118117           pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
................................................................................
116551 118211     RtreeCell *aCell, 
116552 118212     int nCell, 
116553 118213     int iExclude
116554 118214   ){
116555 118215     int ii;
116556 118216     float overlap = 0.0;
116557 118217     for(ii=0; ii<nCell; ii++){
116558         -    if( ii!=iExclude ){
       118218  +#if VARIANT_RSTARTREE_CHOOSESUBTREE
       118219  +    if( ii!=iExclude )
       118220  +#else
       118221  +    assert( iExclude==-1 );
       118222  +#endif
       118223  +    {
116559 118224         int jj;
116560 118225         float o = 1.0;
116561 118226         for(jj=0; jj<(pRtree->nDim*2); jj+=2){
116562 118227           double x1;
116563 118228           double x2;
116564 118229   
116565 118230           x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
................................................................................
116644 118309   #endif
116645 118310   
116646 118311       /* Select the child node which will be enlarged the least if pCell
116647 118312       ** is inserted into it. Resolve ties by choosing the entry with
116648 118313       ** the smallest area.
116649 118314       */
116650 118315       for(iCell=0; iCell<nCell; iCell++){
       118316  +      int bBest = 0;
116651 118317         float growth;
116652 118318         float area;
116653 118319         float overlap = 0.0;
116654 118320         nodeGetCell(pRtree, pNode, iCell, &cell);
116655 118321         growth = cellGrowth(pRtree, &cell, pCell);
116656 118322         area = cellArea(pRtree, &cell);
       118323  +
116657 118324   #if VARIANT_RSTARTREE_CHOOSESUBTREE
116658 118325         if( ii==(pRtree->iDepth-1) ){
116659 118326           overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
116660 118327         }
116661         -#endif
116662 118328         if( (iCell==0) 
116663 118329          || (overlap<fMinOverlap) 
116664 118330          || (overlap==fMinOverlap && growth<fMinGrowth)
116665 118331          || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
116666 118332         ){
       118333  +        bBest = 1;
       118334  +      }
       118335  +#else
       118336  +      if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
       118337  +        bBest = 1;
       118338  +      }
       118339  +#endif
       118340  +      if( bBest ){
116667 118341           fMinOverlap = overlap;
116668 118342           fMinGrowth = growth;
116669 118343           fMinArea = area;
116670 118344           iBest = cell.iRowid;
116671 118345         }
116672 118346       }
116673 118347   
................................................................................
116682 118356   }
116683 118357   
116684 118358   /*
116685 118359   ** A cell with the same content as pCell has just been inserted into
116686 118360   ** the node pNode. This function updates the bounding box cells in
116687 118361   ** all ancestor elements.
116688 118362   */
116689         -static void AdjustTree(
       118363  +static int AdjustTree(
116690 118364     Rtree *pRtree,                    /* Rtree table */
116691 118365     RtreeNode *pNode,                 /* Adjust ancestry of this node. */
116692 118366     RtreeCell *pCell                  /* This cell was just inserted */
116693 118367   ){
116694 118368     RtreeNode *p = pNode;
116695 118369     while( p->pParent ){
116696         -    RtreeCell cell;
116697 118370       RtreeNode *pParent = p->pParent;
116698         -    int iCell = nodeParentIndex(pRtree, p);
       118371  +    RtreeCell cell;
       118372  +    int iCell;
       118373  +
       118374  +    if( nodeParentIndex(pRtree, p, &iCell) ){
       118375  +      return SQLITE_CORRUPT;
       118376  +    }
116699 118377   
116700 118378       nodeGetCell(pRtree, pParent, iCell, &cell);
116701 118379       if( !cellContains(pRtree, &cell, pCell) ){
116702 118380         cellUnion(pRtree, &cell, pCell);
116703 118381         nodeOverwriteCell(pRtree, pParent, &cell, iCell);
116704 118382       }
116705 118383    
116706 118384       p = pParent;
116707 118385     }
       118386  +  return SQLITE_OK;
116708 118387   }
116709 118388   
116710 118389   /*
116711 118390   ** Write mapping (iRowid->iNode) to the <rtree>_rowid table.
116712 118391   */
116713 118392   static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){
116714 118393     sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid);
................................................................................
117229 118908       nodeGetCell(pRtree, pNode, i, &aCell[i]);
117230 118909     }
117231 118910     nodeZero(pRtree, pNode);
117232 118911     memcpy(&aCell[nCell], pCell, sizeof(RtreeCell));
117233 118912     nCell++;
117234 118913   
117235 118914     if( pNode->iNode==1 ){
117236         -    pRight = nodeNew(pRtree, pNode, 1);
117237         -    pLeft = nodeNew(pRtree, pNode, 1);
       118915  +    pRight = nodeNew(pRtree, pNode);
       118916  +    pLeft = nodeNew(pRtree, pNode);
117238 118917       pRtree->iDepth++;
117239 118918       pNode->isDirty = 1;
117240 118919       writeInt16(pNode->zData, pRtree->iDepth);
117241 118920     }else{
117242 118921       pLeft = pNode;
117243         -    pRight = nodeNew(pRtree, pLeft->pParent, 1);
       118922  +    pRight = nodeNew(pRtree, pLeft->pParent);
117244 118923       nodeReference(pLeft);
117245 118924     }
117246 118925   
117247 118926     if( !pLeft || !pRight ){
117248 118927       rc = SQLITE_NOMEM;
117249 118928       goto splitnode_out;
117250 118929     }
................................................................................
117253 118932     memset(pRight->zData, 0, pRtree->iNodeSize);
117254 118933   
117255 118934     rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
117256 118935     if( rc!=SQLITE_OK ){
117257 118936       goto splitnode_out;
117258 118937     }
117259 118938   
117260         -  /* Ensure both child nodes have node numbers assigned to them. */
117261         -  if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)))
       118939  +  /* Ensure both child nodes have node numbers assigned to them by calling
       118940  +  ** nodeWrite(). Node pRight always needs a node number, as it was created
       118941  +  ** by nodeNew() above. But node pLeft sometimes already has a node number.
       118942  +  ** In this case avoid the all to nodeWrite().
       118943  +  */
       118944  +  if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))
117262 118945      || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft)))
117263 118946     ){
117264 118947       goto splitnode_out;
117265 118948     }
117266 118949   
117267 118950     rightbbox.iRowid = pRight->iNode;
117268 118951     leftbbox.iRowid = pLeft->iNode;
................................................................................
117270 118953     if( pNode->iNode==1 ){
117271 118954       rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1);
117272 118955       if( rc!=SQLITE_OK ){
117273 118956         goto splitnode_out;
117274 118957       }
117275 118958     }else{
117276 118959       RtreeNode *pParent = pLeft->pParent;
117277         -    int iCell = nodeParentIndex(pRtree, pLeft);
117278         -    nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
117279         -    AdjustTree(pRtree, pParent, &leftbbox);
       118960  +    int iCell;
       118961  +    rc = nodeParentIndex(pRtree, pLeft, &iCell);
       118962  +    if( rc==SQLITE_OK ){
       118963  +      nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
       118964  +      rc = AdjustTree(pRtree, pParent, &leftbbox);
       118965  +    }
       118966  +    if( rc!=SQLITE_OK ){
       118967  +      goto splitnode_out;
       118968  +    }
117280 118969     }
117281 118970     if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
117282 118971       goto splitnode_out;
117283 118972     }
117284 118973   
117285 118974     for(i=0; i<NCELL(pRight); i++){
117286 118975       i64 iRowid = nodeGetRowid(pRtree, pRight, i);
................................................................................
117316 119005   splitnode_out:
117317 119006     nodeRelease(pRtree, pRight);
117318 119007     nodeRelease(pRtree, pLeft);
117319 119008     sqlite3_free(aCell);
117320 119009     return rc;
117321 119010   }
117322 119011   
       119012  +/*
       119013  +** If node pLeaf is not the root of the r-tree and its pParent pointer is 
       119014  +** still NULL, load all ancestor nodes of pLeaf into memory and populate
       119015  +** the pLeaf->pParent chain all the way up to the root node.
       119016  +**
       119017  +** This operation is required when a row is deleted (or updated - an update
       119018  +** is implemented as a delete followed by an insert). SQLite provides the
       119019  +** rowid of the row to delete, which can be used to find the leaf on which
       119020  +** the entry resides (argument pLeaf). Once the leaf is located, this 
       119021  +** function is called to determine its ancestry.
       119022  +*/
117323 119023   static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
117324 119024     int rc = SQLITE_OK;
117325         -  if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){
117326         -    sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode);
117327         -    if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){
117328         -      i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
117329         -      rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent);
117330         -    }else{
117331         -      rc = SQLITE_ERROR;
       119025  +  RtreeNode *pChild = pLeaf;
       119026  +  while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){
       119027  +    int rc2 = SQLITE_OK;          /* sqlite3_reset() return code */
       119028  +    sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode);
       119029  +    rc = sqlite3_step(pRtree->pReadParent);
       119030  +    if( rc==SQLITE_ROW ){
       119031  +      RtreeNode *pTest;           /* Used to test for reference loops */
       119032  +      i64 iNode;                  /* Node number of parent node */
       119033  +
       119034  +      /* Before setting pChild->pParent, test that we are not creating a
       119035  +      ** loop of references (as we would if, say, pChild==pParent). We don't
       119036  +      ** want to do this as it leads to a memory leak when trying to delete
       119037  +      ** the referenced counted node structures.
       119038  +      */
       119039  +      iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
       119040  +      for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
       119041  +      if( !pTest ){
       119042  +        rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
       119043  +      }
117332 119044       }
117333         -    sqlite3_reset(pRtree->pReadParent);
117334         -    if( rc==SQLITE_OK ){
117335         -      rc = fixLeafParent(pRtree, pLeaf->pParent);
117336         -    }
       119045  +    rc = sqlite3_reset(pRtree->pReadParent);
       119046  +    if( rc==SQLITE_OK ) rc = rc2;
       119047  +    if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT;
       119048  +    pChild = pChild->pParent;
117337 119049     }
117338 119050     return rc;
117339 119051   }
117340 119052   
117341 119053   static int deleteCell(Rtree *, RtreeNode *, int, int);
117342 119054   
117343 119055   static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
117344 119056     int rc;
       119057  +  int rc2;
117345 119058     RtreeNode *pParent;
117346 119059     int iCell;
117347 119060   
117348 119061     assert( pNode->nRef==1 );
117349 119062   
117350 119063     /* Remove the entry in the parent cell. */
117351         -  iCell = nodeParentIndex(pRtree, pNode);
117352         -  pParent = pNode->pParent;
117353         -  pNode->pParent = 0;
117354         -  if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1)) 
117355         -   || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
117356         -  ){
       119064  +  rc = nodeParentIndex(pRtree, pNode, &iCell);
       119065  +  if( rc==SQLITE_OK ){
       119066  +    pParent = pNode->pParent;
       119067  +    pNode->pParent = 0;
       119068  +    rc = deleteCell(pRtree, pParent, iCell, iHeight+1);
       119069  +  }
       119070  +  rc2 = nodeRelease(pRtree, pParent);
       119071  +  if( rc==SQLITE_OK ){
       119072  +    rc = rc2;
       119073  +  }
       119074  +  if( rc!=SQLITE_OK ){
117357 119075       return rc;
117358 119076     }
117359 119077   
117360 119078     /* Remove the xxx_node entry. */
117361 119079     sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode);
117362 119080     sqlite3_step(pRtree->pDeleteNode);
117363 119081     if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){
................................................................................
117379 119097     pNode->pNext = pRtree->pDeleted;
117380 119098     pNode->nRef++;
117381 119099     pRtree->pDeleted = pNode;
117382 119100   
117383 119101     return SQLITE_OK;
117384 119102   }
117385 119103   
117386         -static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
       119104  +static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
117387 119105     RtreeNode *pParent = pNode->pParent;
       119106  +  int rc = SQLITE_OK; 
117388 119107     if( pParent ){
117389 119108       int ii; 
117390 119109       int nCell = NCELL(pNode);
117391 119110       RtreeCell box;                            /* Bounding box for pNode */
117392 119111       nodeGetCell(pRtree, pNode, 0, &box);
117393 119112       for(ii=1; ii<nCell; ii++){
117394 119113         RtreeCell cell;
117395 119114         nodeGetCell(pRtree, pNode, ii, &cell);
117396 119115         cellUnion(pRtree, &box, &cell);
117397 119116       }
117398 119117       box.iRowid = pNode->iNode;
117399         -    ii = nodeParentIndex(pRtree, pNode);
117400         -    nodeOverwriteCell(pRtree, pParent, &box, ii);
117401         -    fixBoundingBox(pRtree, pParent);
       119118  +    rc = nodeParentIndex(pRtree, pNode, &ii);
       119119  +    if( rc==SQLITE_OK ){
       119120  +      nodeOverwriteCell(pRtree, pParent, &box, ii);
       119121  +      rc = fixBoundingBox(pRtree, pParent);
       119122  +    }
117402 119123     }
       119124  +  return rc;
117403 119125   }
117404 119126   
117405 119127   /*
117406 119128   ** Delete the cell at index iCell of node pNode. After removing the
117407 119129   ** cell, adjust the r-tree data structure if required.
117408 119130   */
117409 119131   static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
       119132  +  RtreeNode *pParent;
117410 119133     int rc;
117411 119134   
117412 119135     if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){
117413 119136       return rc;
117414 119137     }
117415 119138   
117416 119139     /* Remove the cell from the node. This call just moves bytes around
................................................................................
117419 119142     nodeDeleteCell(pRtree, pNode, iCell);
117420 119143   
117421 119144     /* If the node is not the tree root and now has less than the minimum
117422 119145     ** number of cells, remove it from the tree. Otherwise, update the
117423 119146     ** cell in the parent node so that it tightly contains the updated
117424 119147     ** node.
117425 119148     */
117426         -  if( pNode->iNode!=1 ){
117427         -    RtreeNode *pParent = pNode->pParent;
117428         -    if( (pParent->iNode!=1 || NCELL(pParent)!=1) 
117429         -     && (NCELL(pNode)<RTREE_MINCELLS(pRtree))
117430         -    ){
       119149  +  pParent = pNode->pParent;
       119150  +  assert( pParent || pNode->iNode==1 );
       119151  +  if( pParent ){
       119152  +    if( NCELL(pNode)<RTREE_MINCELLS(pRtree) ){
117431 119153         rc = removeNode(pRtree, pNode, iHeight);
117432 119154       }else{
117433         -      fixBoundingBox(pRtree, pNode);
       119155  +      rc = fixBoundingBox(pRtree, pNode);
117434 119156       }
117435 119157     }
117436 119158   
117437 119159     return rc;
117438 119160   }
117439 119161   
117440 119162   static int Reinsert(
................................................................................
117509 119231           rc = rowidWrite(pRtree, p->iRowid, pNode->iNode);
117510 119232         }else{
117511 119233           rc = parentWrite(pRtree, p->iRowid, pNode->iNode);
117512 119234         }
117513 119235       }
117514 119236     }
117515 119237     if( rc==SQLITE_OK ){
117516         -    fixBoundingBox(pRtree, pNode);
       119238  +    rc = fixBoundingBox(pRtree, pNode);
117517 119239     }
117518 119240     for(; rc==SQLITE_OK && ii<nCell; ii++){
117519 119241       /* Find a node to store this cell in. pNode->iNode currently contains
117520 119242       ** the height of the sub-tree headed by the cell.
117521 119243       */
117522 119244       RtreeNode *pInsert;
117523 119245       RtreeCell *p = &aCell[aOrder[ii]];
................................................................................
117563 119285         pRtree->iReinsertHeight = iHeight;
117564 119286         rc = Reinsert(pRtree, pNode, pCell, iHeight);
117565 119287       }
117566 119288   #else
117567 119289       rc = SplitNode(pRtree, pNode, pCell, iHeight);
117568 119290   #endif
117569 119291     }else{
117570         -    AdjustTree(pRtree, pNode, pCell);
117571         -    if( iHeight==0 ){
117572         -      rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
117573         -    }else{
117574         -      rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
       119292  +    rc = AdjustTree(pRtree, pNode, pCell);
       119293  +    if( rc==SQLITE_OK ){
       119294  +      if( iHeight==0 ){
       119295  +        rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
       119296  +      }else{
       119297  +        rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
       119298  +      }
117575 119299       }
117576 119300     }
117577 119301     return rc;
117578 119302   }
117579 119303   
117580 119304   static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
117581 119305     int ii;
................................................................................
117637 119361   ){
117638 119362     Rtree *pRtree = (Rtree *)pVtab;
117639 119363     int rc = SQLITE_OK;
117640 119364   
117641 119365     rtreeReference(pRtree);
117642 119366   
117643 119367     assert(nData>=1);
117644         -  assert(hashIsEmpty(pRtree));
117645 119368   
117646 119369     /* If azData[0] is not an SQL NULL value, it is the rowid of a
117647 119370     ** record to delete from the r-tree table. The following block does
117648 119371     ** just that.
117649 119372     */
117650 119373     if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
117651 119374       i64 iDelete;                /* The rowid to delete */
................................................................................
117663 119386         iDelete = sqlite3_value_int64(azData[0]);
117664 119387         rc = findLeafNode(pRtree, iDelete, &pLeaf);
117665 119388       }
117666 119389   
117667 119390       /* Delete the cell in question from the leaf node. */
117668 119391       if( rc==SQLITE_OK ){
117669 119392         int rc2;
117670         -      iCell = nodeRowidIndex(pRtree, pLeaf, iDelete);
117671         -      rc = deleteCell(pRtree, pLeaf, iCell, 0);
       119393  +      rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
       119394  +      if( rc==SQLITE_OK ){
       119395  +        rc = deleteCell(pRtree, pLeaf, iCell, 0);
       119396  +      }
117672 119397         rc2 = nodeRelease(pRtree, pLeaf);
117673 119398         if( rc==SQLITE_OK ){
117674 119399           rc = rc2;
117675 119400         }
117676 119401       }
117677 119402   
117678 119403       /* Delete the corresponding entry in the <rtree>_rowid table. */
................................................................................
117686 119411       ** it, schedule the contents of the child for reinsertion and 
117687 119412       ** reduce the tree height by one.
117688 119413       **
117689 119414       ** This is equivalent to copying the contents of the child into
117690 119415       ** the root node (the operation that Gutman's paper says to perform 
117691 119416       ** in this scenario).
117692 119417       */
117693         -    if( rc==SQLITE_OK && pRtree->iDepth>0 ){
117694         -      if( rc==SQLITE_OK && NCELL(pRoot)==1 ){
117695         -        RtreeNode *pChild;
117696         -        i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
117697         -        rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
117698         -        if( rc==SQLITE_OK ){
117699         -          rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
117700         -        }
117701         -        if( rc==SQLITE_OK ){
117702         -          pRtree->iDepth--;
117703         -          writeInt16(pRoot->zData, pRtree->iDepth);
117704         -          pRoot->isDirty = 1;
117705         -        }
       119418  +    if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
       119419  +      int rc2;
       119420  +      RtreeNode *pChild;
       119421  +      i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
       119422  +      rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
       119423  +      if( rc==SQLITE_OK ){
       119424  +        rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
       119425  +      }
       119426  +      rc2 = nodeRelease(pRtree, pChild);
       119427  +      if( rc==SQLITE_OK ) rc = rc2;
       119428  +      if( rc==SQLITE_OK ){
       119429  +        pRtree->iDepth--;
       119430  +        writeInt16(pRoot->zData, pRtree->iDepth);
       119431  +        pRoot->isDirty = 1;
117706 119432         }
117707 119433       }
117708 119434   
117709 119435       /* Re-insert the contents of any underfull nodes removed from the tree. */
117710 119436       for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){
117711 119437         if( rc==SQLITE_OK ){
117712 119438           rc = reinsertNodeContent(pRtree, pLeaf);
................................................................................
117988 119714     char **pzErr,                       /* OUT: Error message, if any */
117989 119715     int isCreate                        /* True for xCreate, false for xConnect */
117990 119716   ){
117991 119717     int rc = SQLITE_OK;
117992 119718     Rtree *pRtree;
117993 119719     int nDb;              /* Length of string argv[1] */
117994 119720     int nName;            /* Length of string argv[2] */
117995         -  int eCoordType = (int)pAux;
       119721  +  int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32);
117996 119722   
117997 119723     const char *aErrMsg[] = {
117998 119724       0,                                                    /* 0 */
117999 119725       "Wrong number of columns for an rtree table",         /* 1 */
118000 119726       "Too few columns for an rtree table",                 /* 2 */
118001 119727       "Too many columns for an rtree table"                 /* 3 */
118002 119728     };
................................................................................
118134 119860   
118135 119861   /*
118136 119862   ** Register the r-tree module with database handle db. This creates the
118137 119863   ** virtual table module "rtree" and the debugging/analysis scalar 
118138 119864   ** function "rtreenode".
118139 119865   */
118140 119866   SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
118141         -  int rc = SQLITE_OK;
       119867  +  const int utf8 = SQLITE_UTF8;
       119868  +  int rc;
118142 119869   
118143         -  if( rc==SQLITE_OK ){
118144         -    int utf8 = SQLITE_UTF8;
118145         -    rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
118146         -  }
       119870  +  rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
118147 119871     if( rc==SQLITE_OK ){
118148 119872       int utf8 = SQLITE_UTF8;
118149 119873       rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
118150 119874     }
118151 119875     if( rc==SQLITE_OK ){
118152 119876       void *c = (void *)RTREE_COORD_REAL32;
118153 119877       rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
................................................................................
118155 119879     if( rc==SQLITE_OK ){
118156 119880       void *c = (void *)RTREE_COORD_INT32;
118157 119881       rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
118158 119882     }
118159 119883   
118160 119884     return rc;
118161 119885   }
       119886  +
       119887  +/*
       119888  +** A version of sqlite3_free() that can be used as a callback. This is used
       119889  +** in two places - as the destructor for the blob value returned by the
       119890  +** invocation of a geometry function, and as the destructor for the geometry
       119891  +** functions themselves.
       119892  +*/
       119893  +static void doSqlite3Free(void *p){
       119894  +  sqlite3_free(p);
       119895  +}
       119896  +
       119897  +/*
       119898  +** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite
       119899  +** scalar user function. This C function is the callback used for all such
       119900  +** registered SQL functions.
       119901  +**
       119902  +** The scalar user functions return a blob that is interpreted by r-tree
       119903  +** table MATCH operators.
       119904  +*/
       119905  +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
       119906  +  RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
       119907  +  RtreeMatchArg *pBlob;
       119908  +  int nBlob;
       119909  +
       119910  +  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double);
       119911  +  pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
       119912  +  if( !pBlob ){
       119913  +    sqlite3_result_error_nomem(ctx);
       119914  +  }else{
       119915  +    int i;
       119916  +    pBlob->magic = RTREE_GEOMETRY_MAGIC;
       119917  +    pBlob->xGeom = pGeomCtx->xGeom;
       119918  +    pBlob->pContext = pGeomCtx->pContext;
       119919  +    pBlob->nParam = nArg;
       119920  +    for(i=0; i<nArg; i++){
       119921  +      pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
       119922  +    }
       119923  +    sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
       119924  +  }
       119925  +}
       119926  +
       119927  +/*
       119928  +** Register a new geometry function for use with the r-tree MATCH operator.
       119929  +*/
       119930  +SQLITE_API int sqlite3_rtree_geometry_callback(
       119931  +  sqlite3 *db,
       119932  +  const char *zGeom,
       119933  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
       119934  +  void *pContext
       119935  +){
       119936  +  RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */
       119937  +
       119938  +  /* Allocate and populate the context object. */
       119939  +  pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
       119940  +  if( !pGeomCtx ) return SQLITE_NOMEM;
       119941  +  pGeomCtx->xGeom = xGeom;
       119942  +  pGeomCtx->pContext = pContext;
       119943  +
       119944  +  /* Create the new user-function. Register a destructor function to delete
       119945  +  ** the context object when it is no longer required.  */
       119946  +  return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, 
       119947  +      (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
       119948  +  );
       119949  +}
118162 119950   
118163 119951   #if !SQLITE_CORE
118164 119952   SQLITE_API int sqlite3_extension_init(
118165 119953     sqlite3 *db,
118166 119954     char **pzErrMsg,
118167 119955     const sqlite3_api_routines *pApi
118168 119956   ){

Changes to src/sqlite3.h.

    93     93   ** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
    94     94   ** be larger than the release from which it is derived.  Either Y will
    95     95   ** be held constant and Z will be incremented or else Y will be incremented
    96     96   ** and Z will be reset to zero.
    97     97   **
    98     98   ** Since version 3.6.18, SQLite source code has been stored in the
    99     99   ** <a href="http://www.fossil-scm.org/">Fossil configuration management
   100         -** system</a>.  ^The SQLITE_SOURCE_ID macro evalutes to
          100  +** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
   101    101   ** a string which identifies a particular check-in of SQLite
   102    102   ** within its configuration management system.  ^The SQLITE_SOURCE_ID
   103    103   ** string contains the date and time of the check-in (UTC) and an SHA1
   104    104   ** hash of the entire source tree.
   105    105   **
   106    106   ** See also: [sqlite3_libversion()],
   107    107   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   108    108   ** [sqlite_version()] and [sqlite_source_id()].
   109    109   */
   110         -#define SQLITE_VERSION        "3.7.1"
   111         -#define SQLITE_VERSION_NUMBER 3007001
   112         -#define SQLITE_SOURCE_ID      "2010-08-05 03:21:40 fbe70e1106bcc5086ceb9d8f39cc39baf3643092"
          110  +#define SQLITE_VERSION        "3.7.3"
          111  +#define SQLITE_VERSION_NUMBER 3007003
          112  +#define SQLITE_SOURCE_ID      "2010-10-07 13:29:13 e55ada89246d4cc5f476891c70572dc7c1c3643e"
   113    113   
   114    114   /*
   115    115   ** CAPI3REF: Run-Time Library Version Numbers
   116    116   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   117    117   **
   118    118   ** These interfaces provide the same information as the [SQLITE_VERSION],
   119    119   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
   150    150   ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
   151    151   **
   152    152   ** ^The sqlite3_compileoption_used() function returns 0 or 1 
   153    153   ** indicating whether the specified option was defined at 
   154    154   ** compile time.  ^The SQLITE_ prefix may be omitted from the 
   155    155   ** option name passed to sqlite3_compileoption_used().  
   156    156   **
   157         -** ^The sqlite3_compileoption_get() function allows interating
          157  +** ^The sqlite3_compileoption_get() function allows iterating
   158    158   ** over the list of options that were defined at compile time by
   159    159   ** returning the N-th compile time option string.  ^If N is out of range,
   160    160   ** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_ 
   161    161   ** prefix is omitted from any strings returned by 
   162    162   ** sqlite3_compileoption_get().
   163    163   **
   164    164   ** ^Support for the diagnostic functions sqlite3_compileoption_used()
   165         -** and sqlite3_compileoption_get() may be omitted by specifing the 
          165  +** and sqlite3_compileoption_get() may be omitted by specifying the 
   166    166   ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
   167    167   **
   168    168   ** See also: SQL functions [sqlite_compileoption_used()] and
   169    169   ** [sqlite_compileoption_get()] and the [compile_options pragma].
   170    170   */
   171    171   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   172    172   SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
................................................................................
   264    264   #endif
   265    265   
   266    266   /*
   267    267   ** CAPI3REF: Closing A Database Connection
   268    268   **
   269    269   ** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
   270    270   ** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
   271         -** successfullly destroyed and all associated resources are deallocated.
          271  +** successfully destroyed and all associated resources are deallocated.
   272    272   **
   273    273   ** Applications must [sqlite3_finalize | finalize] all [prepared statements]
   274    274   ** and [sqlite3_blob_close | close] all [BLOB handles] associated with
   275    275   ** the [sqlite3] object prior to attempting to close the object.  ^If
   276    276   ** sqlite3_close() is called on a [database connection] that still has
   277    277   ** outstanding [prepared statements] or [BLOB handles], then it returns
   278    278   ** SQLITE_BUSY.
................................................................................
   691    691   **
   692    692   ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
   693    693   ** layer a hint of how large the database file will grow to be during the
   694    694   ** current transaction.  This hint is not guaranteed to be accurate but it
   695    695   ** is often close.  The underlying VFS might choose to preallocate database
   696    696   ** file space based on this hint in order to help writes to the database
   697    697   ** file run faster.
          698  +**
          699  +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
          700  +** extends and truncates the database file in chunks of a size specified
          701  +** by the user. The fourth argument to [sqlite3_file_control()] should 
          702  +** point to an integer (type int) containing the new chunk-size to use
          703  +** for the nominated database. Allocating database file space in large
          704  +** chunks (say 1MB at a time), may reduce file-system fragmentation and
          705  +** improve performance on some systems.
   698    706   */
   699    707   #define SQLITE_FCNTL_LOCKSTATE        1
   700    708   #define SQLITE_GET_LOCKPROXYFILE      2
   701    709   #define SQLITE_SET_LOCKPROXYFILE      3
   702    710   #define SQLITE_LAST_ERRNO             4
   703    711   #define SQLITE_FCNTL_SIZE_HINT        5
          712  +#define SQLITE_FCNTL_CHUNK_SIZE       6
   704    713   
   705    714   /*
   706    715   ** CAPI3REF: Mutex Handle
   707    716   **
   708    717   ** The mutex module within SQLite defines [sqlite3_mutex] to be an
   709    718   ** abstract type for a mutex object.  The SQLite core never looks
   710    719   ** at the internal representation of an [sqlite3_mutex].  It only
................................................................................
   744    753   ** or modify this field while holding a particular static mutex.
   745    754   ** The application should never modify anything within the sqlite3_vfs
   746    755   ** object once the object has been registered.
   747    756   **
   748    757   ** The zName field holds the name of the VFS module.  The name must
   749    758   ** be unique across all VFS modules.
   750    759   **
   751         -** SQLite will guarantee that the zFilename parameter to xOpen
          760  +** ^SQLite guarantees that the zFilename parameter to xOpen
   752    761   ** is either a NULL pointer or string obtained
   753         -** from xFullPathname().  SQLite further guarantees that
          762  +** from xFullPathname() with an optional suffix added.
          763  +** ^If a suffix is added to the zFilename parameter, it will
          764  +** consist of a single "-" character followed by no more than
          765  +** 10 alphanumeric and/or "-" characters.
          766  +** ^SQLite further guarantees that
   754    767   ** the string will be valid and unchanged until xClose() is
   755    768   ** called. Because of the previous sentence,
   756    769   ** the [sqlite3_file] can safely store a pointer to the
   757    770   ** filename if it needs to remember the filename for some reason.
   758         -** If the zFilename parameter is xOpen is a NULL pointer then xOpen
   759         -** must invent its own temporary name for the file.  Whenever the 
          771  +** If the zFilename parameter to xOpen is a NULL pointer then xOpen
          772  +** must invent its own temporary name for the file.  ^Whenever the 
   760    773   ** xFilename parameter is NULL it will also be the case that the
   761    774   ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
   762    775   **
   763    776   ** The flags argument to xOpen() includes all bits set in
   764    777   ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
   765    778   ** or [sqlite3_open16()] is used, then flags includes at least
   766    779   ** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. 
   767    780   ** If xOpen() opens a file read-only then it sets *pOutFlags to
   768    781   ** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
   769    782   **
   770         -** SQLite will also add one of the following flags to the xOpen()
          783  +** ^(SQLite will also add one of the following flags to the xOpen()
   771    784   ** call, depending on the object being opened:
   772    785   **
   773    786   ** <ul>
   774    787   ** <li>  [SQLITE_OPEN_MAIN_DB]
   775    788   ** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
   776    789   ** <li>  [SQLITE_OPEN_TEMP_DB]
   777    790   ** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
   778    791   ** <li>  [SQLITE_OPEN_TRANSIENT_DB]
   779    792   ** <li>  [SQLITE_OPEN_SUBJOURNAL]
   780    793   ** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
   781         -** </ul>
          794  +** <li>  [SQLITE_OPEN_WAL]
          795  +** </ul>)^
   782    796   **
   783    797   ** The file I/O implementation can use the object type flags to
   784    798   ** change the way it deals with files.  For example, an application
   785    799   ** that does not care about crash recovery or rollback might make
   786    800   ** the open of a journal file a no-op.  Writes to this journal would
   787    801   ** also be no-ops, and any attempt to read the journal would return
   788    802   ** SQLITE_IOERR.  Or the implementation might recognize that a database
................................................................................
   793    807   **
   794    808   ** <ul>
   795    809   ** <li> [SQLITE_OPEN_DELETEONCLOSE]
   796    810   ** <li> [SQLITE_OPEN_EXCLUSIVE]
   797    811   ** </ul>
   798    812   **
   799    813   ** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
   800         -** deleted when it is closed.  The [SQLITE_OPEN_DELETEONCLOSE]
   801         -** will be set for TEMP  databases, journals and for subjournals.
          814  +** deleted when it is closed.  ^The [SQLITE_OPEN_DELETEONCLOSE]
          815  +** will be set for TEMP databases and their journals, transient
          816  +** databases, and subjournals.
   802    817   **
   803         -** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
          818  +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
   804    819   ** with the [SQLITE_OPEN_CREATE] flag, which are both directly
   805    820   ** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
   806    821   ** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
   807    822   ** SQLITE_OPEN_CREATE, is used to indicate that file should always
   808    823   ** be created, and that it is an error if it already exists.
   809    824   ** It is <i>not</i> used to indicate the file should be opened 
   810    825   ** for exclusive access.
   811    826   **
   812         -** At least szOsFile bytes of memory are allocated by SQLite
          827  +** ^At least szOsFile bytes of memory are allocated by SQLite
   813    828   ** to hold the  [sqlite3_file] structure passed as the third
   814    829   ** argument to xOpen.  The xOpen method does not have to
   815    830   ** allocate the structure; it should just fill it in.  Note that
   816    831   ** the xOpen method must set the sqlite3_file.pMethods to either
   817    832   ** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
   818    833   ** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
   819    834   ** element will be valid after xOpen returns regardless of the success
   820    835   ** or failure of the xOpen call.
   821    836   **
   822         -** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
          837  +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
   823    838   ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
   824    839   ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
   825    840   ** to test whether a file is at least readable.   The file can be a
   826    841   ** directory.
   827    842   **
   828         -** SQLite will always allocate at least mxPathname+1 bytes for the
          843  +** ^SQLite will always allocate at least mxPathname+1 bytes for the
   829    844   ** output buffer xFullPathname.  The exact size of the output buffer
   830    845   ** is also passed as a parameter to both  methods. If the output buffer
   831    846   ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
   832    847   ** handled as a fatal error by SQLite, vfs implementations should endeavor
   833    848   ** to prevent this by setting mxPathname to a sufficiently large value.
   834    849   **
   835    850   ** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
   836    851   ** interfaces are not strictly a part of the filesystem, but they are
   837    852   ** included in the VFS structure for completeness.
   838    853   ** The xRandomness() function attempts to return nBytes bytes
   839    854   ** of good-quality randomness into zOut.  The return value is
   840    855   ** the actual number of bytes of randomness obtained.
   841    856   ** The xSleep() method causes the calling thread to sleep for at
   842         -** least the number of microseconds given.  The xCurrentTime()
          857  +** least the number of microseconds given.  ^The xCurrentTime()
   843    858   ** method returns a Julian Day Number for the current date and time as
   844    859   ** a floating point value.
   845         -** The xCurrentTimeInt64() method returns, as an integer, the Julian
          860  +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
   846    861   ** Day Number multipled by 86400000 (the number of milliseconds in 
   847    862   ** a 24-hour day).  
   848    863   ** ^SQLite will use the xCurrentTimeInt64() method to get the current
   849    864   ** date and time if that method is available (if iVersion is 2 or 
   850    865   ** greater and the function pointer is not NULL) and will fall back
   851    866   ** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
   852    867   */
................................................................................
  1235   1250   ** <dd> ^This option takes single argument of type int, interpreted as a 
  1236   1251   ** boolean, which enables or disables the collection of memory allocation 
  1237   1252   ** statistics. ^(When memory allocation statistics are disabled, the 
  1238   1253   ** following SQLite interfaces become non-operational:
  1239   1254   **   <ul>
  1240   1255   **   <li> [sqlite3_memory_used()]
  1241   1256   **   <li> [sqlite3_memory_highwater()]
  1242         -**   <li> [sqlite3_soft_heap_limit()]
         1257  +**   <li> [sqlite3_soft_heap_limit64()]
  1243   1258   **   <li> [sqlite3_status()]
  1244   1259   **   </ul>)^
  1245   1260   ** ^Memory allocation statistics are enabled by default unless SQLite is
  1246   1261   ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
  1247   1262   ** allocation statistics are disabled by default.
  1248   1263   ** </dd>
  1249   1264   **
  1250   1265   ** <dt>SQLITE_CONFIG_SCRATCH</dt>
  1251   1266   ** <dd> ^This option specifies a static memory buffer that SQLite can use for
  1252   1267   ** scratch memory.  There are three arguments:  A pointer an 8-byte
  1253   1268   ** aligned memory buffer from which the scrach allocations will be
  1254   1269   ** drawn, the size of each scratch allocation (sz),
  1255   1270   ** and the maximum number of scratch allocations (N).  The sz
  1256         -** argument must be a multiple of 16. The sz parameter should be a few bytes
  1257         -** larger than the actual scratch space required due to internal overhead.
         1271  +** argument must be a multiple of 16.
  1258   1272   ** The first argument must be a pointer to an 8-byte aligned buffer
  1259   1273   ** of at least sz*N bytes of memory.
  1260         -** ^SQLite will use no more than one scratch buffer per thread.  So
  1261         -** N should be set to the expected maximum number of threads.  ^SQLite will
  1262         -** never require a scratch buffer that is more than 6 times the database
  1263         -** page size. ^If SQLite needs needs additional scratch memory beyond 
  1264         -** what is provided by this configuration option, then 
         1274  +** ^SQLite will use no more than two scratch buffers per thread.  So
         1275  +** N should be set to twice the expected maximum number of threads.
         1276  +** ^SQLite will never require a scratch buffer that is more than 6
         1277  +** times the database page size. ^If SQLite needs needs additional
         1278  +** scratch memory beyond what is provided by this configuration option, then 
  1265   1279   ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
  1266   1280   **
  1267   1281   ** <dt>SQLITE_CONFIG_PAGECACHE</dt>
  1268   1282   ** <dd> ^This option specifies a static memory buffer that SQLite can use for
  1269   1283   ** the database page cache with the default page cache implemenation.  
  1270   1284   ** This configuration should not be used if an application-define page
  1271   1285   ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
................................................................................
  1277   1291   ** the host architecture.  ^It is harmless, apart from the wasted memory,
  1278   1292   ** to make sz a little too large.  The first
  1279   1293   ** argument should point to an allocation of at least sz*N bytes of memory.
  1280   1294   ** ^SQLite will use the memory provided by the first argument to satisfy its
  1281   1295   ** memory needs for the first N pages that it adds to cache.  ^If additional
  1282   1296   ** page cache memory is needed beyond what is provided by this option, then
  1283   1297   ** SQLite goes to [sqlite3_malloc()] for the additional storage space.
  1284         -** ^The implementation might use one or more of the N buffers to hold 
  1285         -** memory accounting information. The pointer in the first argument must
         1298  +** The pointer in the first argument must
  1286   1299   ** be aligned to an 8-byte boundary or subsequent behavior of SQLite
  1287   1300   ** will be undefined.</dd>
  1288   1301   **
  1289   1302   ** <dt>SQLITE_CONFIG_HEAP</dt>
  1290   1303   ** <dd> ^This option specifies a static memory buffer that SQLite will use
  1291   1304   ** for all of its dynamic memory allocation needs beyond those provided
  1292   1305   ** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
................................................................................
  1407   1420   ** may be NULL in which case SQLite will allocate the
  1408   1421   ** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
  1409   1422   ** size of each lookaside buffer slot.  ^The third argument is the number of
  1410   1423   ** slots.  The size of the buffer in the first argument must be greater than
  1411   1424   ** or equal to the product of the second and third arguments.  The buffer
  1412   1425   ** must be aligned to an 8-byte boundary.  ^If the second argument to
  1413   1426   ** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
  1414         -** rounded down to the next smaller
  1415         -** multiple of 8.  See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
         1427  +** rounded down to the next smaller multiple of 8.  ^(The lookaside memory
         1428  +** configuration for a database connection can only be changed when that
         1429  +** connection is not currently using lookaside memory, or in other words
         1430  +** when the "current value" returned by
         1431  +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
         1432  +** Any attempt to change the lookaside memory configuration when lookaside
         1433  +** memory is in use leaves the configuration unchanged and returns 
         1434  +** [SQLITE_BUSY].)^</dd>
  1416   1435   **
  1417   1436   ** </dl>
  1418   1437   */
  1419   1438   #define SQLITE_DBCONFIG_LOOKASIDE    1001  /* void* int int */
  1420   1439   
  1421   1440   
  1422   1441   /*
................................................................................
  1712   1731   ** was defined  (using [sqlite3_busy_handler()]) prior to calling
  1713   1732   ** this routine, that other busy handler is cleared.)^
  1714   1733   */
  1715   1734   SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
  1716   1735   
  1717   1736   /*
  1718   1737   ** CAPI3REF: Convenience Routines For Running Queries
         1738  +**
         1739  +** This is a legacy interface that is preserved for backwards compatibility.
         1740  +** Use of this interface is not recommended.
  1719   1741   **
  1720   1742   ** Definition: A <b>result table</b> is memory data structure created by the
  1721   1743   ** [sqlite3_get_table()] interface.  A result table records the
  1722   1744   ** complete query results from one or more queries.
  1723   1745   **
  1724   1746   ** The table conceptually has a number of rows and columns.  But
  1725   1747   ** these numbers are not part of the result table itself.  These
................................................................................
  1733   1755   ** in NULL pointers.  All other values are in their UTF-8 zero-terminated
  1734   1756   ** string representation as returned by [sqlite3_column_text()].
  1735   1757   **
  1736   1758   ** A result table might consist of one or more memory allocations.
  1737   1759   ** It is not safe to pass a result table directly to [sqlite3_free()].
  1738   1760   ** A result table should be deallocated using [sqlite3_free_table()].
  1739   1761   **
  1740         -** As an example of the result table format, suppose a query result
         1762  +** ^(As an example of the result table format, suppose a query result
  1741   1763   ** is as follows:
  1742   1764   **
  1743   1765   ** <blockquote><pre>
  1744   1766   **        Name        | Age
  1745   1767   **        -----------------------
  1746   1768   **        Alice       | 43
  1747   1769   **        Bob         | 28
................................................................................
  1757   1779   **        azResult&#91;1] = "Age";
  1758   1780   **        azResult&#91;2] = "Alice";
  1759   1781   **        azResult&#91;3] = "43";
  1760   1782   **        azResult&#91;4] = "Bob";
  1761   1783   **        azResult&#91;5] = "28";
  1762   1784   **        azResult&#91;6] = "Cindy";
  1763   1785   **        azResult&#91;7] = "21";
  1764         -** </pre></blockquote>
         1786  +** </pre></blockquote>)^
  1765   1787   **
  1766   1788   ** ^The sqlite3_get_table() function evaluates one or more
  1767   1789   ** semicolon-separated SQL statements in the zero-terminated UTF-8
  1768   1790   ** string of its 2nd parameter and returns a result table to the
  1769   1791   ** pointer given in its 3rd parameter.
  1770   1792   **
  1771   1793   ** After the application has finished with the result from sqlite3_get_table(),
  1772         -** it should pass the result table pointer to sqlite3_free_table() in order to
         1794  +** it must pass the result table pointer to sqlite3_free_table() in order to
  1773   1795   ** release the memory that was malloced.  Because of the way the
  1774   1796   ** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
  1775   1797   ** function must not try to call [sqlite3_free()] directly.  Only
  1776   1798   ** [sqlite3_free_table()] is able to release the memory properly and safely.
  1777   1799   **
  1778         -** ^(The sqlite3_get_table() interface is implemented as a wrapper around
         1800  +** The sqlite3_get_table() interface is implemented as a wrapper around
  1779   1801   ** [sqlite3_exec()].  The sqlite3_get_table() routine does not have access
  1780   1802   ** to any internal data structures of SQLite.  It uses only the public
  1781   1803   ** interface defined here.  As a consequence, errors that occur in the
  1782   1804   ** wrapper layer outside of the internal [sqlite3_exec()] call are not
  1783   1805   ** reflected in subsequent calls to [sqlite3_errcode()] or
  1784         -** [sqlite3_errmsg()].)^
         1806  +** [sqlite3_errmsg()].
  1785   1807   */
  1786   1808   SQLITE_API int sqlite3_get_table(
  1787   1809     sqlite3 *db,          /* An open database */
  1788   1810     const char *zSql,     /* SQL to be evaluated */
  1789   1811     char ***pazResult,    /* Results of the query */
  1790   1812     int *pnRow,           /* Number of result rows written here */
  1791   1813     int *pnColumn,        /* Number of result columns written here */
................................................................................
  1929   1951   ** ^If M is the size of the prior allocation, then min(N,M) bytes
  1930   1952   ** of the prior allocation are copied into the beginning of buffer returned
  1931   1953   ** by sqlite3_realloc() and the prior allocation is freed.
  1932   1954   ** ^If sqlite3_realloc() returns NULL, then the prior allocation
  1933   1955   ** is not freed.
  1934   1956   **
  1935   1957   ** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
  1936         -** is always aligned to at least an 8 byte boundary.
         1958  +** is always aligned to at least an 8 byte boundary, or to a
         1959  +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
         1960  +** option is used.
  1937   1961   **
  1938   1962   ** In SQLite version 3.5.0 and 3.5.1, it was possible to define
  1939   1963   ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
  1940   1964   ** implementation of these routines to be omitted.  That capability
  1941   1965   ** is no longer provided.  Only built-in memory allocators can be used.
  1942   1966   **
  1943   1967   ** The Windows OS interface layer calls
................................................................................
  2187   2211   SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
  2188   2212   SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
  2189   2213      void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
  2190   2214   
  2191   2215   /*
  2192   2216   ** CAPI3REF: Query Progress Callbacks
  2193   2217   **
  2194         -** ^This routine configures a callback function - the
  2195         -** progress callback - that is invoked periodically during long
  2196         -** running calls to [sqlite3_exec()], [sqlite3_step()] and
  2197         -** [sqlite3_get_table()].  An example use for this
         2218  +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
         2219  +** function X to be invoked periodically during long running calls to
         2220  +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
         2221  +** database connection D.  An example use for this
  2198   2222   ** interface is to keep a GUI updated during a large query.
         2223  +**
         2224  +** ^The parameter P is passed through as the only parameter to the 
         2225  +** callback function X.  ^The parameter N is the number of 
         2226  +** [virtual machine instructions] that are evaluated between successive
         2227  +** invocations of the callback X.
         2228  +**
         2229  +** ^Only a single progress handler may be defined at one time per
         2230  +** [database connection]; setting a new progress handler cancels the
         2231  +** old one.  ^Setting parameter X to NULL disables the progress handler.
         2232  +** ^The progress handler is also disabled by setting N to a value less
         2233  +** than 1.
  2199   2234   **
  2200   2235   ** ^If the progress callback returns non-zero, the operation is
  2201   2236   ** interrupted.  This feature can be used to implement a
  2202   2237   ** "Cancel" button on a GUI progress dialog box.
  2203   2238   **
  2204         -** The progress handler must not do anything that will modify
         2239  +** The progress handler callback must not do anything that will modify
  2205   2240   ** the database connection that invoked the progress handler.
  2206   2241   ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
  2207   2242   ** database connections for the meaning of "modify" in this paragraph.
  2208   2243   **
  2209   2244   */
  2210   2245   SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
  2211   2246   
................................................................................
  2256   2291   ** it does not already exist. This is the behavior that is always used for
  2257   2292   ** sqlite3_open() and sqlite3_open16().</dd>)^
  2258   2293   ** </dl>
  2259   2294   **
  2260   2295   ** If the 3rd parameter to sqlite3_open_v2() is not one of the
  2261   2296   ** combinations shown above or one of the combinations shown above combined
  2262   2297   ** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
  2263         -** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
         2298  +** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_PRIVATECACHE] flags,
  2264   2299   ** then the behavior is undefined.
  2265   2300   **
  2266   2301   ** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
  2267   2302   ** opens in the multi-thread [threading mode] as long as the single-thread
  2268   2303   ** mode has not been set at compile-time or start-time.  ^If the
  2269   2304   ** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
  2270   2305   ** in the serialized [threading mode] unless single-thread was
................................................................................
  2381   2416   ** CAPI3REF: Run-time Limits
  2382   2417   **
  2383   2418   ** ^(This interface allows the size of various constructs to be limited
  2384   2419   ** on a connection by connection basis.  The first parameter is the
  2385   2420   ** [database connection] whose limit is to be set or queried.  The
  2386   2421   ** second parameter is one of the [limit categories] that define a
  2387   2422   ** class of constructs to be size limited.  The third parameter is the
  2388         -** new limit for that construct.  The function returns the old limit.)^
         2423  +** new limit for that construct.)^
  2389   2424   **
  2390   2425   ** ^If the new limit is a negative number, the limit is unchanged.
  2391         -** ^(For the limit category of SQLITE_LIMIT_XYZ there is a 
         2426  +** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a 
  2392   2427   ** [limits | hard upper bound]
  2393         -** set by a compile-time C preprocessor macro named 
  2394         -** [limits | SQLITE_MAX_XYZ].
         2428  +** set at compile-time by a C preprocessor macro called
         2429  +** [limits | SQLITE_MAX_<i>NAME</i>].
  2395   2430   ** (The "_LIMIT_" in the name is changed to "_MAX_".))^
  2396   2431   ** ^Attempts to increase a limit above its hard upper bound are
  2397   2432   ** silently truncated to the hard upper bound.
  2398   2433   **
         2434  +** ^Regardless of whether or not the limit was changed, the 
         2435  +** [sqlite3_limit()] interface returns the prior value of the limit.
         2436  +** ^Hence, to find the current value of a limit without changing it,
         2437  +** simply invoke this interface with the third parameter set to -1.
         2438  +**
  2399   2439   ** Run-time limits are intended for use in applications that manage
  2400   2440   ** both their own internal database and also databases that are controlled
  2401   2441   ** by untrusted external sources.  An example application might be a
  2402   2442   ** web browser that has its own databases for storing history and
  2403   2443   ** separate databases controlled by JavaScript applications downloaded
  2404   2444   ** off the Internet.  The internal databases can be given the
  2405   2445   ** large, default limits.  Databases managed by external sources can
................................................................................
  2420   2460   ** These constants define various performance limits
  2421   2461   ** that can be lowered at run-time using [sqlite3_limit()].
  2422   2462   ** The synopsis of the meanings of the various limits is shown below.
  2423   2463   ** Additional information is available at [limits | Limits in SQLite].
  2424   2464   **
  2425   2465   ** <dl>
  2426   2466   ** ^(<dt>SQLITE_LIMIT_LENGTH</dt>
  2427         -** <dd>The maximum size of any string or BLOB or table row.<dd>)^
         2467  +** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
  2428   2468   **
  2429   2469   ** ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
  2430   2470   ** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
  2431   2471   **
  2432   2472   ** ^(<dt>SQLITE_LIMIT_COLUMN</dt>
  2433   2473   ** <dd>The maximum number of columns in a table definition or in the
  2434   2474   ** result set of a [SELECT] or the maximum number of columns in an index
................................................................................
  2438   2478   ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
  2439   2479   **
  2440   2480   ** ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
  2441   2481   ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
  2442   2482   **
  2443   2483   ** ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
  2444   2484   ** <dd>The maximum number of instructions in a virtual machine program
  2445         -** used to implement an SQL statement.</dd>)^
         2485  +** used to implement an SQL statement.  This limit is not currently
         2486  +** enforced, though that might be added in some future release of
         2487  +** SQLite.</dd>)^
  2446   2488   **
  2447   2489   ** ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
  2448   2490   ** <dd>The maximum number of arguments on a function.</dd>)^
  2449   2491   **
  2450   2492   ** ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
  2451   2493   ** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
  2452   2494   **
  2453   2495   ** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
  2454   2496   ** <dd>The maximum length of the pattern argument to the [LIKE] or
  2455   2497   ** [GLOB] operators.</dd>)^
  2456   2498   **
  2457   2499   ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
  2458         -** <dd>The maximum number of variables in an SQL statement that can
  2459         -** be bound.</dd>)^
         2500  +** <dd>The maximum index number of any [parameter] in an SQL statement.)^
  2460   2501   **
  2461   2502   ** ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
  2462   2503   ** <dd>The maximum depth of recursion for triggers.</dd>)^
  2463   2504   ** </dl>
  2464   2505   */
  2465   2506   #define SQLITE_LIMIT_LENGTH                    0
  2466   2507   #define SQLITE_LIMIT_SQL_LENGTH                1
................................................................................
  2524   2565   ** original SQL text. This causes the [sqlite3_step()] interface to
  2525   2566   ** behave differently in three ways:
  2526   2567   **
  2527   2568   ** <ol>
  2528   2569   ** <li>
  2529   2570   ** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
  2530   2571   ** always used to do, [sqlite3_step()] will automatically recompile the SQL
  2531         -** statement and try to run it again.  ^If the schema has changed in
  2532         -** a way that makes the statement no longer valid, [sqlite3_step()] will still
  2533         -** return [SQLITE_SCHEMA].  But unlike the legacy behavior, [SQLITE_SCHEMA] is
  2534         -** now a fatal error.  Calling [sqlite3_prepare_v2()] again will not make the
  2535         -** error go away.  Note: use [sqlite3_errmsg()] to find the text
  2536         -** of the parsing error that results in an [SQLITE_SCHEMA] return.
         2572  +** statement and try to run it again.
  2537   2573   ** </li>
  2538   2574   **
  2539   2575   ** <li>
  2540   2576   ** ^When an error occurs, [sqlite3_step()] will return one of the detailed
  2541   2577   ** [error codes] or [extended error codes].  ^The legacy behavior was that
  2542   2578   ** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
  2543   2579   ** and the application would have to make a second call to [sqlite3_reset()]
  2544   2580   ** in order to find the underlying cause of the problem. With the "v2" prepare
  2545   2581   ** interfaces, the underlying reason for the error is returned immediately.
  2546   2582   ** </li>
  2547   2583   **
  2548   2584   ** <li>
  2549         -** ^If the value of a [parameter | host parameter] in the WHERE clause might
  2550         -** change the query plan for a statement, then the statement may be
  2551         -** automatically recompiled (as if there had been a schema change) on the first 
  2552         -** [sqlite3_step()] call following any change to the 
  2553         -** [sqlite3_bind_text | bindings] of the [parameter]. 
         2585  +** ^If the specific value bound to [parameter | host parameter] in the 
         2586  +** WHERE clause might influence the choice of query plan for a statement,
         2587  +** then the statement will be automatically recompiled, as if there had been 
         2588  +** a schema change, on the first  [sqlite3_step()] call following any change
         2589  +** to the [sqlite3_bind_text | bindings] of that [parameter]. 
         2590  +** ^The specific value of WHERE-clause [parameter] might influence the 
         2591  +** choice of query plan if the parameter is the left-hand side of a [LIKE]
         2592  +** or [GLOB] operator or if the parameter is compared to an indexed column
         2593  +** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
         2594  +** the 
  2554   2595   ** </li>
  2555   2596   ** </ol>
  2556   2597   */
  2557   2598   SQLITE_API int sqlite3_prepare(
  2558   2599     sqlite3 *db,            /* Database handle */
  2559   2600     const char *zSql,       /* SQL statement, UTF-8 encoded */
  2560   2601     int nByte,              /* Maximum length of zSql in bytes. */
................................................................................
  2613   2654   ** sqlite3_value object.  If SQLite is compiled to be single-threaded
  2614   2655   ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
  2615   2656   ** or if SQLite is run in one of reduced mutex modes 
  2616   2657   ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
  2617   2658   ** then there is no distinction between protected and unprotected
  2618   2659   ** sqlite3_value objects and they can be used interchangeably.  However,
  2619   2660   ** for maximum code portability it is recommended that applications
  2620         -** still make the distinction between between protected and unprotected
         2661  +** still make the distinction between protected and unprotected
  2621   2662   ** sqlite3_value objects even when not strictly required.
  2622   2663   **
  2623   2664   ** ^The sqlite3_value objects that are passed as parameters into the
  2624   2665   ** implementation of [application-defined SQL functions] are protected.
  2625   2666   ** ^The sqlite3_value object returned by
  2626   2667   ** [sqlite3_column_value()] is unprotected.
  2627   2668   ** Unprotected sqlite3_value objects may only be used with
................................................................................
  2659   2700   ** <li>  ?NNN
  2660   2701   ** <li>  :VVV
  2661   2702   ** <li>  @VVV
  2662   2703   ** <li>  $VVV
  2663   2704   ** </ul>
  2664   2705   **
  2665   2706   ** In the templates above, NNN represents an integer literal,
  2666         -** and VVV represents an alphanumeric identifer.)^  ^The values of these
         2707  +** and VVV represents an alphanumeric identifier.)^  ^The values of these
  2667   2708   ** parameters (also called "host parameter names" or "SQL parameters")
  2668   2709   ** can be set using the sqlite3_bind_*() routines defined here.
  2669   2710   **
  2670   2711   ** ^The first argument to the sqlite3_bind_*() routines is always
  2671   2712   ** a pointer to the [sqlite3_stmt] object returned from
  2672   2713   ** [sqlite3_prepare_v2()] or its variants.
  2673   2714   **
................................................................................
  2808   2849   
  2809   2850   /*
  2810   2851   ** CAPI3REF: Number Of Columns In A Result Set
  2811   2852   **
  2812   2853   ** ^Return the number of columns in the result set returned by the
  2813   2854   ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
  2814   2855   ** statement that does not return data (for example an [UPDATE]).
         2856  +**
         2857  +** See also: [sqlite3_data_count()]
  2815   2858   */
  2816   2859   SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
  2817   2860   
  2818   2861   /*
  2819   2862   ** CAPI3REF: Column Names In A Result Set
  2820   2863   **
  2821   2864   ** ^These routines return the name assigned to a particular column
................................................................................
  2998   3041   ** by sqlite3_step().  The use of the "v2" interface is recommended.
  2999   3042   */
  3000   3043   SQLITE_API int sqlite3_step(sqlite3_stmt*);
  3001   3044   
  3002   3045   /*
  3003   3046   ** CAPI3REF: Number of columns in a result set
  3004   3047   **
  3005         -** ^The sqlite3_data_count(P) the number of columns in the
  3006         -** of the result set of [prepared statement] P.
         3048  +** ^The sqlite3_data_count(P) interface returns the number of columns in the
         3049  +** current row of the result set of [prepared statement] P.
         3050  +** ^If prepared statement P does not have results ready to return
         3051  +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
         3052  +** interfaces) then sqlite3_data_count(P) returns 0.
         3053  +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
         3054  +**
         3055  +** See also: [sqlite3_column_count()]
  3007   3056   */
  3008   3057   SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
  3009   3058   
  3010   3059   /*
  3011   3060   ** CAPI3REF: Fundamental Datatypes
  3012   3061   ** KEYWORDS: SQLITE_TEXT
  3013   3062   **
................................................................................
  3079   3128   ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
  3080   3129   ** routine returns the number of bytes in that BLOB or string.
  3081   3130   ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
  3082   3131   ** the string to UTF-8 and then returns the number of bytes.
  3083   3132   ** ^If the result is a numeric value then sqlite3_column_bytes() uses
  3084   3133   ** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
  3085   3134   ** the number of bytes in that string.
  3086         -** ^The value returned does not include the zero terminator at the end
  3087         -** of the string.  ^For clarity: the value returned is the number of
         3135  +** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
         3136  +**
         3137  +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
         3138  +** routine returns the number of bytes in that BLOB or string.
         3139  +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
         3140  +** the string to UTF-16 and then returns the number of bytes.
         3141  +** ^If the result is a numeric value then sqlite3_column_bytes16() uses
         3142  +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
         3143  +** the number of bytes in that string.
         3144  +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
         3145  +**
         3146  +** ^The values returned by [sqlite3_column_bytes()] and 
         3147  +** [sqlite3_column_bytes16()] do not include the zero terminators at the end
         3148  +** of the string.  ^For clarity: the values returned by
         3149  +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
  3088   3150   ** bytes in the string, not the number of characters.
  3089   3151   **
  3090   3152   ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
  3091   3153   ** even empty strings, are always zero terminated.  ^The return
  3092         -** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
  3093         -** pointer, possibly even a NULL pointer.
  3094         -**
  3095         -** ^The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
  3096         -** but leaves the result in UTF-16 in native byte order instead of UTF-8.
  3097         -** ^The zero terminator is not included in this count.
         3154  +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
  3098   3155   **
  3099   3156   ** ^The object returned by [sqlite3_column_value()] is an
  3100   3157   ** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
  3101   3158   ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
  3102   3159   ** If the [unprotected sqlite3_value] object returned by
  3103   3160   ** [sqlite3_column_value()] is used in any other way, including calls
  3104   3161   ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
................................................................................
  3135   3192   **
  3136   3193   ** The table above makes reference to standard C library functions atoi()
  3137   3194   ** and atof().  SQLite does not really use these functions.  It has its
  3138   3195   ** own equivalent internal routines.  The atoi() and atof() names are
  3139   3196   ** used in the table for brevity and because they are familiar to most
  3140   3197   ** C programmers.
  3141   3198   **
  3142         -** ^Note that when type conversions occur, pointers returned by prior
         3199  +** Note that when type conversions occur, pointers returned by prior
  3143   3200   ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
  3144   3201   ** sqlite3_column_text16() may be invalidated.
  3145         -** ^(Type conversions and pointer invalidations might occur
         3202  +** Type conversions and pointer invalidations might occur
  3146   3203   ** in the following cases:
  3147   3204   **
  3148   3205   ** <ul>
  3149   3206   ** <li> The initial content is a BLOB and sqlite3_column_text() or
  3150   3207   **      sqlite3_column_text16() is called.  A zero-terminator might
  3151   3208   **      need to be added to the string.</li>
  3152   3209   ** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
  3153   3210   **      sqlite3_column_text16() is called.  The content must be converted
  3154   3211   **      to UTF-16.</li>
  3155   3212   ** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
  3156   3213   **      sqlite3_column_text() is called.  The content must be converted
  3157   3214   **      to UTF-8.</li>
  3158         -** </ul>)^
         3215  +** </ul>
  3159   3216   **
  3160   3217   ** ^Conversions between UTF-16be and UTF-16le are always done in place and do
  3161   3218   ** not invalidate a prior pointer, though of course the content of the buffer
  3162         -** that the prior pointer points to will have been modified.  Other kinds
         3219  +** that the prior pointer references will have been modified.  Other kinds
  3163   3220   ** of conversion are done in place when it is possible, but sometimes they
  3164   3221   ** are not possible and in those cases prior pointers are invalidated.
  3165   3222   **
  3166         -** ^(The safest and easiest to remember policy is to invoke these routines
         3223  +** The safest and easiest to remember policy is to invoke these routines
  3167   3224   ** in one of the following ways:
  3168   3225   **
  3169   3226   ** <ul>
  3170   3227   **  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
  3171   3228   **  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
  3172   3229   **  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
  3173         -** </ul>)^
         3230  +** </ul>
  3174   3231   **
  3175   3232   ** In other words, you should call sqlite3_column_text(),
  3176   3233   ** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
  3177   3234   ** into the desired format, then invoke sqlite3_column_bytes() or
  3178   3235   ** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
  3179   3236   ** to sqlite3_column_text() or sqlite3_column_blob() with calls to
  3180   3237   ** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
................................................................................
  3204   3261   SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
  3205   3262   SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
  3206   3263   
  3207   3264   /*
  3208   3265   ** CAPI3REF: Destroy A Prepared Statement Object
  3209   3266   **
  3210   3267   ** ^The sqlite3_finalize() function is called to delete a [prepared statement].
  3211         -** ^If the statement was executed successfully or not executed at all, then
  3212         -** SQLITE_OK is returned. ^If execution of the statement failed then an
  3213         -** [error code] or [extended error code] is returned.
         3268  +** ^If the most recent evaluation of the statement encountered no errors or
         3269  +** or if the statement is never been evaluated, then sqlite3_finalize() returns
         3270  +** SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
         3271  +** sqlite3_finalize(S) returns the appropriate [error code] or
         3272  +** [extended error code].
  3214   3273   **
  3215         -** ^This routine can be called at any point during the execution of the
  3216         -** [prepared statement].  ^If the virtual machine has not
  3217         -** completed execution when this routine is called, that is like
  3218         -** encountering an error or an [sqlite3_interrupt | interrupt].
  3219         -** ^Incomplete updates may be rolled back and transactions canceled,
  3220         -** depending on the circumstances, and the
  3221         -** [error code] returned will be [SQLITE_ABORT].
         3274  +** ^The sqlite3_finalize(S) routine can be called at any point during
         3275  +** the life cycle of [prepared statement] S:
         3276  +** before statement S is ever evaluated, after
         3277  +** one or more calls to [sqlite3_reset()], or after any call
         3278  +** to [sqlite3_step()] regardless of whether or not the statement has
         3279  +** completed execution.
         3280  +**
         3281  +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
         3282  +**
         3283  +** The application must finalize every [prepared statement] in order to avoid
         3284  +** resource leaks.  It is a grievous error for the application to try to use
         3285  +** a prepared statement after it has been finalized.  Any use of a prepared
         3286  +** statement after it has been finalized can result in undefined and
         3287  +** undesirable behavior such as segfaults and heap corruption.
  3222   3288   */
  3223   3289   SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
  3224   3290   
  3225   3291   /*
  3226   3292   ** CAPI3REF: Reset A Prepared Statement Object
  3227   3293   **
  3228   3294   ** The sqlite3_reset() function is called to reset a [prepared statement]
................................................................................
  3250   3316   
  3251   3317   /*
  3252   3318   ** CAPI3REF: Create Or Redefine SQL Functions
  3253   3319   ** KEYWORDS: {function creation routines}
  3254   3320   ** KEYWORDS: {application-defined SQL function}
  3255   3321   ** KEYWORDS: {application-defined SQL functions}
  3256   3322   **
  3257         -** ^These two functions (collectively known as "function creation routines")
         3323  +** ^These functions (collectively known as "function creation routines")
  3258   3324   ** are used to add SQL functions or aggregates or to redefine the behavior
  3259         -** of existing SQL functions or aggregates.  The only difference between the
  3260         -** two is that the second parameter, the name of the (scalar) function or
  3261         -** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
  3262         -** for sqlite3_create_function16().
         3325  +** of existing SQL functions or aggregates.  The only differences between
         3326  +** these routines are the text encoding expected for
         3327  +** the the second parameter (the name of the function being created)
         3328  +** and the presence or absence of a destructor callback for
         3329  +** the application data pointer.
  3263   3330   **
  3264   3331   ** ^The first parameter is the [database connection] to which the SQL
  3265   3332   ** function is to be added.  ^If an application uses more than one database
  3266   3333   ** connection then application-defined SQL functions must be added
  3267   3334   ** to each database connection separately.
  3268   3335   **
  3269         -** The second parameter is the name of the SQL function to be created or
  3270         -** redefined.  ^The length of the name is limited to 255 bytes, exclusive of
  3271         -** the zero-terminator.  Note that the name length limit is in bytes, not
  3272         -** characters.  ^Any attempt to create a function with a longer name
  3273         -** will result in [SQLITE_ERROR] being returned.
         3336  +** ^The second parameter is the name of the SQL function to be created or
         3337  +** redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
         3338  +** representation, exclusive of the zero-terminator.  ^Note that the name
         3339  +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.  
         3340  +** ^Any attempt to create a function with a longer name
         3341  +** will result in [SQLITE_MISUSE] being returned.
  3274   3342   **
  3275   3343   ** ^The third parameter (nArg)
  3276   3344   ** is the number of arguments that the SQL function or
  3277   3345   ** aggregate takes. ^If this parameter is -1, then the SQL function or
  3278   3346   ** aggregate may take any number of arguments between 0 and the limit
  3279   3347   ** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
  3280   3348   ** parameter is less than -1 or greater than 127 then the behavior is
  3281   3349   ** undefined.
  3282   3350   **
  3283         -** The fourth parameter, eTextRep, specifies what
         3351  +** ^The fourth parameter, eTextRep, specifies what
  3284   3352   ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
  3285         -** its parameters.  Any SQL function implementation should be able to work
  3286         -** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
         3353  +** its parameters.  Every SQL function implementation must be able to work
         3354  +** with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
  3287   3355   ** more efficient with one encoding than another.  ^An application may
  3288   3356   ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
  3289   3357   ** times with the same function but with different values of eTextRep.
  3290   3358   ** ^When multiple implementations of the same function are available, SQLite
  3291   3359   ** will pick the one that involves the least amount of data conversion.
  3292   3360   ** If there is only a single implementation which does not care what text
  3293   3361   ** encoding is used, then the fourth argument should be [SQLITE_ANY].
  3294   3362   **
  3295   3363   ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
  3296   3364   ** function can gain access to this pointer using [sqlite3_user_data()].)^
  3297   3365   **
  3298         -** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
         3366  +** ^The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
  3299   3367   ** pointers to C-language functions that implement the SQL function or
  3300   3368   ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
  3301         -** callback only; NULL pointers should be passed as the xStep and xFinal
         3369  +** callback only; NULL pointers must be passed as the xStep and xFinal
  3302   3370   ** parameters. ^An aggregate SQL function requires an implementation of xStep
  3303         -** and xFinal and NULL should be passed for xFunc. ^To delete an existing
  3304         -** SQL function or aggregate, pass NULL for all three function callbacks.
         3371  +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
         3372  +** SQL function or aggregate, pass NULL poiners for all three function
         3373  +** callbacks.
         3374  +**
         3375  +** ^If the tenth parameter to sqlite3_create_function_v2() is not NULL,
         3376  +** then it is invoked when the function is deleted, either by being
         3377  +** overloaded or when the database connection closes.
         3378  +** ^When the destructure callback of the tenth parameter is invoked, it
         3379  +** is passed a single argument which is a copy of the pointer which was
         3380  +** the fifth parameter to sqlite3_create_function_v2().
  3305   3381   **
  3306   3382   ** ^It is permitted to register multiple implementations of the same
  3307   3383   ** functions with the same name but with either differing numbers of
  3308   3384   ** arguments or differing preferred text encodings.  ^SQLite will use
  3309   3385   ** the implementation that most closely matches the way in which the
  3310   3386   ** SQL function is used.  ^A function implementation with a non-negative
  3311   3387   ** nArg parameter is a better match than a function implementation with
................................................................................
  3313   3389   ** matches the database encoding is a better
  3314   3390   ** match than a function where the encoding is different.  
  3315   3391   ** ^A function where the encoding difference is between UTF16le and UTF16be
  3316   3392   ** is a closer match than a function where the encoding difference is
  3317   3393   ** between UTF8 and UTF16.
  3318   3394   **
  3319   3395   ** ^Built-in functions may be overloaded by new application-defined functions.
  3320         -** ^The first application-defined function with a given name overrides all
  3321         -** built-in functions in the same [database connection] with the same name.
  3322         -** ^Subsequent application-defined functions of the same name only override 
  3323         -** prior application-defined functions that are an exact match for the
  3324         -** number of parameters and preferred encoding.
  3325   3396   **
  3326   3397   ** ^An application-defined function is permitted to call other
  3327   3398   ** SQLite interfaces.  However, such calls must not
  3328   3399   ** close the database connection nor finalize or reset the prepared
  3329   3400   ** statement in which the function is running.
  3330   3401   */
  3331   3402   SQLITE_API int sqlite3_create_function(
................................................................................
  3343   3414     const void *zFunctionName,
  3344   3415     int nArg,
  3345   3416     int eTextRep,
  3346   3417     void *pApp,
  3347   3418     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  3348   3419     void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  3349   3420     void (*xFinal)(sqlite3_context*)
         3421  +);
         3422  +SQLITE_API int sqlite3_create_function_v2(
         3423  +  sqlite3 *db,
         3424  +  const char *zFunctionName,
         3425  +  int nArg,
         3426  +  int eTextRep,
         3427  +  void *pApp,
         3428  +  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
         3429  +  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
         3430  +  void (*xFinal)(sqlite3_context*),
         3431  +  void(*xDestroy)(void*)
  3350   3432   );
  3351   3433   
  3352   3434   /*
  3353   3435   ** CAPI3REF: Text Encodings
  3354   3436   **
  3355   3437   ** These constant define integer codes that represent the various
  3356   3438   ** text encodings supported by SQLite.
................................................................................
  3438   3520   SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
  3439   3521   SQLITE_API int sqlite3_value_type(sqlite3_value*);
  3440   3522   SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
  3441   3523   
  3442   3524   /*
  3443   3525   ** CAPI3REF: Obtain Aggregate Function Context
  3444   3526   **
  3445         -** Implementions of aggregate SQL functions use this
         3527  +** Implementations of aggregate SQL functions use this
  3446   3528   ** routine to allocate memory for storing their state.
  3447   3529   **
  3448   3530   ** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
  3449   3531   ** for a particular aggregate function, SQLite
  3450   3532   ** allocates N of memory, zeroes out that memory, and returns a pointer
  3451   3533   ** to the new memory. ^On second and subsequent calls to
  3452   3534   ** sqlite3_aggregate_context() for the same aggregate function instance,
................................................................................
  3690   3772   SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
  3691   3773   SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
  3692   3774   SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
  3693   3775   
  3694   3776   /*
  3695   3777   ** CAPI3REF: Define New Collating Sequences
  3696   3778   **
  3697         -** These functions are used to add new collation sequences to the
  3698         -** [database connection] specified as the first argument.
         3779  +** ^These functions add, remove, or modify a [collation] associated
         3780  +** with the [database connection] specified as the first argument.
  3699   3781   **
  3700         -** ^The name of the new collation sequence is specified as a UTF-8 string
         3782  +** ^The name of the collation is a UTF-8 string
  3701   3783   ** for sqlite3_create_collation() and sqlite3_create_collation_v2()
  3702         -** and a UTF-16 string for sqlite3_create_collation16(). ^In all cases
  3703         -** the name is passed as the second function argument.
  3704         -**
  3705         -** ^The third argument may be one of the constants [SQLITE_UTF8],
  3706         -** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied
  3707         -** routine expects to be passed pointers to strings encoded using UTF-8,
  3708         -** UTF-16 little-endian, or UTF-16 big-endian, respectively. ^The
  3709         -** third argument might also be [SQLITE_UTF16] to indicate that the routine
  3710         -** expects pointers to be UTF-16 strings in the native byte order, or the
  3711         -** argument can be [SQLITE_UTF16_ALIGNED] if the
  3712         -** the routine expects pointers to 16-bit word aligned strings
  3713         -** of UTF-16 in the native byte order.
  3714         -**
  3715         -** A pointer to the user supplied routine must be passed as the fifth
  3716         -** argument.  ^If it is NULL, this is the same as deleting the collation
  3717         -** sequence (so that SQLite cannot call it anymore).
  3718         -** ^Each time the application supplied function is invoked, it is passed
  3719         -** as its first parameter a copy of the void* passed as the fourth argument
  3720         -** to sqlite3_create_collation() or sqlite3_create_collation16().
  3721         -**
  3722         -** ^The remaining arguments to the application-supplied routine are two strings,
  3723         -** each represented by a (length, data) pair and encoded in the encoding
  3724         -** that was passed as the third argument when the collation sequence was
  3725         -** registered.  The application defined collation routine should
  3726         -** return negative, zero or positive if the first string is less than,
  3727         -** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
         3784  +** and a UTF-16 string in native byte order for sqlite3_create_collation16().
         3785  +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
         3786  +** considered to be the same name.
         3787  +**
         3788  +** ^(The third argument (eTextRep) must be one of the constants:
         3789  +** <ul>
         3790  +** <li> [SQLITE_UTF8],
         3791  +** <li> [SQLITE_UTF16LE],
         3792  +** <li> [SQLITE_UTF16BE],
         3793  +** <li> [SQLITE_UTF16], or
         3794  +** <li> [SQLITE_UTF16_ALIGNED].
         3795  +** </ul>)^
         3796  +** ^The eTextRep argument determines the encoding of strings passed
         3797  +** to the collating function callback, xCallback.
         3798  +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
         3799  +** force strings to be UTF16 with native byte order.
         3800  +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
         3801  +** on an even byte address.
         3802  +**
         3803  +** ^The fourth argument, pArg, is a application data pointer that is passed
         3804  +** through as the first argument to the collating function callback.
         3805  +**
         3806  +** ^The fifth argument, xCallback, is a pointer to the collating function.
         3807  +** ^Multiple collating functions can be registered using the same name but
         3808  +** with different eTextRep parameters and SQLite will use whichever
         3809  +** function requires the least amount of data transformation.
         3810  +** ^If the xCallback argument is NULL then the collating function is
         3811  +** deleted.  ^When all collating functions having the same name are deleted,
         3812  +** that collation is no longer usable.
         3813  +**
         3814  +** ^The collating function callback is invoked with a copy of the pArg 
         3815  +** application data pointer and with two strings in the encoding specified
         3816  +** by the eTextRep argument.  The collating function must return an
         3817  +** integer that is negative, zero, or positive
         3818  +** if the first string is less than, equal to, or greater than the second,
         3819  +** respectively.  A collating function must alway return the same answer
         3820  +** given the same inputs.  If two or more collating functions are registered
         3821  +** to the same collation name (using different eTextRep values) then all
         3822  +** must give an equivalent answer when invoked with equivalent strings.
         3823  +** The collating function must obey the following properties for all
         3824  +** strings A, B, and C:
         3825  +**
         3826  +** <ol>
         3827  +** <li> If A==B then B==A.
         3828  +** <li> If A==B and B==C then A==C.
         3829  +** <li> If A&lt;B THEN B&gt;A.
         3830  +** <li> If A&lt;B and B&lt;C then A&lt;C.
         3831  +** </ol>
         3832  +**
         3833  +** If a collating function fails any of the above constraints and that
         3834  +** collating function is  registered and used, then the behavior of SQLite
         3835  +** is undefined.
  3728   3836   **
  3729   3837   ** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
  3730         -** except that it takes an extra argument which is a destructor for
  3731         -** the collation.  ^The destructor is called when the collation is
  3732         -** destroyed and is passed a copy of the fourth parameter void* pointer
  3733         -** of the sqlite3_create_collation_v2().
  3734         -** ^Collations are destroyed when they are overridden by later calls to the
  3735         -** collation creation functions or when the [database connection] is closed
  3736         -** using [sqlite3_close()].
         3838  +** with the addition that the xDestroy callback is invoked on pArg when
         3839  +** the collating function is deleted.
         3840  +** ^Collating functions are deleted when they are overridden by later
         3841  +** calls to the collation creation functions or when the
         3842  +** [database connection] is closed using [sqlite3_close()].
  3737   3843   **
  3738   3844   ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
  3739   3845   */
  3740   3846   SQLITE_API int sqlite3_create_collation(
  3741   3847     sqlite3*, 
  3742   3848     const char *zName, 
  3743   3849     int eTextRep, 
  3744         -  void*,
         3850  +  void *pArg,
  3745   3851     int(*xCompare)(void*,int,const void*,int,const void*)
  3746   3852   );
  3747   3853   SQLITE_API int sqlite3_create_collation_v2(
  3748   3854     sqlite3*, 
  3749   3855     const char *zName, 
  3750   3856     int eTextRep, 
  3751         -  void*,
         3857  +  void *pArg,
  3752   3858     int(*xCompare)(void*,int,const void*,int,const void*),
  3753   3859     void(*xDestroy)(void*)
  3754   3860   );
  3755   3861   SQLITE_API int sqlite3_create_collation16(
  3756   3862     sqlite3*, 
  3757   3863     const void *zName,
  3758   3864     int eTextRep, 
  3759         -  void*,
         3865  +  void *pArg,
  3760   3866     int(*xCompare)(void*,int,const void*,int,const void*)
  3761   3867   );
  3762   3868   
  3763   3869   /*
  3764   3870   ** CAPI3REF: Collation Needed Callbacks
  3765   3871   **
  3766   3872   ** ^To avoid having to register all collation sequences before a database
................................................................................
  3841   3947     const char *zPassPhrase        /* Activation phrase */
  3842   3948   );
  3843   3949   #endif
  3844   3950   
  3845   3951   /*
  3846   3952   ** CAPI3REF: Suspend Execution For A Short Time
  3847   3953   **
  3848         -** ^The sqlite3_sleep() function causes the current thread to suspend execution
         3954  +** The sqlite3_sleep() function causes the current thread to suspend execution
  3849   3955   ** for at least a number of milliseconds specified in its parameter.
  3850   3956   **
  3851         -** ^If the operating system does not support sleep requests with
         3957  +** If the operating system does not support sleep requests with
  3852   3958   ** millisecond time resolution, then the time will be rounded up to
  3853         -** the nearest second. ^The number of milliseconds of sleep actually
         3959  +** the nearest second. The number of milliseconds of sleep actually
  3854   3960   ** requested from the operating system is returned.
  3855   3961   **
  3856   3962   ** ^SQLite implements this interface by calling the xSleep()
  3857         -** method of the default [sqlite3_vfs] object.
         3963  +** method of the default [sqlite3_vfs] object.  If the xSleep() method
         3964  +** of the default VFS is not implemented correctly, or not implemented at
         3965  +** all, then the behavior of sqlite3_sleep() may deviate from the description
         3966  +** in the previous paragraphs.
  3858   3967   */
  3859   3968   SQLITE_API int sqlite3_sleep(int);
  3860   3969   
  3861   3970   /*
  3862   3971   ** CAPI3REF: Name Of The Folder Holding Temporary Files
  3863   3972   **
  3864   3973   ** ^(If this global variable is made to point to a string which is
................................................................................
  4072   4181   **
  4073   4182   ** ^The sqlite3_release_memory() interface attempts to free N bytes
  4074   4183   ** of heap memory by deallocating non-essential memory allocations
  4075   4184   ** held by the database library.   Memory used to cache database
  4076   4185   ** pages to improve performance is an example of non-essential memory.
  4077   4186   ** ^sqlite3_release_memory() returns the number of bytes actually freed,
  4078   4187   ** which might be more or less than the amount requested.
         4188  +** ^The sqlite3_release_memory() routine is a no-op returning zero
         4189  +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
  4079   4190   */
  4080   4191   SQLITE_API int sqlite3_release_memory(int);
  4081   4192   
  4082   4193   /*
  4083   4194   ** CAPI3REF: Impose A Limit On Heap Size
  4084   4195   **
  4085         -** ^The sqlite3_soft_heap_limit() interface places a "soft" limit
  4086         -** on the amount of heap memory that may be allocated by SQLite.
  4087         -** ^If an internal allocation is requested that would exceed the
  4088         -** soft heap limit, [sqlite3_release_memory()] is invoked one or
  4089         -** more times to free up some space before the allocation is performed.
  4090         -**
  4091         -** ^The limit is called "soft" because if [sqlite3_release_memory()]
  4092         -** cannot free sufficient memory to prevent the limit from being exceeded,
  4093         -** the memory is allocated anyway and the current operation proceeds.
  4094         -**
  4095         -** ^A negative or zero value for N means that there is no soft heap limit and
  4096         -** [sqlite3_release_memory()] will only be called when memory is exhausted.
  4097         -** ^The default value for the soft heap limit is zero.
  4098         -**
  4099         -** ^(SQLite makes a best effort to honor the soft heap limit.
  4100         -** But if the soft heap limit cannot be honored, execution will
  4101         -** continue without error or notification.)^  This is why the limit is
  4102         -** called a "soft" limit.  It is advisory only.
  4103         -**
  4104         -** Prior to SQLite version 3.5.0, this routine only constrained the memory
  4105         -** allocated by a single thread - the same thread in which this routine
  4106         -** runs.  Beginning with SQLite version 3.5.0, the soft heap limit is
  4107         -** applied to all threads. The value specified for the soft heap limit
  4108         -** is an upper bound on the total memory allocation for all threads. In
  4109         -** version 3.5.0 there is no mechanism for limiting the heap usage for
  4110         -** individual threads.
  4111         -*/
  4112         -SQLITE_API void sqlite3_soft_heap_limit(int);
         4196  +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
         4197  +** soft limit on the amount of heap memory that may be allocated by SQLite.
         4198  +** ^SQLite strives to keep heap memory utilization below the soft heap
         4199  +** limit by reducing the number of pages held in the page cache
         4200  +** as heap memory usages approaches the limit.
         4201  +** ^The soft heap limit is "soft" because even though SQLite strives to stay
         4202  +** below the limit, it will exceed the limit rather than generate
         4203  +** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
         4204  +** is advisory only.
         4205  +**
         4206  +** ^The return value from sqlite3_soft_heap_limit64() is the size of
         4207  +** the soft heap limit prior to the call.  ^If the argument N is negative
         4208  +** then no change is made to the soft heap limit.  Hence, the current
         4209  +** size of the soft heap limit can be determined by invoking
         4210  +** sqlite3_soft_heap_limit64() with a negative argument.
         4211  +**
         4212  +** ^If the argument N is zero then the soft heap limit is disabled.
         4213  +**
         4214  +** ^(The soft heap limit is not enforced in the current implementation
         4215  +** if one or more of following conditions are true:
         4216  +**
         4217  +** <ul>
         4218  +** <li> The soft heap limit is set to zero.
         4219  +** <li> Memory accounting is disabled using a combination of the
         4220  +**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
         4221  +**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
         4222  +** <li> An alternative page cache implementation is specifed using
         4223  +**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
         4224  +** <li> The page cache allocates from its own memory pool supplied
         4225  +**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
         4226  +**      from the heap.
         4227  +** </ul>)^
         4228  +**
         4229  +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
         4230  +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
         4231  +** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
         4232  +** the soft heap limit is enforced on every memory allocation.  Without
         4233  +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
         4234  +** when memory is allocated by the page cache.  Testing suggests that because
         4235  +** the page cache is the predominate memory user in SQLite, most
         4236  +** applications will achieve adequate soft heap limit enforcement without
         4237  +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
         4238  +**
         4239  +** The circumstances under which SQLite will enforce the soft heap limit may
         4240  +** changes in future releases of SQLite.
         4241  +*/
         4242  +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
         4243  +
         4244  +/*
         4245  +** CAPI3REF: Deprecated Soft Heap Limit Interface
         4246  +** DEPRECATED
         4247  +**
         4248  +** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
         4249  +** interface.  This routine is provided for historical compatibility
         4250  +** only.  All new applications should use the
         4251  +** [sqlite3_soft_heap_limit64()] interface rather than this one.
         4252  +*/
         4253  +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
         4254  +
  4113   4255   
  4114   4256   /*
  4115   4257   ** CAPI3REF: Extract Metadata About A Column Of A Table
  4116   4258   **
  4117   4259   ** ^This routine returns metadata about a specific column of a specific
  4118   4260   ** database table accessible using the [database connection] handle
  4119   4261   ** passed as the first function argument.
................................................................................
  4229   4371   ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
  4230   4372   ** to turn extension loading on and call it with onoff==0 to turn
  4231   4373   ** it back off again.
  4232   4374   */
  4233   4375   SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
  4234   4376   
  4235   4377   /*
  4236         -** CAPI3REF: Automatically Load An Extensions
  4237         -**
  4238         -** ^This API can be invoked at program startup in order to register
  4239         -** one or more statically linked extensions that will be available
  4240         -** to all new [database connections].
  4241         -**
  4242         -** ^(This routine stores a pointer to the extension entry point
  4243         -** in an array that is obtained from [sqlite3_malloc()].  That memory
  4244         -** is deallocated by [sqlite3_reset_auto_extension()].)^
  4245         -**
  4246         -** ^This function registers an extension entry point that is
  4247         -** automatically invoked whenever a new [database connection]
  4248         -** is opened using [sqlite3_open()], [sqlite3_open16()],
  4249         -** or [sqlite3_open_v2()].
  4250         -** ^Duplicate extensions are detected so calling this routine
  4251         -** multiple times with the same extension is harmless.
  4252         -** ^Automatic extensions apply across all threads.
         4378  +** CAPI3REF: Automatically Load Statically Linked Extensions
         4379  +**
         4380  +** ^This interface causes the xEntryPoint() function to be invoked for
         4381  +** each new [database connection] that is created.  The idea here is that
         4382  +** xEntryPoint() is the entry point for a statically linked SQLite extension
         4383  +** that is to be automatically loaded into all new database connections.
         4384  +**
         4385  +** ^(Even though the function prototype shows that xEntryPoint() takes
         4386  +** no arguments and returns void, SQLite invokes xEntryPoint() with three
         4387  +** arguments and expects and integer result as if the signature of the
         4388  +** entry point where as follows:
         4389  +**
         4390  +** <blockquote><pre>
         4391  +** &nbsp;  int xEntryPoint(
         4392  +** &nbsp;    sqlite3 *db,
         4393  +** &nbsp;    const char **pzErrMsg,
         4394  +** &nbsp;    const struct sqlite3_api_routines *pThunk
         4395  +** &nbsp;  );
         4396  +** </pre></blockquote>)^
         4397  +**
         4398  +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
         4399  +** point to an appropriate error message (obtained from [sqlite3_mprintf()])
         4400  +** and return an appropriate [error code].  ^SQLite ensures that *pzErrMsg
         4401  +** is NULL before calling the xEntryPoint().  ^SQLite will invoke
         4402  +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns.  ^If any
         4403  +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
         4404  +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
         4405  +**
         4406  +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
         4407  +** on the list of automatic extensions is a harmless no-op. ^No entry point
         4408  +** will be called more than once for each database connection that is opened.
         4409  +**
         4410  +** See also: [sqlite3_reset_auto_extension()].
  4253   4411   */
  4254   4412   SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
  4255   4413   
  4256   4414   /*
  4257   4415   ** CAPI3REF: Reset Automatic Extension Loading
  4258   4416   **
  4259         -** ^(This function disables all previously registered automatic
  4260         -** extensions. It undoes the effect of all prior
  4261         -** [sqlite3_auto_extension()] calls.)^
  4262         -**
  4263         -** ^This function disables automatic extensions in all threads.
         4417  +** ^This interface disables all automatic extensions previously
         4418  +** registered using [sqlite3_auto_extension()].
  4264   4419   */
  4265   4420   SQLITE_API void sqlite3_reset_auto_extension(void);
  4266   4421   
  4267   4422   /*
  4268   4423   ** The interface to the virtual-table mechanism is currently considered
  4269   4424   ** to be experimental.  The interface might change in incompatible ways.
  4270   4425   ** If this is a problem for you, do not use the interface at this time.
................................................................................
  4895   5050   ** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
  4896   5051   ** Additionally, an instance of this structure can be used as an
  4897   5052   ** output variable when querying the system for the current mutex
  4898   5053   ** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
  4899   5054   **
  4900   5055   ** ^The xMutexInit method defined by this structure is invoked as
  4901   5056   ** part of system initialization by the sqlite3_initialize() function.
  4902         -** ^The xMutexInit routine is calle by SQLite exactly once for each
         5057  +** ^The xMutexInit routine is called by SQLite exactly once for each
  4903   5058   ** effective call to [sqlite3_initialize()].
  4904   5059   **
  4905   5060   ** ^The xMutexEnd method defined by this structure is invoked as
  4906   5061   ** part of system shutdown by the sqlite3_shutdown() function. The
  4907   5062   ** implementation of this method is expected to release all outstanding
  4908   5063   ** resources obtained by the mutex methods implementation, especially
  4909   5064   ** those obtained by the xMutexInit method.  ^The xMutexEnd()
................................................................................
  4928   5083   ** of a valid mutex handle. The implementations of the methods defined
  4929   5084   ** by this structure are not required to handle this case, the results
  4930   5085   ** of passing a NULL pointer instead of a valid mutex handle are undefined
  4931   5086   ** (i.e. it is acceptable to provide an implementation that segfaults if
  4932   5087   ** it is passed a NULL pointer).
  4933   5088   **
  4934   5089   ** The xMutexInit() method must be threadsafe.  ^It must be harmless to
  4935         -** invoke xMutexInit() mutiple times within the same process and without
         5090  +** invoke xMutexInit() multiple times within the same process and without
  4936   5091   ** intervening calls to xMutexEnd().  Second and subsequent calls to
  4937   5092   ** xMutexInit() must be no-ops.
  4938   5093   **
  4939   5094   ** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
  4940   5095   ** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
  4941   5096   ** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
  4942   5097   ** memory allocation for a fast or recursive mutex.
................................................................................
  5092   5247   #define SQLITE_TESTCTRL_PENDING_BYTE            11
  5093   5248   #define SQLITE_TESTCTRL_ASSERT                  12
  5094   5249   #define SQLITE_TESTCTRL_ALWAYS                  13
  5095   5250   #define SQLITE_TESTCTRL_RESERVE                 14
  5096   5251   #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
  5097   5252   #define SQLITE_TESTCTRL_ISKEYWORD               16
  5098   5253   #define SQLITE_TESTCTRL_PGHDRSZ                 17
  5099         -#define SQLITE_TESTCTRL_LAST                    17
         5254  +#define SQLITE_TESTCTRL_SCRATCHMALLOC           18
         5255  +#define SQLITE_TESTCTRL_LAST                    18
  5100   5256   
  5101   5257   /*
  5102   5258   ** CAPI3REF: SQLite Runtime Status
  5103   5259   **
  5104   5260   ** ^This interface is used to retrieve runtime status information
  5105         -** about the preformance of SQLite, and optionally to reset various
         5261  +** about the performance of SQLite, and optionally to reset various
  5106   5262   ** highwater marks.  ^The first argument is an integer code for
  5107   5263   ** the specific parameter to measure.  ^(Recognized integer codes
  5108   5264   ** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^
  5109   5265   ** ^The current value of the parameter is returned into *pCurrent.
  5110   5266   ** ^The highest recorded value is returned in *pHighwater.  ^If the
  5111   5267   ** resetFlag is true, then the highest record value is reset after
  5112   5268   ** *pHighwater is written.  ^(Some parameters do not record the highest
  5113   5269   ** value.  For those parameters
  5114   5270   ** nothing is written into *pHighwater and the resetFlag is ignored.)^
  5115   5271   ** ^(Other parameters record only the highwater mark and not the current
  5116   5272   ** value.  For these latter parameters nothing is written into *pCurrent.)^
  5117   5273   **
  5118         -** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
         5274  +** ^The sqlite3_status() routine returns SQLITE_OK on success and a
  5119   5275   ** non-zero [error code] on failure.
  5120   5276   **
  5121   5277   ** This routine is threadsafe but is not atomic.  This routine can be
  5122   5278   ** called while other threads are running the same or different SQLite
  5123   5279   ** interfaces.  However the values returned in *pCurrent and
  5124   5280   ** *pHighwater reflect the status of SQLite at different points in time
  5125   5281   ** and it is possible that another thread might change the parameter
................................................................................
  5161   5317   ** <dd>This parameter returns the number of pages used out of the
  5162   5318   ** [pagecache memory allocator] that was configured using 
  5163   5319   ** [SQLITE_CONFIG_PAGECACHE].  The
  5164   5320   ** value returned is in pages, not in bytes.</dd>)^
  5165   5321   **
  5166   5322   ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
  5167   5323   ** <dd>This parameter returns the number of bytes of page cache
  5168         -** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
         5324  +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
  5169   5325   ** buffer and where forced to overflow to [sqlite3_malloc()].  The
  5170   5326   ** returned value includes allocations that overflowed because they
  5171   5327   ** where too large (they were larger than the "sz" parameter to
  5172   5328   ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
  5173   5329   ** no space was left in the page cache.</dd>)^
  5174   5330   **
  5175   5331   ** ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
................................................................................
  5184   5340   ** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
  5185   5341   ** in bytes.  Since a single thread may only have one scratch allocation
  5186   5342   ** outstanding at time, this parameter also reports the number of threads
  5187   5343   ** using scratch memory at the same time.</dd>)^
  5188   5344   **
  5189   5345   ** ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
  5190   5346   ** <dd>This parameter returns the number of bytes of scratch memory
  5191         -** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
         5347  +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
  5192   5348   ** buffer and where forced to overflow to [sqlite3_malloc()].  The values
  5193   5349   ** returned include overflows because the requested allocation was too
  5194   5350   ** larger (that is, because the requested allocation was larger than the
  5195   5351   ** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
  5196   5352   ** slots were available.
  5197   5353   ** </dd>)^
  5198   5354   **
................................................................................
  5224   5380   ** CAPI3REF: Database Connection Status
  5225   5381   **
  5226   5382   ** ^This interface is used to retrieve runtime status information 
  5227   5383   ** about a single [database connection].  ^The first argument is the
  5228   5384   ** database connection object to be interrogated.  ^The second argument
  5229   5385   ** is an integer constant, taken from the set of
  5230   5386   ** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros, that
  5231         -** determiness the parameter to interrogate.  The set of 
         5387  +** determines the parameter to interrogate.  The set of 
  5232   5388   ** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros is likely
  5233   5389   ** to grow in future releases of SQLite.
  5234   5390   **
  5235   5391   ** ^The current value of the requested parameter is written into *pCur
  5236   5392   ** and the highest instantaneous value is written into *pHiwtr.  ^If
  5237   5393   ** the resetFlg is true, then the highest instantaneous value is
  5238   5394   ** reset back down to the current value.
         5395  +**
         5396  +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
         5397  +** non-zero [error code] on failure.
  5239   5398   **
  5240   5399   ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
  5241   5400   */
  5242   5401   SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
  5243   5402   
  5244   5403   /*
  5245   5404   ** CAPI3REF: Status Parameters for database connections
................................................................................
  5359   5518   
  5360   5519   /*
  5361   5520   ** CAPI3REF: Application Defined Page Cache.
  5362   5521   ** KEYWORDS: {page cache}
  5363   5522   **
  5364   5523   ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
  5365   5524   ** register an alternative page cache implementation by passing in an 
  5366         -** instance of the sqlite3_pcache_methods structure.)^ The majority of the 
  5367         -** heap memory used by SQLite is used by the page cache to cache data read 
  5368         -** from, or ready to be written to, the database file. By implementing a 
  5369         -** custom page cache using this API, an application can control more 
  5370         -** precisely the amount of memory consumed by SQLite, the way in which 
         5525  +** instance of the sqlite3_pcache_methods structure.)^
         5526  +** In many applications, most of the heap memory allocated by 
         5527  +** SQLite is used for the page cache.
         5528  +** By implementing a 
         5529  +** custom page cache using this API, an application can better control
         5530  +** the amount of memory consumed by SQLite, the way in which 
  5371   5531   ** that memory is allocated and released, and the policies used to 
  5372   5532   ** determine exactly which parts of a database file are cached and for 
  5373   5533   ** how long.
  5374   5534   **
         5535  +** The alternative page cache mechanism is an
         5536  +** extreme measure that is only needed by the most demanding applications.
         5537  +** The built-in page cache is recommended for most uses.
         5538  +**
  5375   5539   ** ^(The contents of the sqlite3_pcache_methods structure are copied to an
  5376   5540   ** internal buffer by SQLite within the call to [sqlite3_config].  Hence
  5377   5541   ** the application may discard the parameter after the call to
  5378   5542   ** [sqlite3_config()] returns.)^
  5379   5543   **
  5380         -** ^The xInit() method is called once for each call to [sqlite3_initialize()]
         5544  +** ^(The xInit() method is called once for each effective 
         5545  +** call to [sqlite3_initialize()])^
  5381   5546   ** (usually only once during the lifetime of the process). ^(The xInit()
  5382   5547   ** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^
  5383         -** ^The xInit() method can set up up global structures and/or any mutexes
         5548  +** The intent of the xInit() method is to set up global data structures 
  5384   5549   ** required by the custom page cache implementation. 
         5550  +** ^(If the xInit() method is NULL, then the 
         5551  +** built-in default page cache is used instead of the application defined
         5552  +** page cache.)^
  5385   5553   **
  5386         -** ^The xShutdown() method is called from within [sqlite3_shutdown()], 
  5387         -** if the application invokes this API. It can be used to clean up 
         5554  +** ^The xShutdown() method is called by [sqlite3_shutdown()].
         5555  +** It can be used to clean up 
  5388   5556   ** any outstanding resources before process shutdown, if required.
         5557  +** ^The xShutdown() method may be NULL.
  5389   5558   **
  5390         -** ^SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
  5391         -** the xInit method, so the xInit method need not be threadsafe.  ^The
         5559  +** ^SQLite automatically serializes calls to the xInit method,
         5560  +** so the xInit method need not be threadsafe.  ^The
  5392   5561   ** xShutdown method is only called from [sqlite3_shutdown()] so it does
  5393   5562   ** not need to be threadsafe either.  All other methods must be threadsafe
  5394   5563   ** in multithreaded applications.
  5395   5564   **
  5396   5565   ** ^SQLite will never invoke xInit() more than once without an intervening
  5397   5566   ** call to xShutdown().
  5398   5567   **
  5399         -** ^The xCreate() method is used to construct a new cache instance.  SQLite
  5400         -** will typically create one cache instance for each open database file,
         5568  +** ^SQLite invokes the xCreate() method to construct a new cache instance.
         5569  +** SQLite will typically create one cache instance for each open database file,
  5401   5570   ** though this is not guaranteed. ^The
  5402   5571   ** first parameter, szPage, is the size in bytes of the pages that must
  5403   5572   ** be allocated by the cache.  ^szPage will not be a power of two.  ^szPage
  5404   5573   ** will the page size of the database file that is to be cached plus an
  5405         -** increment (here called "R") of about 100 or 200.  ^SQLite will use the
         5574  +** increment (here called "R") of about 100 or 200.  SQLite will use the
  5406   5575   ** extra R bytes on each page to store metadata about the underlying
  5407   5576   ** database page on disk.  The value of R depends
  5408   5577   ** on the SQLite version, the target platform, and how SQLite was compiled.
  5409   5578   ** ^R is constant for a particular build of SQLite.  ^The second argument to
  5410   5579   ** xCreate(), bPurgeable, is true if the cache being created will
  5411   5580   ** be used to cache database pages of a file stored on disk, or
  5412         -** false if it is used for an in-memory database. ^The cache implementation
         5581  +** false if it is used for an in-memory database. The cache implementation
  5413   5582   ** does not have to do anything special based with the value of bPurgeable;
  5414   5583   ** it is purely advisory.  ^On a cache where bPurgeable is false, SQLite will
  5415   5584   ** never invoke xUnpin() except to deliberately delete a page.
  5416         -** ^In other words, a cache created with bPurgeable set to false will
         5585  +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
         5586  +** false will always have the "discard" flag set to true.  
         5587  +** ^Hence, a cache created with bPurgeable false will
  5417   5588   ** never contain any unpinned pages.
  5418   5589   **
  5419   5590   ** ^(The xCachesize() method may be called at any time by SQLite to set the
  5420   5591   ** suggested maximum cache-size (number of pages stored by) the cache
  5421   5592   ** instance passed as the first argument. This is the value configured using
  5422         -** the SQLite "[PRAGMA cache_size]" command.)^  ^As with the bPurgeable
         5593  +** the SQLite "[PRAGMA cache_size]" command.)^  As with the bPurgeable
  5423   5594   ** parameter, the implementation is not required to do anything with this
  5424   5595   ** value; it is advisory only.
  5425   5596   **
  5426         -** ^The xPagecount() method should return the number of pages currently
  5427         -** stored in the cache.
         5597  +** The xPagecount() method must return the number of pages currently
         5598  +** stored in the cache, both pinned and unpinned.
  5428   5599   ** 
  5429         -** ^The xFetch() method is used to fetch a page and return a pointer to it. 
  5430         -** ^A 'page', in this context, is a buffer of szPage bytes aligned at an
  5431         -** 8-byte boundary. ^The page to be fetched is determined by the key. ^The
  5432         -** mimimum key value is 1. After it has been retrieved using xFetch, the page 
         5600  +** The xFetch() method locates a page in the cache and returns a pointer to 
         5601  +** the page, or a NULL pointer.
         5602  +** A "page", in this context, means a buffer of szPage bytes aligned at an
         5603  +** 8-byte boundary. The page to be fetched is determined by the key. ^The
         5604  +** mimimum key value is 1.  After it has been retrieved using xFetch, the page 
  5433   5605   ** is considered to be "pinned".
  5434   5606   **
  5435         -** ^If the requested page is already in the page cache, then the page cache
         5607  +** If the requested page is already in the page cache, then the page cache
  5436   5608   ** implementation must return a pointer to the page buffer with its content
  5437         -** intact.  ^(If the requested page is not already in the cache, then the
  5438         -** behavior of the cache implementation is determined by the value of the
  5439         -** createFlag parameter passed to xFetch, according to the following table:
         5609  +** intact.  If the requested page is not already in the cache, then the
         5610  +** behavior of the cache implementation should use the value of the createFlag
         5611  +** parameter to help it determined what action to take:
  5440   5612   **
  5441   5613   ** <table border=1 width=85% align=center>
  5442   5614   ** <tr><th> createFlag <th> Behaviour when page is not already in cache
  5443   5615   ** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
  5444   5616   ** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
  5445   5617   **                 Otherwise return NULL.
  5446   5618   ** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
  5447   5619   **                 NULL if allocating a new page is effectively impossible.
  5448         -** </table>)^
         5620  +** </table>
  5449   5621   **
  5450         -** SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  If
  5451         -** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
         5622  +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
         5623  +** will only use a createFlag of 2 after a prior call with a createFlag of 1
         5624  +** failed.)^  In between the to xFetch() calls, SQLite may
  5452   5625   ** attempt to unpin one or more cache pages by spilling the content of
  5453         -** pinned pages to disk and synching the operating system disk cache. After
  5454         -** attempting to unpin pages, the xFetch() method will be invoked again with
  5455         -** a createFlag of 2.
         5626  +** pinned pages to disk and synching the operating system disk cache.
  5456   5627   **
  5457   5628   ** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
  5458         -** as its second argument. ^(If the third parameter, discard, is non-zero,
  5459         -** then the page should be evicted from the cache. In this case SQLite 
  5460         -** assumes that the next time the page is retrieved from the cache using
  5461         -** the xFetch() method, it will be zeroed.)^ ^If the discard parameter is
  5462         -** zero, then the page is considered to be unpinned. ^The cache implementation
         5629  +** as its second argument.  If the third parameter, discard, is non-zero,
         5630  +** then the page must be evicted from the cache.
         5631  +** ^If the discard parameter is
         5632  +** zero, then the page may be discarded or retained at the discretion of
         5633  +** page cache implementation. ^The page cache implementation
  5463   5634   ** may choose to evict unpinned pages at any time.
  5464   5635   **
  5465         -** ^(The cache is not required to perform any reference counting. A single 
         5636  +** The cache must not perform any reference counting. A single 
  5466   5637   ** call to xUnpin() unpins the page regardless of the number of prior calls 
  5467         -** to xFetch().)^
         5638  +** to xFetch().
  5468   5639   **
  5469         -** ^The xRekey() method is used to change the key value associated with the
  5470         -** page passed as the second argument from oldKey to newKey. ^If the cache
  5471         -** previously contains an entry associated with newKey, it should be
         5640  +** The xRekey() method is used to change the key value associated with the
         5641  +** page passed as the second argument. If the cache
         5642  +** previously contains an entry associated with newKey, it must be
  5472   5643   ** discarded. ^Any prior cache entry associated with newKey is guaranteed not
  5473   5644   ** to be pinned.
  5474   5645   **
  5475         -** ^When SQLite calls the xTruncate() method, the cache must discard all
         5646  +** When SQLite calls the xTruncate() method, the cache must discard all
  5476   5647   ** existing cache entries with page numbers (keys) greater than or equal
  5477         -** to the value of the iLimit parameter passed to xTruncate(). ^If any
         5648  +** to the value of the iLimit parameter passed to xTruncate(). If any
  5478   5649   ** of these pages are pinned, they are implicitly unpinned, meaning that
  5479   5650   ** they can be safely discarded.
  5480   5651   **
  5481   5652   ** ^The xDestroy() method is used to delete a cache allocated by xCreate().
  5482   5653   ** All resources associated with the specified cache should be freed. ^After
  5483   5654   ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
  5484   5655   ** handle invalid, and will not use it with any other sqlite3_pcache_methods
................................................................................
  5646   5817   ** is not a permanent error and does not affect the return value of
  5647   5818   ** sqlite3_backup_finish().
  5648   5819   **
  5649   5820   ** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
  5650   5821   **
  5651   5822   ** ^Each call to sqlite3_backup_step() sets two values inside
  5652   5823   ** the [sqlite3_backup] object: the number of pages still to be backed
  5653         -** up and the total number of pages in the source databae file.
         5824  +** up and the total number of pages in the source database file.
  5654   5825   ** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
  5655   5826   ** retrieve these two values, respectively.
  5656   5827   **
  5657   5828   ** ^The values returned by these functions are only updated by
  5658   5829   ** sqlite3_backup_step(). ^If the source database is modified during a backup
  5659   5830   ** operation, then the values are not updated to account for any extra
  5660   5831   ** pages that need to be updated or the size of the source database file
................................................................................
  5742   5913   ** the other connections to use as the blocking connection.
  5743   5914   **
  5744   5915   ** ^(There may be at most one unlock-notify callback registered by a 
  5745   5916   ** blocked connection. If sqlite3_unlock_notify() is called when the
  5746   5917   ** blocked connection already has a registered unlock-notify callback,
  5747   5918   ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
  5748   5919   ** called with a NULL pointer as its second argument, then any existing
  5749         -** unlock-notify callback is cancelled. ^The blocked connections 
         5920  +** unlock-notify callback is canceled. ^The blocked connections 
  5750   5921   ** unlock-notify callback may also be canceled by closing the blocked
  5751   5922   ** connection using [sqlite3_close()].
  5752   5923   **
  5753   5924   ** The unlock-notify callback is not reentrant. If an application invokes
  5754   5925   ** any sqlite3_xxx API functions from within an unlock-notify callback, a
  5755   5926   ** crash or deadlock may be the result.
  5756   5927   **
................................................................................
  5824   5995   
  5825   5996   
  5826   5997   /*
  5827   5998   ** CAPI3REF: String Comparison
  5828   5999   **
  5829   6000   ** ^The [sqlite3_strnicmp()] API allows applications and extensions to
  5830   6001   ** compare the contents of two buffers containing UTF-8 strings in a
  5831         -** case-indendent fashion, using the same definition of case independence 
         6002  +** case-independent fashion, using the same definition of case independence 
  5832   6003   ** that SQLite uses internally when comparing identifiers.
  5833   6004   */
  5834   6005   SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
  5835   6006   
  5836   6007   /*
  5837   6008   ** CAPI3REF: Error Logging Interface
  5838   6009   **
................................................................................
  5948   6119   #endif
  5949   6120   
  5950   6121   #ifdef __cplusplus
  5951   6122   }  /* End of the 'extern "C"' block */
  5952   6123   #endif
  5953   6124   #endif
  5954   6125   
         6126  +/*
         6127  +** 2010 August 30
         6128  +**
         6129  +** The author disclaims copyright to this source code.  In place of
         6130  +** a legal notice, here is a blessing:
         6131  +**
         6132  +**    May you do good and not evil.
         6133  +**    May you find forgiveness for yourself and forgive others.
         6134  +**    May you share freely, never taking more than you give.
         6135  +**
         6136  +*************************************************************************
         6137  +*/
         6138  +
         6139  +#ifndef _SQLITE3RTREE_H_
         6140  +#define _SQLITE3RTREE_H_
         6141  +
         6142  +
         6143  +#ifdef __cplusplus
         6144  +extern "C" {
         6145  +#endif
         6146  +
         6147  +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
         6148  +
         6149  +/*
         6150  +** Register a geometry callback named zGeom that can be used as part of an
         6151  +** R-Tree geometry query as follows:
         6152  +**
         6153  +**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
         6154  +*/
         6155  +SQLITE_API int sqlite3_rtree_geometry_callback(
         6156  +  sqlite3 *db,
         6157  +  const char *zGeom,
         6158  +  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
         6159  +  void *pContext
         6160  +);
         6161  +
         6162  +
         6163  +/*
         6164  +** A pointer to a structure of the following type is passed as the first
         6165  +** argument to callbacks registered using rtree_geometry_callback().
         6166  +*/
         6167  +struct sqlite3_rtree_geometry {
         6168  +  void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
         6169  +  int nParam;                     /* Size of array aParam[] */
         6170  +  double *aParam;                 /* Parameters passed to SQL geom function */
         6171  +  void *pUser;                    /* Callback implementation user data */
         6172  +  void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
         6173  +};
         6174  +
         6175  +
         6176  +#ifdef __cplusplus
         6177  +}  /* end of the 'extern "C"' block */
         6178  +#endif
         6179  +
         6180  +#endif  /* ifndef _SQLITE3RTREE_H_ */
         6181  +

Changes to src/stat.c.

    24     24   
    25     25   /*
    26     26   ** WEBPAGE: stat
    27     27   **
    28     28   ** Show statistics and global information about the repository.
    29     29   */
    30     30   void stat_page(void){
    31         -  i64 t;
    32         -  int n, m, fsize;
           31  +  i64 t, fsize;
           32  +  int n, m;
           33  +  int szMax, szAvg;
    33     34     char zBuf[100];
           35  +
    34     36     login_check_credentials();
    35     37     if( !g.okRead ){ login_needed(); return; }
    36     38     style_header("Repository Statistics");
    37         -  @ <p><table class="label-value">
           39  +  @ <table class="label-value">
    38     40     @ <tr><th>Repository&nbsp;Size:</th><td>
    39     41     fsize = file_size(g.zRepositoryName);
    40         -  @ %d(fsize) bytes
           42  +  sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", fsize);
           43  +  @ %s(zBuf) bytes
    41     44     @ </td></tr>
    42     45     @ <tr><th>Number&nbsp;Of&nbsp;Artifacts:</th><td>
    43     46     n = db_int(0, "SELECT count(*) FROM blob");
    44     47     m = db_int(0, "SELECT count(*) FROM delta");
    45     48     @ %d(n) (stored as %d(n-m) full text and %d(m) delta blobs)
    46     49     @ </td></tr>
    47     50     if( n>0 ){
    48     51       int a, b;
           52  +    Stmt q;
    49     53       @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
    50         -    t = db_int64(0, "SELECT total(size) FROM blob WHERE size>0");
           54  +    db_prepare(&q, "SELECT total(size), avg(size), max(size)"
           55  +                   " FROM blob WHERE size>0");
           56  +    db_step(&q);
           57  +    t = db_column_int64(&q, 0);
           58  +    szAvg = db_column_int(&q, 1);
           59  +    szMax = db_column_int(&q, 2);
           60  +    db_finalize(&q);
    51     61       sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t);
    52         -    @ %d((int)(((double)t)/(double)n)) bytes average, %s(zBuf) bytes total
           62  +    @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) bytes total
    53     63       @ </td></tr>
    54     64       @ <tr><th>Compression&nbsp;Ratio:</th><td>
    55     65       if( t/fsize < 5 ){
    56     66         b = 10;
    57     67         fsize /= 10;
    58     68       }else{
    59     69         b = 1;
................................................................................
    80     90                   " WHERE +tagname GLOB 'tkt-*'");
    81     91     @ %d(n)
    82     92     @ </td></tr>
    83     93     @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
    84     94     n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
    85     95                   " + 0.99");
    86     96     @ %d(n) days
           97  +  sqlite3_snprintf(sizeof(zBuf), zBuf, "%.2f", n/365.24);
           98  +  @ or approximately %s(zBuf) years
    87     99     @ </td></tr>
    88    100     @ <tr><th>Project&nbsp;ID:</th><td>
    89    101     @ %h(db_get("project-code",""))
    90    102     @ </td></tr>
    91    103     @ <tr><th>Server&nbsp;ID:</th><td>
    92    104     @ %h(db_get("server-code",""))
    93    105     @ </td></tr>
    94    106   
    95    107     @ <tr><th>Fossil&nbsp;Version:</th><td>
    96         -  @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
          108  +  @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) (%h(COMPILER_NAME))
    97    109     @ </td></tr>
    98    110     @ <tr><th>SQLite&nbsp;Version:</th><td>
    99         -  @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)"))
   100         -  @ (%h(SQLITE_VERSION))
          111  +  sqlite3_snprintf(sizeof(zBuf), zBuf, "%.19s [%.10s] (%s)",
          112  +                   SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20], SQLITE_VERSION);
          113  +  @ %s(zBuf)
   101    114     @ </td></tr>
   102    115     @ <tr><th>Database&nbsp;Stats:</th><td>
   103    116     @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages,
   104    117     @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page,
   105    118     @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages,
   106    119     @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)),
   107    120     @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode
   108    121     @ </td></tr>
   109    122   
   110         -  @ </table></p>
          123  +  @ </table>
   111    124     style_footer();
   112    125   }

Changes to src/style.c.

    38     38   
    39     39   /*
    40     40   ** Remember that the header has been generated.  The footer is omitted
    41     41   ** if an error occurs before the header.
    42     42   */
    43     43   static int headerHasBeenGenerated = 0;
    44     44   
           45  +/*
           46  +** remember, if a sidebox was used
           47  +*/
           48  +static int sideboxUsed = 0;
           49  +
    45     50   /*
    46     51   ** Add a new element to the submenu
    47     52   */
    48     53   void style_submenu_element(
    49     54     const char *zLabel,
    50     55     const char *zTitle,
    51     56     const char *zLink,
................................................................................
    81     86   
    82     87     va_start(ap, zTitleFormat);
    83     88     zTitle = vmprintf(zTitleFormat, ap);
    84     89     va_end(ap);
    85     90     
    86     91     cgi_destination(CGI_HEADER);
    87     92     cgi_printf("%s",
    88         -     "<!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML 1.0 Strict//EN\""
           93  +     "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
    89     94        " \"http://www.x3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
    90     95     
    91     96     if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
    92     97   
    93     98     /* Generate the header up through the main menu */
    94     99     Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
    95    100     Th_Store("title", zTitle);
    96    101     Th_Store("baseurl", g.zBaseURL);
    97    102     Th_Store("index_page", db_get("index-page","/home"));
    98    103     Th_Store("current_page", g.zPath);
    99    104     Th_Store("manifest_version", MANIFEST_VERSION);
   100    105     Th_Store("manifest_date", MANIFEST_DATE);
          106  +  Th_Store("compiler_name", COMPILER_NAME);
   101    107     if( g.zLogin ){
   102    108       Th_Store("login", g.zLogin);
   103    109     }
   104    110     if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1);
   105    111     Th_Render(zHeader);
   106    112     if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
   107    113     Th_Unstore("title");   /* Avoid collisions with ticket field names */
   108    114     cgi_destination(CGI_BODY);
   109    115     g.cgiOutput = 1;
   110    116     headerHasBeenGenerated = 1;
          117  +  sideboxUsed = 0;
   111    118   }
   112    119   
   113    120   /*
   114    121   ** Draw the footer at the bottom of the page.
   115    122   */
   116    123   void style_footer(void){
   117    124     const char *zFooter;
................................................................................
   136    143         }
   137    144       }
   138    145       @ </div>
   139    146     }
   140    147     @ <div class="content">
   141    148     cgi_destination(CGI_BODY);
   142    149   
   143         -  /* Put the footer at the bottom of the page.
   144         -  */
   145         -  @ </div><br clear="both"/>
          150  +  if (sideboxUsed) {
          151  +    /* Put the footer at the bottom of the page.
          152  +    ** the additional clear/both is needed to extend the content
          153  +    ** part to the end of an optional sidebox.
          154  +    */
          155  +    @ <div class="endContent"></div>
          156  +  }
          157  +  @ </div>
   146    158     zFooter = db_get("footer", (char*)zDefaultFooter);
   147    159     if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
   148    160     Th_Render(zFooter);
   149    161     if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
   150    162     
   151    163     /* Render trace log if TH1 tracing is enabled. */
   152    164     if( g.thTrace ){
   153         -    cgi_append_content("<font color=\"red\"><hr>\n", -1);
          165  +    cgi_append_content("<span class=\"thTrace\"><hr />\n", -1);
   154    166       cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog));
   155         -    cgi_append_content("</font>\n", -1);
          167  +    cgi_append_content("</span>\n", -1);
   156    168     }
   157    169   }
   158    170   
   159    171   /*
   160    172   ** Begin a side-box on the right-hand side of a page.  The title and
   161    173   ** the width of the box are given as arguments.  The width is usually
   162    174   ** a percentage of total screen width.
   163    175   */
   164    176   void style_sidebox_begin(const char *zTitle, const char *zWidth){
   165         -  @ <table width="%s(zWidth)" align="right" border="1" cellpadding=5
   166         -  @  vspace=5 hspace=5>
   167         -  @ <tr><td>
   168         -  @ <b>%h(zTitle)</b>
          177  +  sideboxUsed = 1;
          178  +  @ <div class="sidebox" style="width:%s(zWidth)">
          179  +  @ <div class="sideboxTitle">%h(zTitle)</div>
   169    180   }
   170    181   
   171    182   /* End the side-box
   172    183   */
   173    184   void style_sidebox_end(void){
   174         -  @ </td></tr></table>
          185  +  @ </div>
   175    186   }
   176    187   
   177    188   /* @-comment: // */
   178    189   /*
   179    190   ** The default page header.
   180    191   */
   181    192   const char zDefaultHeader[] = 
   182    193   @ <html>
   183    194   @ <head>
   184    195   @ <title>$<project_name>: $<title></title>
   185    196   @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
   186         -@       href="$baseurl/timeline.rss">
          197  +@       href="$baseurl/timeline.rss" />
   187    198   @ <link rel="stylesheet" href="$baseurl/style.css?default" type="text/css"
   188         -@       media="screen">
          199  +@       media="screen" />
   189    200   @ </head>
   190    201   @ <body>
   191    202   @ <div class="header">
   192    203   @   <div class="logo">
   193         -@     <img src="$baseurl/logo" alt="logo">
          204  +@     <img src="$baseurl/logo" alt="logo" />
   194    205   @   </div>
   195         -@   <div class="title"><small>$<project_name></small><br>$<title></div>
   196         -@   <div class="status"><nobr><th1>
          206  +@   <div class="title"><small>$<project_name></small><br />$<title></div>
          207  +@   <div class="status"><th1>
   197    208   @      if {[info exists login]} {
   198    209   @        puts "Logged in as $login"
   199    210   @      } else {
   200    211   @        puts "Not logged in"
   201    212   @      }
   202         -@   </th1></nobr></div>
          213  +@   </th1></div>
   203    214   @ </div>
   204    215   @ <div class="mainmenu"><th1>
   205    216   @ html "<a href='$baseurl$index_page'>Home</a> "
   206    217   @ if {[anycap jor]} {
   207    218   @   html "<a href='$baseurl/timeline'>Timeline</a> "
   208    219   @ }
   209    220   @ if {[hascap oh]} {
................................................................................
   241    252   @ Fossil version $manifest_version $manifest_date
   242    253   @ </div>
   243    254   @ </body></html>
   244    255   ;
   245    256   
   246    257   /*
   247    258   ** The default Cascading Style Sheet.
          259  +** It's assembled by different strings for each class.
          260  +** The default css conatains all definitions.
          261  +** The style sheet, send to the client only contains the ones,
          262  +** not defined in the user defined css.
   248    263   */
   249    264   const char zDefaultCSS[] = 
   250    265   @ /* General settings for the entire page */
   251    266   @ body {
   252    267   @   margin: 0ex 1ex;
   253    268   @   padding: 0px;
   254    269   @   background-color: white;
................................................................................
   270    285   @   display: table-cell;
   271    286   @   font-size: 2em;
   272    287   @   font-weight: bold;
   273    288   @   text-align: center;
   274    289   @   padding: 0 0 0 1em;
   275    290   @   color: #558195;
   276    291   @   vertical-align: bottom;
   277         -@   width: 100%;
          292  +@   width: 100% ;
   278    293   @ }
   279    294   @
   280    295   @ /* The login status message in the top right-hand corner */
   281    296   @ div.status {
   282    297   @   display: table-cell;
   283    298   @   text-align: right;
   284    299   @   vertical-align: bottom;
   285    300   @   color: #558195;
   286    301   @   font-size: 0.8em;
   287    302   @   font-weight: bold;
   288    303   @   min-width: 200px;
          304  +@   white-space: nowrap;
   289    305   @ }
   290    306   @
   291    307   @ /* The header across the top of the page */
   292    308   @ div.header {
   293    309   @   display: table;
   294         -@   width: 100%;
          310  +@   width: 100% ;
   295    311   @ }
   296    312   @
   297    313   @ /* The main menu bar that appears at the top of the page beneath
   298    314   @ ** the header */
   299    315   @ div.mainmenu {
   300    316   @   padding: 5px 10px 5px 10px;
   301    317   @   font-size: 0.9em;
................................................................................
   335    351   @   margin-bottom: 0px;
   336    352   @   margin-top: 1em;
   337    353   @   padding: 1px 1px 1px 1px;
   338    354   @   font-size: 1.2em;
   339    355   @   font-weight: bold;
   340    356   @   background-color: #558195;
   341    357   @   color: white;
          358  +@   white-space: nowrap;
   342    359   @ }
   343    360   @
   344    361   @ /* The "Date" that occurs on the left hand side of timelines */
   345    362   @ div.divider {
   346    363   @   background: #a1c4d4;
   347    364   @   border: 2px #558195 solid;
   348    365   @   font-size: 1em; font-weight: normal;
   349    366   @   padding: .25em;
   350    367   @   margin: .2em 0 .2em 0;
   351    368   @   float: left;
   352    369   @   clear: left;
          370  +@   white-space: nowrap;
   353    371   @ }
   354    372   @
   355    373   @ /* The footer at the very bottom of the page */
   356    374   @ div.footer {
          375  +@   clear: both;
   357    376   @   font-size: 0.8em;
   358    377   @   margin-top: 12px;
   359    378   @   padding: 5px 10px 5px 10px;
   360    379   @   text-align: right;
   361    380   @   background-color: #558195;
   362    381   @   color: white;
   363    382   @ }
................................................................................
   364    383   @
   365    384   @ /* Hyperlink colors in the footer */
   366    385   @ div.footer a { color: white; }
   367    386   @ div.footer a:link { color: white; }
   368    387   @ div.footer a:visited { color: white; }
   369    388   @ div.footer a:hover { background-color: white; color: #558195; }
   370    389   @ 
   371         -@ /* <verbatim> blocks */
          390  +@ /* verbatim blocks */
   372    391   @ pre.verbatim {
   373    392   @    background-color: #f5f5f5;
   374    393   @    padding: 0.5em;
   375    394   @}
   376    395   @
   377    396   @ /* The label/value pairs on (for example) the ci page */
   378    397   @ table.label-value th {
   379    398   @   vertical-align: top;
   380    399   @   text-align: right;
   381    400   @   padding: 0.2ex 2ex;
   382    401   @ }
          402  +@
   383    403   ;
   384    404   
          405  +
          406  +/* The following table contains bits of default CSS that must
          407  +** be included if they are not found in the application-defined
          408  +** CSS.
          409  +*/
          410  +const struct strctCssDefaults {
          411  +  char const * const elementClass;  /* Name of element needed */
          412  +  char const * const comment;       /* Comment text */
          413  +  char const * const value;         /* CSS text */
          414  +} cssDefaultList[] = {
          415  +  { "",
          416  +    "",
          417  +    zDefaultCSS
          418  +  },
          419  +  { "div.sidebox",
          420  +    "The nomenclature sidebox for branches,..",
          421  +    @   float: right;
          422  +    @   background-color: white;
          423  +    @   border-width: medium;
          424  +    @   border-style: double;
          425  +    @   margin: 10;
          426  +  },
          427  +  { "div.sideboxTitle",
          428  +    "The nomenclature title in sideboxes for branches,..",
          429  +    @   display: inline;
          430  +    @   font-weight: bold;
          431  +  },
          432  +  { "div.sideboxDescribed",
          433  +    "The defined element in sideboxes for branches,..",
          434  +    @   display: inline;
          435  +    @   font-weight: bold;
          436  +  },
          437  +  { "span.disabled",
          438  +    "The defined element in sideboxes for branches,..",
          439  +    @   color: red;
          440  +  },
          441  +  { "span.timelineDisabled",
          442  +    "The suppressed duplicates lines in timeline, ..",
          443  +    @   font-style: italic;
          444  +    @   font-size: small;
          445  +  },
          446  +  { "table.timelineTable",
          447  +    "the format for the timeline data table",
          448  +    @   cellspacing: 0;
          449  +    @   border: 0;
          450  +    @   cellpadding: 0
          451  +  },
          452  +  { "td.timelineTableCell",
          453  +    "the format for the timeline data cells",
          454  +    @   valign: top;
          455  +    @   align: left;
          456  +  },
          457  +  { "span.timelineLeaf",
          458  +    "the format for the timeline leaf marks",
          459  +    @   font-weight: bold;
          460  +  },
          461  +  { "a.timelineHistLink",
          462  +    "the format for the timeline version links",
          463  +    @
          464  +  },
          465  +  { "span.timelineHistDsp",
          466  +    "the format for the timeline version display(no history permission!)",
          467  +    @   font-weight: bold;
          468  +  },
          469  +  { "td.timelineTime",
          470  +    "the format for the timeline time display",
          471  +    @   vertical-align: top;
          472  +    @   text-align: right;
          473  +  },
          474  +  { "td.timelineGraph",
          475  +    "the format for the grap placeholder cells in timelines",
          476  +    @ width: 20;
          477  +    @ text-align: left;
          478  +    @ vertical-align: top;
          479  +  },
          480  +  { "a.tagLink",
          481  +    "the format for the tag links",
          482  +    @
          483  +  },
          484  +  { "span.tagDsp",
          485  +    "the format for the tag display(no history permission!)",
          486  +    @   font-weight: bold;
          487  +  },
          488  +  { "span.wikiError",
          489  +    "the format for wiki errors",
          490  +    @   font-weight: bold;
          491  +    @   color: red;
          492  +  },
          493  +  { "span.infoTagCancelled",
          494  +    "the format for fixed/canceled tags,..",
          495  +    @   font-weight: bold;
          496  +    @   text-decoration: line-through;
          497  +  },
          498  +  { "span.infoTag",
          499  +    "the format for tags,..",
          500  +    @   font-weight: bold;
          501  +  },
          502  +  { "span.wikiTagCancelled",
          503  +    "the format for fixed/cancelled tags,.. on wiki pages",
          504  +    @   text-decoration: line-through;
          505  +  },
          506  +  { "table.browser",
          507  +    "format for the file display table",
          508  +    @ /* the format for wiki errors */
          509  +    @   width: 100% ;
          510  +    @   border: 0;
          511  +  },
          512  +  { "td.browser",
          513  +    "format for cells in the file browser",
          514  +    @   width: 24% ;
          515  +    @   vertical-align: top;
          516  +  },
          517  +  { "ul.browser",
          518  +    "format for the list in the file browser",
          519  +    @   margin-left: 0.5em;
          520  +    @   padding-left: 0.5em;
          521  +  },
          522  +  { "table.login_out",
          523  +    "table format for login/out label/input table",
          524  +    @   text-align: left;
          525  +    @   margin-right: 10px;
          526  +    @   margin-left: 10px;
          527  +    @   margin-top: 10px;
          528  +  },
          529  +  { "div.captcha",
          530  +    "captcha display options",
          531  +    @   text-align: center;
          532  +  },
          533  +  { "table.captcha",
          534  +    "format for the layout table, used for the captcha display",
          535  +    @   margin: auto;
          536  +    @   padding: 10px;
          537  +    @   border-width: 4px;
          538  +    @   border-style: double;
          539  +    @   border-color: black;
          540  +  },
          541  +  { "td.login_out_label",
          542  +    "format for the label cells in the login/out table",
          543  +    @   text-align: center;
          544  +  },
          545  +  { "span.loginError",
          546  +    "format for login error messages",
          547  +    @   color: red;
          548  +  },
          549  +  { "span.note",
          550  +    "format for leading text for notes",
          551  +    @   font-weight: bold;
          552  +  },
          553  +  { "span.textareaLabel",
          554  +    "format for textare labels",
          555  +    @   font-weight: bold;
          556  +  },
          557  +  { "table.usetupLayoutTable",
          558  +    "format for the user setup layout table",
          559  +    @   outline-style: none;
          560  +    @   padding: 0;
          561  +    @   margin: 25px;
          562  +  },
          563  +  { "td.usetupColumnLayout",
          564  +    "format of the columns on the user setup list page",
          565  +    @   vertical-align: top
          566  +  },
          567  +  { "table.usetupUserList",
          568  +    "format for the user list table on the user setup page",
          569  +    @   outline-style: double;
          570  +    @   outline-width: 1;
          571  +    @   padding: 10px;
          572  +  },
          573  +  { "th.usetupListUser",
          574  +    "format for table header user in user list on user setup page",
          575  +    @   text-align: right;
          576  +    @   padding-right: 20px;
          577  +  },
          578  +  { "th.usetupListCap",
          579  +    "format for table header capabilities in user list on user setup page",
          580  +    @   text-align: center;
          581  +    @   padding-right: 15px;
          582  +  },
          583  +  { "th.usetupListCon",
          584  +    "format for table header contact info in user list on user setup page",
          585  +    @   text-align: left;
          586  +  },
          587  +  { "td.usetupListUser",
          588  +    "format for table cell user in user list on user setup page",
          589  +    @   text-align: right;
          590  +    @   padding-right: 20px;
          591  +    @   white-space:nowrap;
          592  +  },
          593  +  { "td.usetupListCap",
          594  +    "format for table cell capabilities in user list on user setup page",
          595  +    @   text-align: center;
          596  +    @   padding-right: 15px;
          597  +  },
          598  +  { "td.usetupListCon",
          599  +    "format for table cell contact info in user list on user setup page",
          600  +    @   text-align: left
          601  +  },
          602  +  { "div.ueditCapBox",
          603  +    "layout definition for the capabilities box on the user edit detail page",
          604  +    @   float: left;
          605  +    @   margin-right: 20px;
          606  +    @   margin-bottom: 20px;
          607  +  },
          608  +  { "td.usetupEditLabel",
          609  +    "format of the label cells in the detailed user edit page",
          610  +    @   text-align: right;
          611  +    @   vertical-align: top;
          612  +    @   white-space: nowrap;
          613  +  },
          614  +  { "span.ueditInheritNobody",
          615  +    "color for capabilities, inherited by nobody",
          616  +    @   color: green;
          617  +  },
          618  +  { "span.ueditInheritDeveloper",
          619  +    "color for capabilities, inherited by developer",
          620  +    @   color: red;
          621  +  },
          622  +  { "span.ueditInheritReader",
          623  +    "color for capabilities, inherited by reader",
          624  +    @   color: black;
          625  +  },
          626  +  { "span.ueditInheritAnonymous",
          627  +    "color for capabilities, inherited by anonymous",
          628  +    @   color: blue;
          629  +  },
          630  +  { "span.capability",
          631  +    "format for capabilites, mentioned on the user edit page",
          632  +    @   font-weight: bold;
          633  +  },
          634  +  { "span.usertype",
          635  +    "format for different user types, mentioned on the user edit page",
          636  +    @   font-weight: bold;
          637  +  },
          638  +  { "span.usertype:before",
          639  +    "leading text for user types, mentioned on the user edit page",
          640  +    @   content:"'";
          641  +  },
          642  +  { "span.usertype:after",
          643  +    "trailing text for user types, mentioned on the user edit page",
          644  +    @   content:"'";
          645  +  },
          646  +  { "p.missingPriv",
          647  +    "format for missing priviliges note on user setup page",
          648  +    @  color: blue;
          649  +  },
          650  +  { "span.wikiruleHead",
          651  +    "format for leading text in wikirules definitions",
          652  +    @   font-weight: bold;
          653  +  },
          654  +  { "td.tktDspLabel",
          655  +    "format for labels on ticket display page",
          656  +    @   text-align: right;
          657  +  },
          658  +  { "td.tktDspValue",
          659  +    "format for values on ticket display page",
          660  +    @   text-align: left;
          661  +    @   vertical-align: top;
          662  +    @   background-color: #d0d0d0;
          663  +  },
          664  +  { "span.tktError",
          665  +    "format for ticket error messages",
          666  +    @   color: red;
          667  +    @   font-weight: bold;
          668  +  },
          669  +  { "table.rpteditex",
          670  +    "format for example tables on the report edit page",
          671  +    @   float: right;
          672  +    @   margin: 0;
          673  +    @   padding: 0;
          674  +    @   width: 125px;
          675  +    @   text-align: center;
          676  +    @   border-collapse: collapse;
          677  +    @   border-spacing: 0;
          678  +  },
          679  +  { "td.rpteditex",
          680  +    "format for example table cells on the report edit page",
          681  +    @   border-width: thin;
          682  +    @   border-color: #000000;
          683  +    @   border-style: solid;
          684  +  },
          685  +  { "input.checkinUserColor",
          686  +    "format for user color input on checkin edit page",
          687  +    @ # no special definitions, class defined, to enable color pickers, f.e.:
          688  +    @ #  add the color picker found at http:jscolor.com  as java script include
          689  +    @ #  to the header and configure the java script file with
          690  +    @ #   1. use as bindClass :checkinUserColor
          691  +    @ #   2. change the default hash adding behaviour to ON
          692  +    @ #  or change the class defition of element identified by id="clrcust"
          693  +    @ #  to a standard jscolor definition with java script in the footer.
          694  +  },
          695  +  { "div.endContent",
          696  +    "format for end of content area, to be used to clear page flow(sidebox on branch,..",
          697  +    @   clear: both;
          698  +  },
          699  +  { "p.generalError",
          700  +    "format for general errors",
          701  +    @   color: red;
          702  +  },
          703  +  { "p.tktsetupError",
          704  +    "format for tktsetup errors",
          705  +    @   color: red;
          706  +    @   font-weight: bold;
          707  +  },
          708  +  { "p.thmainError",
          709  +    "format for th script errors",
          710  +    @   color: red;
          711  +    @   font-weight: bold;
          712  +  },
          713  +  { "span.thTrace",
          714  +    "format for th script trace messages",
          715  +    @   color: red;
          716  +  },
          717  +  { "p:reportError",
          718  +    "format for report configuration errors",
          719  +    @   color: red;
          720  +    @   font-weight: bold;
          721  +  },
          722  +  { "blockquote.reportError",
          723  +    "format for report configuration errors",
          724  +    @   color: red;
          725  +    @   font-weight: bold;
          726  +  },
          727  +  { "p.noMoreShun",
          728  +    "format for artifact lines, no longer shunned",
          729  +    @   color: blue;
          730  +  },
          731  +  { "p.shunned",
          732  +    "format for artifact lines beeing shunned",
          733  +    @   color: blue;
          734  +  },
          735  +  { 0,
          736  +    0,
          737  +    0
          738  +  }
          739  +};
          740  +
          741  +/*
          742  +** Append all of the default CSS to the CGI output.
          743  +*/
          744  +void cgi_append_default_css(void) {
          745  +  int i;
          746  +
          747  +  for (i=0;cssDefaultList[i].elementClass;i++){
          748  +    if (cssDefaultList[i].elementClass[0]){
          749  +      cgi_printf("/* %s */\n%s {\n%s\n}\n\n",
          750  +		 cssDefaultList[i].comment,
          751  +		 cssDefaultList[i].elementClass,
          752  +		 cssDefaultList[i].value
          753  +		);
          754  +    }else{
          755  +      cgi_printf("%s",
          756  +		 cssDefaultList[i].value
          757  +		);
          758  +    }
          759  +  }
          760  +}
          761  +
   385    762   /*
   386    763   ** WEBPAGE: style.css
   387    764   */
   388    765   void page_style_css(void){
   389         -  char *zCSS = 0;
          766  +  const char *zCSS    = 0;
          767  +  int i;
   390    768   
   391    769     cgi_set_content_type("text/css");
   392    770     zCSS = db_get("css",(char*)zDefaultCSS);
          771  +  /* append user defined css */
   393    772     cgi_append_content(zCSS, -1);
          773  +  /* add special missing definitions */
          774  +  for (i=1;cssDefaultList[i].elementClass;i++)
          775  +    if (!strstr(zCSS,cssDefaultList[i].elementClass)) {
          776  +      cgi_append_content("/* ", -1);
          777  +      cgi_append_content(cssDefaultList[i].comment, -1);
          778  +      cgi_append_content(" */\n", -1);
          779  +      cgi_append_content(cssDefaultList[i].elementClass, -1);
          780  +      cgi_append_content(" {\n", -1);
          781  +      cgi_append_content(cssDefaultList[i].value, -1);
          782  +      cgi_append_content("}\n\n", -1);
          783  +    }
   394    784     g.isConst = 1;
   395    785   }
   396    786   
   397    787   /*
   398    788   ** WEBPAGE: test_env
   399    789   */
   400    790   void page_test_env(void){
   401    791     style_header("Environment Test");
   402         -#if !defined(__MINGW32__)
   403         -  @ uid=%d(getuid()), gid=%d(getgid())<br>
          792  +#if !defined(_WIN32)
          793  +  @ uid=%d(getuid()), gid=%d(getgid())<br />
   404    794   #endif
   405         -  @ g.zBaseURL = %h(g.zBaseURL)<br>
   406         -  @ g.zTop = %h(g.zTop)<br>
   407         -  @ g.zRepositoryName = %h(g.zRepositoryName)<br>
          795  +  @ g.zBaseURL = %h(g.zBaseURL)<br />
          796  +  @ g.zTop = %h(g.zTop)<br />
   408    797     cgi_print_all();
   409    798     style_footer();
   410    799   }

Changes to src/sync.c.

    54     54     }else{
    55     55       /* Autosync defaults on.  To make it default off, "return" here. */
    56     56     }
    57     57     zUrl = db_get("last-sync-url", 0);
    58     58     if( zUrl==0 ){
    59     59       return;  /* No default server */
    60     60     }
    61         -  zPw = db_get("last-sync-pw", 0);
           61  +  zPw = unobscure(db_get("last-sync-pw", 0));
    62     62     url_parse(zUrl);
    63     63     if( g.urlUser!=0 && g.urlPasswd==0 ){
    64     64       g.urlPasswd = mprintf("%s", zPw);
    65     65     }
    66     66     if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
    67     67       /* When doing an automatic pull, also automatically pull shuns from
    68     68       ** the server if pull_shuns is enabled.
................................................................................
    91     91     int urlOptional = find_option("autourl",0,0)!=0;
    92     92     g.dontKeepUrl = find_option("once",0,0)!=0;
    93     93     url_proxy_options();
    94     94     db_find_and_open_repository(1);
    95     95     db_open_config(0);
    96     96     if( g.argc==2 ){
    97     97       zUrl = db_get("last-sync-url", 0);
    98         -    zPw = db_get("last-sync-pw", 0);
           98  +    zPw = unobscure(db_get("last-sync-pw", 0));
    99     99       if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
   100    100     }else if( g.argc==3 ){
   101    101       zUrl = g.argv[2];
   102    102     }
   103    103     if( zUrl==0 ){
   104    104       if( urlOptional ) fossil_exit(0);
   105    105       usage("URL");
   106    106     }
   107    107     url_parse(zUrl);
   108    108     if( !g.dontKeepUrl ){
   109    109       db_set("last-sync-url", g.urlCanonical, 0);
   110         -    if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0);
          110  +    if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
   111    111     }
   112    112     if( g.urlUser!=0 && g.urlPasswd==0 ){
   113    113       if( zPw==0 ){
   114    114         url_prompt_for_password();
   115    115       }else{
   116    116         g.urlPasswd = mprintf("%s", zPw);
   117    117       }
................................................................................
   230    230       }else{
   231    231         url_parse(g.argv[2]);
   232    232         if( g.urlUser && g.urlPasswd==0 ){
   233    233           url_prompt_for_password();
   234    234         }
   235    235         db_set("last-sync-url", g.urlCanonical, 0);
   236    236         if( g.urlPasswd ){
   237         -        db_set("last-sync-pw", g.urlPasswd, 0);
          237  +        db_set("last-sync-pw", obscure(g.urlPasswd), 0);
   238    238         }else{
   239    239           db_unset("last-sync-pw", 0);
   240    240         }
   241    241       }
   242    242     }
   243    243     zUrl = db_get("last-sync-url", 0);
   244    244     if( zUrl==0 ){

Changes to src/tag.c.

   256    256   ** or cancels a tag.
   257    257   */
   258    258   void tag_add_artifact(
   259    259     const char *zPrefix,        /* Prefix to prepend to tag name */
   260    260     const char *zTagname,       /* The tag to add or cancel */
   261    261     const char *zObjName,       /* Name of object attached to */
   262    262     const char *zValue,         /* Value for the tag.  Might be NULL */
   263         -  int tagtype                 /* 0:cancel 1:singleton 2:propagated */
          263  +  int tagtype,                /* 0:cancel 1:singleton 2:propagated */
          264  +  const char *zDateOvrd,      /* Override date string */
          265  +  const char *zUserOvrd       /* Override user name */
   264    266   ){
   265    267     int rid;
   266    268     int nrid;
   267    269     char *zDate;
   268    270     Blob uuid;
   269    271     Blob ctrl;
   270    272     Blob cksum;
................................................................................
   287    289       fossil_fatal(
   288    290          "invalid tag name \"%s\" - might be confused with"
   289    291          " a hexadecimal artifact ID",
   290    292          zTagname
   291    293       );
   292    294     }
   293    295   #endif
   294         -  zDate = db_text(0, "SELECT datetime('now')");
          296  +  zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
   295    297     zDate[10] = 'T';
   296    298     blob_appendf(&ctrl, "D %s\n", zDate);
   297    299     blob_appendf(&ctrl, "T %c%s%F %b",
   298    300                  zTagtype[tagtype], zPrefix, zTagname, &uuid);
   299    301     if( tagtype>0 && zValue && zValue[0] ){
   300    302       blob_appendf(&ctrl, " %F\n", zValue);
   301    303     }else{
   302    304       blob_appendf(&ctrl, "\n");
   303    305     }
   304         -  blob_appendf(&ctrl, "U %F\n", g.zLogin);
          306  +  blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
   305    307     md5sum_blob(&ctrl, &cksum);
   306    308     blob_appendf(&ctrl, "Z %b\n", &cksum);
   307    309     nrid = content_put(&ctrl, 0, 0);
   308    310     manifest_crosslink(nrid, &ctrl);
   309    311   }
   310    312   
   311    313   /*
................................................................................
   350    352   ** will be taken as an artifact or baseline ID and fossil will
   351    353   ** probably complain that no such revision was found. However
   352    354   **
   353    355   **   fossil update tag:decaf
   354    356   **
   355    357   ** will assume that "decaf" is a tag/branch name.
   356    358   **
          359  +** only allow --date-override and --user-override in 
          360  +**   %fossil tag add --date-override 'YYYY-MMM-DD HH:MM:SS' \\
          361  +**                   --user-override user 
          362  +** in order to import history from other scm systems
   357    363   */
   358    364   void tag_cmd(void){
   359    365     int n;
   360    366     int fRaw = find_option("raw","",0)!=0;
   361    367     int fPropagate = find_option("propagate","",0)!=0;
   362    368     const char *zPrefix = fRaw ? "" : "sym-";
   363    369   
................................................................................
   368    374     n = strlen(g.argv[2]);
   369    375     if( n==0 ){
   370    376       goto tag_cmd_usage;
   371    377     }
   372    378   
   373    379     if( strncmp(g.argv[2],"add",n)==0 ){
   374    380       char *zValue;
          381  +    const char *zDateOvrd = find_option("date-override",0,1);
          382  +    const char *zUserOvrd = find_option("user-override",0,1);
   375    383       if( g.argc!=5 && g.argc!=6 ){
   376    384         usage("add ?--raw? ?--propagate? TAGNAME CHECK-IN ?VALUE?");
   377    385       }
   378    386       zValue = g.argc==6 ? g.argv[5] : 0;
   379    387       db_begin_transaction();
   380         -    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], zValue, 1+fPropagate);
          388  +    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], zValue,
          389  +                     1+fPropagate,zDateOvrd,zUserOvrd);
   381    390       db_end_transaction(0);
   382    391     }else
   383    392   
   384    393     if( strncmp(g.argv[2],"branch",n)==0 ){
   385    394       fossil_fatal("the \"fossil tag branch\" command is discontinued\n"
   386    395                    "Use the \"fossil branch new\" command instead.");
   387    396     }else
   388    397   
   389    398     if( strncmp(g.argv[2],"cancel",n)==0 ){
   390    399       if( g.argc!=5 ){
   391    400         usage("cancel ?--raw? TAGNAME CHECK-IN");
   392    401       }
   393    402       db_begin_transaction();
   394         -    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0);
          403  +    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0);
   395    404       db_end_transaction(0);
   396    405     }else
   397    406   
   398    407     if( strncmp(g.argv[2],"find",n)==0 ){
   399    408       Stmt q;
   400    409       if( g.argc!=4 ){
   401    410         usage("find ?--raw? TAGNAME");
................................................................................
   512    521       " AND tagname GLOB 'sym-*'"
   513    522       " ORDER BY tagname"
   514    523     );
   515    524     @ <ul>
   516    525     while( db_step(&q)==SQLITE_ROW ){
   517    526       const char *zName = db_column_text(&q, 0);
   518    527       if( g.okHistory ){
   519         -      @ <li><a href=%s(g.zBaseURL)/timeline?t=%T(zName)>%h(zName)</a></li>
          528  +      @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)">
          529  +      @ %h(zName)</a></li>
   520    530       }else{
   521         -      @ <li><strong>%h(zName)</strong></li>
          531  +      @ <li><span class="tagDsp">%h(zName)</span></li>
   522    532       }
   523    533     }
   524    534     @ </ul>
   525    535     db_finalize(&q);
   526    536     style_footer();
   527    537   }
   528    538   
................................................................................
   540    550       "   AND tagxref.tagtype>0 AND tagxref.srcid>0"
   541    551       "   AND tag.tagname GLOB 'sym-*'",
   542    552       rid
   543    553     );
   544    554     while( db_step(&q)==SQLITE_ROW ){
   545    555       const char *zTagName = db_column_text(&q, 0);
   546    556       if( g.okHistory ){
   547         -      @ <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">[%h(zTagName)]</a>
          557  +      @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">
          558  +      @ [%h(zTagName)]</a>
   548    559       }else{
   549         -      @ <b>[%h(zTagName)]</b>
          560  +      @ <span class="tagDsp">[%h(zTagName)]</span>
   550    561       }
   551    562     }
   552    563     db_finalize(&q);
   553    564   }
   554    565   
   555    566   /*
   556    567   ** WEBPAGE: /tagtimeline
................................................................................
   571    582       "                       AND tagid IN (SELECT tagid FROM tag "
   572    583       "                                      WHERE tagname GLOB 'sym-*'))"
   573    584       " ORDER BY event.mtime DESC",
   574    585       timeline_query_for_www()
   575    586     );
   576    587     www_print_timeline(&q, 0, tagtimeline_extra);
   577    588     db_finalize(&q);
   578         -  @ <br clear="both">
   579         -  @ <script>
          589  +  @ <br />
          590  +  @ <script  type="text/JavaScript">
   580    591     @ function xin(id){
   581    592     @ }
   582    593     @ function xout(id){
   583    594     @ }
   584    595     @ </script>
   585    596     style_footer();
   586    597   }

Changes to src/th.c.

   844    844         continue;
   845    845       }
   846    846   
   847    847       /* Gobble up input a word at a time until the end of the command
   848    848       ** (a semi-colon or end of line).
   849    849       */
   850    850       while( rc==TH_OK && *zInput!=';' && !thEndOfLine(zInput, nInput) ){
   851         -      int nWord;
          851  +      int nWord=0;
   852    852         thNextSpace(interp, zInput, nInput, &nSpace);
   853    853         rc = thNextWord(interp, &zInput[nSpace], nInput-nSpace, &nWord, 1);
   854    854         zInput += (nSpace+nWord);
   855    855         nInput -= (nSpace+nWord);
   856    856       }
   857    857       if( rc!=TH_OK ) continue;
   858    858   

Changes to src/th_lang.c.

     5      5   **
     6      6   ** All built-in commands are implemented using the public interface 
     7      7   ** declared in th.h, so this file serves as both a part of the language 
     8      8   ** implementation and an example of how to extend the language with
     9      9   ** new commands.
    10     10   */
    11     11   
           12  +#include "config.h"
    12     13   #include "th.h"
    13     14   #include <string.h>
    14     15   #include <assert.h>
    15     16   
    16     17   int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg){
    17     18     Th_ErrorMessage(interp, "wrong # args: should be \"", zMsg, -1);
    18     19     return TH_ERROR;
................................................................................
   569    570   ){
   570    571     if( argc!=1 && argc!=2 ){
   571    572       return Th_WrongNumArgs(interp, "return ?value?");
   572    573     }
   573    574     if( argc==2 ){
   574    575       Th_SetResult(interp, argv[1], argl[1]);
   575    576     }
   576         -  return (int)ctx;
          577  +  return FOSSIL_PTR_TO_INT(ctx);
   577    578   }
   578    579   
   579    580   /*
   580    581   ** TH Syntax: 
   581    582   **
   582    583   **   return ?-code code? ?value?
   583    584   */

Changes to src/th_main.c.

    28     28   */
    29     29   static int nOutstandingMalloc = 0;
    30     30   
    31     31   /*
    32     32   ** Implementations of malloc() and free() to pass to the interpreter.
    33     33   */
    34     34   static void *xMalloc(unsigned int n){
    35         -  void *p = malloc(n);
           35  +  void *p = fossil_malloc(n);
    36     36     if( p ){
    37     37       nOutstandingMalloc++;
    38     38     }
    39     39     return p;
    40     40   }
    41     41   static void xFree(void *p){
    42     42     if( p ){
................................................................................
   276    276       sendText(z, -1, 0);
   277    277       free(z);
   278    278       blob_reset(&name);
   279    279       for(i=0; i<nElem; i++){
   280    280         zH = htmlize((char*)azElem[i], aszElem[i]);
   281    281         if( zValue && aszElem[i]==nValue 
   282    282                && memcmp(zValue, azElem[i], nValue)==0 ){
   283         -        z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
          283  +        z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
          284  +                     zH, zH);
   284    285         }else{
   285    286           z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
   286    287         }
   287    288         free(zH);
   288    289         sendText(z, -1, 0);
   289    290         free(z);
   290    291       }
................................................................................
   432    433   static int validVarName(const char *z){
   433    434     int i = 0;
   434    435     int inBracket = 0;
   435    436     if( z[0]=='<' ){
   436    437       inBracket = 1;
   437    438       z++;
   438    439     }
   439         -  if( z[0]==':' && z[1]==':' && isalpha(z[2]) ){
          440  +  if( z[0]==':' && z[1]==':' && fossil_isalpha(z[2]) ){
   440    441       z += 3;
   441    442       i += 3;
   442         -  }else if( isalpha(z[0]) ){
          443  +  }else if( fossil_isalpha(z[0]) ){
   443    444       z ++;
   444    445       i += 1;
   445    446     }else{
   446    447       return 0;
   447    448     }
   448         -  while( isalnum(z[0]) || z[0]=='_' ){
          449  +  while( fossil_isalnum(z[0]) || z[0]=='_' ){
   449    450       z++;
   450    451       i++;
   451    452     }
   452    453     if( inBracket ){
   453    454       if( z[0]!='>' ) return 0;
   454    455       i += 2;
   455    456     }
................................................................................
   501    502         if( z[0] ){ z += 6; }
   502    503         i = 0;
   503    504       }else{
   504    505         i++;
   505    506       }
   506    507     }
   507    508     if( rc==TH_ERROR ){
   508         -    sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
          509  +    sendText("<hr><p class=\"thmainError\">ERROR: ", -1, 0);
   509    510       zResult = (char*)Th_GetResult(g.interp, &n);
   510    511       sendText((char*)zResult, n, 1);
   511         -    sendText("</b></font></p>", -1, 0);
          512  +    sendText("</p>", -1, 0);
   512    513     }else{
   513    514       sendText(z, i, 0);
   514    515     }
   515    516     return rc;
   516    517   }
   517    518   
   518    519   /*

Changes to src/timeline.c.

    46     46   /*
    47     47   ** Generate a hyperlink to a version.
    48     48   */
    49     49   void hyperlink_to_uuid(const char *zUuid){
    50     50     char zShortUuid[UUID_SIZE+1];
    51     51     shorten_uuid(zShortUuid, zUuid);
    52     52     if( g.okHistory ){
    53         -    @ <a href="%s(g.zBaseURL)/info/%s(zShortUuid)">[%s(zShortUuid)]</a>
           53  +    @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)">
           54  +    @ [%s(zShortUuid)]</a>
    54     55     }else{
    55         -    @ <b>[%s(zShortUuid)]</b>
           56  +    @ <span class="timelineHistDsp">[%s(zShortUuid)]</span>
    56     57     }
    57     58   }
    58     59   
    59     60   /*
    60     61   ** Generate a hyperlink that invokes javascript to highlight
    61     62   ** a version on mouseover.
    62     63   */
................................................................................
    81     82   ** Generate a hyperlink to a diff between two versions.
    82     83   */
    83     84   void hyperlink_to_diff(const char *zV1, const char *zV2){
    84     85     if( g.okHistory ){
    85     86       if( zV2==0 ){
    86     87         @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
    87     88       }else{
    88         -      @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
           89  +      @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&amp;v2=%s(zV2)">[diff]</a>
    89     90       }
    90     91     }
    91     92   }
    92     93   
    93     94   /*
    94     95   ** Generate a hyperlink to a date & time.
    95     96   */
................................................................................
   107    108   ** events by that user.  If the date+time is specified, then the timeline
   108    109   ** is centered on that date+time.
   109    110   */
   110    111   void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
   111    112     if( zSuf==0 ) zSuf = "";
   112    113     if( g.okHistory ){
   113    114       if( zD && zD[0] ){
   114         -      @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf)
          115  +      @ <a href="%s(g.zTop)/timeline?c=%T(zD)&amp;u=%T(zU)">%h(zU)</a>%s(zSuf)
   115    116       }else{
   116    117         @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf)
   117    118       }
   118    119     }else{
   119    120       @ %s(zU)
   120    121     }
   121    122   }
................................................................................
   162    163   **    2.  Date/Time
   163    164   **    3.  Comment string
   164    165   **    4.  User
   165    166   **    5.  True if is a leaf
   166    167   **    6.  background color
   167    168   **    7.  type ("ci", "w", "t")
   168    169   **    8.  list of symbolic tags.
   169         -**    9.  tagid for ticket or wiki
          170  +**    9.  tagid for ticket or wiki or event
   170    171   **   10.  Short comment to user for repeated tickets and wiki
   171    172   */
   172    173   void www_print_timeline(
   173    174     Stmt *pQuery,          /* Query to implement the timeline */
   174    175     int tmFlags,           /* Flags controlling display behavior */
   175    176     void (*xExtra)(int)    /* Routine to call on each line of display */
   176    177   ){
................................................................................
   187    188     if( db_get_boolean("timeline-block-markup", 0) ){
   188    189       wikiFlags = WIKI_INLINE;
   189    190     }else{
   190    191       wikiFlags = WIKI_INLINE | WIKI_NOBLOCK;
   191    192     }
   192    193     if( tmFlags & TIMELINE_GRAPH ){
   193    194       pGraph = graph_init();
          195  +    /* style is not moved to css, because this is
          196  +    ** a technical div for the timeline graph
          197  +    */
   194    198       @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
   195    199     }
   196    200   
   197         -  @ <table cellspacing=0 border=0 cellpadding=0>
          201  +  @ <table class="timelineTable">
   198    202     blob_zero(&comment);
   199    203     while( db_step(pQuery)==SQLITE_ROW ){
   200    204       int rid = db_column_int(pQuery, 0);
   201    205       const char *zUuid = db_column_text(pQuery, 1);
   202    206       int isLeaf = db_column_int(pQuery, 5);
   203    207       const char *zBgClr = db_column_text(pQuery, 6);
   204    208       const char *zDate = db_column_text(pQuery, 2);
................................................................................
   216    220           }else{
   217    221             commentColumn = 10;
   218    222           }
   219    223         }
   220    224       }
   221    225       prevTagid = tagid;
   222    226       if( suppressCnt ){
   223         -      @ <tr><td><td><td>
   224         -      @ <small><i>... %d(suppressCnt) similar
   225         -      @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
          227  +      @ <tr><td /><td /><td>
          228  +      @ <span class="timelineDisabled">... %d(suppressCnt) similar
          229  +      @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr>
   226    230         suppressCnt = 0;
   227    231       }
   228    232       if( strcmp(zType,"div")==0 ){
   229         -      @ <tr><td colspan=3><hr></td></tr>
          233  +      @ <tr><td colspan="3"><hr /></td></tr>
   230    234         continue;
   231    235       }
   232    236       if( memcmp(zDate, zPrevDate, 10) ){
   233    237         sprintf(zPrevDate, "%.10s", zDate);
   234    238         @ <tr><td>
   235         -      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
          239  +      @   <div class="divider">%s(zPrevDate)</div>
   236    240         @ </td></tr>
   237    241       }
   238    242       memcpy(zTime, &zDate[11], 5);
   239    243       zTime[5] = 0;
   240    244       @ <tr>
   241         -    @ <td valign="top" align="right">%s(zTime)</td>
   242         -    @ <td width="20" align="left" valign="top">
          245  +    @ <td class="timelineTime">%s(zTime)</td>
          246  +    @ <td class="timelineGraph">
   243    247       if( pGraph && zType[0]=='c' ){
   244    248         int nParent = 0;
   245    249         int aParent[32];
   246    250         const char *zBr;
   247    251         int gidx;
   248    252         static Stmt qparent;
   249    253         static Stmt qbranch;
................................................................................
   265    269         }else{
   266    270           zBr = "trunk";
   267    271         }
   268    272         gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr);
   269    273         db_reset(&qbranch);
   270    274         @ <div id="m%d(gidx)"></div>
   271    275       }
          276  +    @</td>
   272    277       if( zBgClr && zBgClr[0] ){
   273         -      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
          278  +      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
   274    279       }else{
   275         -      @ <td valign="top" align="left">
          280  +      @ <td class="timelineTableCell">
   276    281       }
   277    282       if( zType[0]=='c' ){
   278    283         hyperlink_to_uuid(zUuid);
   279    284         if( isLeaf ){
   280    285           if( db_exists("SELECT 1 FROM tagxref"
   281    286                         " WHERE rid=%d AND tagid=%d AND tagtype>0",
   282    287                         rid, TAG_CLOSED) ){
   283         -          @ <b>Closed-Leaf:</b>
          288  +          @ <span class="timelineLeaf">Closed-Leaf:</span>
   284    289           }else{
   285         -          @ <b>Leaf:</b>
          290  +          @ <span class="timelineLeaf">Leaf:</span>
   286    291           }
   287    292         }
          293  +    }else if( zType[0]=='e' && tagid ){
          294  +      hyperlink_to_event_tagid(tagid);
   288    295       }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
   289    296         hyperlink_to_uuid(zUuid);
   290    297       }
   291    298       db_column_blob(pQuery, commentColumn, &comment);
   292    299       if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
   293    300         Blob truncated;
   294    301         blob_zero(&truncated);
................................................................................
   307    314       }
   308    315       if( xExtra ){
   309    316         xExtra(rid);
   310    317       }
   311    318       @ </td></tr>
   312    319     }
   313    320     if( suppressCnt ){
   314         -    @ <tr><td><td><td>
   315         -    @ <small><i>... %d(suppressCnt) similar
   316         -    @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
          321  +    @ <tr><td /><td /><td>
          322  +    @ <span class="timelineDisabled">... %d(suppressCnt) similar
          323  +    @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr>
   317    324       suppressCnt = 0;
   318    325     }
   319    326     if( pGraph ){
   320    327       graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
   321    328       if( pGraph->nErr ){
   322    329         graph_free(pGraph);
   323    330         pGraph = 0;
   324    331       }else{
   325         -      @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
          332  +      /* style is not moved to css, because this is
          333  +      ** a technical div for the timeline graph
          334  +      */
          335  +      @ <tr><td /><td>
          336  +      @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div>
          337  +      @ </td></tr>
   326    338       }
   327    339     }
   328    340     @ </table>
   329    341     timeline_output_graph_javascript(pGraph);
   330    342   }
   331    343   
   332    344   /*
................................................................................
   334    346   ** graph.
   335    347   */
   336    348   void timeline_output_graph_javascript(GraphContext *pGraph){
   337    349     if( pGraph && pGraph->nErr==0 ){
   338    350       GraphRow *pRow;
   339    351       int i;
   340    352       char cSep;
   341         -    @ <script type="text/JavaScript">
          353  +    @ <script  type="text/JavaScript">
          354  +    @ /* <![CDATA[ */
   342    355       cgi_printf("var rowinfo = [\n");
   343    356       for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
   344    357         cgi_printf("{id:\"m%d\",bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,au:",
   345    358           pRow->idx,
   346    359           pRow->zBgClr,
   347    360           pRow->iRail,
   348    361           pRow->bDescender,
................................................................................
   350    363           pRow->mergeUpto,
   351    364           pRow->aiRaiser[pRow->iRail]
   352    365         );
   353    366         cSep = '[';
   354    367         for(i=0; i<GR_MAX_RAIL; i++){
   355    368           if( i==pRow->iRail ) continue;
   356    369           if( pRow->aiRaiser[i]>0 ){
   357         -          cgi_printf("%c%d,%d", cSep, pGraph->railMap[i], pRow->aiRaiser[i]);
          370  +          cgi_printf("%c%d,%d", cSep, i, pRow->aiRaiser[i]);
   358    371             cSep = ',';
   359    372           }
   360    373         }
   361    374         if( cSep=='[' ) cgi_printf("[");
   362    375         cgi_printf("],mi:");
   363    376         cSep = '[';
   364    377         for(i=0; i<GR_MAX_RAIL; i++){
   365    378           if( pRow->mergeIn & (1<<i) ){
   366         -          cgi_printf("%c%d", cSep, pGraph->railMap[i]);
          379  +          cgi_printf("%c%d", cSep, i);
   367    380             cSep = ',';
   368    381           }
   369    382         }
   370    383         if( cSep=='[' ) cgi_printf("[");
   371    384         cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
   372    385       }
   373    386       cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
................................................................................
   480    493       @   var canvasY = absoluteY("canvas");
   481    494       @   var left = absoluteX(rowinfo[0].id) - absoluteX("canvas") + 15;
   482    495       @   var width = nrail*20;
   483    496       @   for(var i in rowinfo){
   484    497       @     rowinfo[i].y = absoluteY(rowinfo[i].id) + 10 - canvasY;
   485    498       @     rowinfo[i].x = left + rowinfo[i].r*20;
   486    499       @   }
   487         -    @   var btm = rowinfo[rowinfo.length-1].y + 20;
          500  +    @   var btm = absoluteY("grbtm") + 10 - canvasY;
   488    501       @   if( btm<32768 ){
   489    502       @     canvasDiv.innerHTML = '<canvas id="timeline-canvas" '+
   490    503       @        'style="position:absolute;left:'+(left-5)+'px;"' +
   491         -    @        ' width="'+width+'" height="'+btm+'"></canvas>';
          504  +    @        ' width="'+width+'" height="'+btm+'"><'+'/canvas>';
   492    505       @     realCanvas = document.getElementById('timeline-canvas');
   493    506       @   }else{
   494    507       @     realCanvas = 0;
   495    508       @   }
   496    509       @   var context;
   497    510       @   if( realCanvas && realCanvas.getContext
   498    511       @        && (context = realCanvas.getContext('2d'))) {
................................................................................
   516    529       @   if( h!=lastY ){
   517    530       @     renderGraph();
   518    531       @     lastY = h;
   519    532       @   }
   520    533       @   setTimeout("checkHeight();", 1000);
   521    534       @ }
   522    535       @ checkHeight();
          536  +    @ /* ]]> */
   523    537       @ </script>
   524    538     }
   525    539   }
   526    540   
   527    541   /*
   528    542   ** Create a temporary table suitable for storing timeline data.
   529    543   */
................................................................................
   625    639   **    c=TIMESTAMP    "circa" this date.
   626    640   **    n=COUNT        number of events in output
   627    641   **    p=RID          artifact RID and up to COUNT parents and ancestors
   628    642   **    d=RID          artifact RID and up to COUNT descendants
   629    643   **    t=TAGID        show only check-ins with the given tagid
   630    644   **    r=TAGID        show check-ins related to tagid
   631    645   **    u=USER         only if belonging to this user
   632         -**    y=TYPE         'ci', 'w', 't'
          646  +**    y=TYPE         'ci', 'w', 't', 'e'
   633    647   **    s=TEXT         string search (comment and brief)
   634    648   **    ng             Suppress the graph if present
   635    649   **
   636    650   ** p= and d= can appear individually or together.  If either p= or d=
   637    651   ** appear, then u=, y=, a=, and b= are ignored.
   638    652   **
   639    653   ** If a= and b= appear, only a= is used.  If neither appear, the most
................................................................................
   735    749         blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>",
   736    750                      g.zBaseURL, zUuid, zUuid);
   737    751       }else{
   738    752         blob_appendf(&desc, " of check-in [%.10s]", zUuid);
   739    753       }
   740    754     }else{
   741    755       int n;
   742         -    const char *zEType = "event";
          756  +    const char *zEType = "timeline item";
   743    757       char *zDate;
   744    758       char *zNEntry = mprintf("%d", nEntry);
   745    759       url_initialize(&url, "timeline");
   746    760       url_add_parameter(&url, "n", zNEntry);
   747    761       if( tagid>0 ){
   748         -      zType = "ci";
          762  +      if( zType[0]!='e' ) zType = "ci";
   749    763         blob_appendf(&sql,
   750    764           "AND (EXISTS(SELECT 1 FROM tagxref"
   751    765                       " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
   752    766   
   753         -      if( zBrName ){
          767  +      if( zBrName && zType[0]=='c' ){
   754    768           /* The next two blob_appendf() calls add SQL that causes checkins that
   755    769           ** are not part of the branch which are parents or childen of the branch
   756    770           ** to be included in the report.  This related check-ins are useful
   757    771           ** in helping to visualize what has happened on a quiescent branch 
   758    772           ** that is infrequently merged with a much more activate branch.
   759    773           */
   760    774           url_add_parameter(&url, "r", zBrName);
................................................................................
   767    781         }else{
   768    782           url_add_parameter(&url, "t", zTagName);
   769    783         }
   770    784         blob_appendf(&sql, ")");
   771    785       }
   772    786       if( (zType[0]=='w' && !g.okRdWiki)
   773    787        || (zType[0]=='t' && !g.okRdTkt)
          788  +     || (zType[0]=='e' && !g.okRdWiki)
   774    789        || (zType[0]=='c' && !g.okRead)
   775    790       ){
   776    791         zType = "all";
   777    792       }
   778    793       if( zType[0]=='a' ){
   779    794         if( !g.okRead || !g.okRdWiki || !g.okRdTkt ){
   780    795           char cSep = '(';
   781    796           blob_appendf(&sql, " AND event.type IN ");
   782    797           if( g.okRead ){
   783    798             blob_appendf(&sql, "%c'ci'", cSep);
   784    799             cSep = ',';
   785    800           }
   786    801           if( g.okRdWiki ){
   787         -          blob_appendf(&sql, "%c'w'", cSep);
          802  +          blob_appendf(&sql, "%c'w','e'", cSep);
   788    803             cSep = ',';
   789    804           }
   790    805           if( g.okRdTkt ){
   791    806             blob_appendf(&sql, "%c't'", cSep);
   792    807             cSep = ',';
   793    808           }
   794    809           blob_appendf(&sql, ")");
................................................................................
   798    813         url_add_parameter(&url, "y", zType);
   799    814         if( zType[0]=='c' ){
   800    815           zEType = "checkin";
   801    816         }else if( zType[0]=='w' ){
   802    817           zEType = "wiki edit";
   803    818         }else if( zType[0]=='t' ){
   804    819           zEType = "ticket change";
          820  +      }else if( zType[0]=='e' ){
          821  +        zEType = "event";
   805    822         }
   806    823       }
   807    824       if( zUser ){
   808    825         blob_appendf(&sql, " AND event.user=%Q", zUser);
   809    826         url_add_parameter(&url, "u", zUser);
   810    827       }
   811    828       if ( zSearch ){
   812    829         blob_appendf(&sql,
   813    830           " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
   814    831           zSearch, zSearch);
   815    832         url_add_parameter(&url, "s", zSearch);
   816    833       }
   817    834       if( zAfter ){
   818         -      while( isspace(zAfter[0]) ){ zAfter++; }
          835  +      while( fossil_isspace(zAfter[0]) ){ zAfter++; }
   819    836         if( zAfter[0] ){
   820    837           blob_appendf(&sql, 
   821    838              " AND event.mtime>=(SELECT julianday(%Q, 'utc'))"
   822    839              " ORDER BY event.mtime ASC", zAfter);
   823    840           url_add_parameter(&url, "a", zAfter);
   824    841           zBefore = 0;
   825    842         }else{
   826    843           zAfter = 0;
   827    844         }
   828    845       }else if( zBefore ){
   829         -      while( isspace(zBefore[0]) ){ zBefore++; }
          846  +      while( fossil_isspace(zBefore[0]) ){ zBefore++; }
   830    847         if( zBefore[0] ){
   831    848           blob_appendf(&sql, 
   832    849              " AND event.mtime<=(SELECT julianday(%Q, 'utc'))"
   833    850              " ORDER BY event.mtime DESC", zBefore);
   834    851           url_add_parameter(&url, "b", zBefore);
   835    852          }else{
   836    853           zBefore = 0;
   837    854         }
   838    855       }else if( zCirca ){
   839         -      while( isspace(zCirca[0]) ){ zCirca++; }
          856  +      while( fossil_isspace(zCirca[0]) ){ zCirca++; }
   840    857         if( zCirca[0] ){
   841    858           double rCirca = db_double(0.0, "SELECT julianday(%Q, 'utc')", zCirca);
   842    859           Blob sql2;
   843    860           blob_init(&sql2, blob_str(&sql), -1);
   844    861           blob_appendf(&sql2,
   845    862               " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
   846    863               rCirca, (nEntry+1)/2
................................................................................
   880    897         blob_appendf(&desc, " tagged with \"%h\"", zTagName);
   881    898         tmFlags |= TIMELINE_DISJOINT;
   882    899       }else if( zBrName ){
   883    900         blob_appendf(&desc, " related to \"%h\"", zBrName);
   884    901         tmFlags |= TIMELINE_DISJOINT;
   885    902       }
   886    903       if( zAfter ){
   887         -      blob_appendf(&desc, " occurring on or after %h.<br>", zAfter);
          904  +      blob_appendf(&desc, " occurring on or after %h.<br />", zAfter);
   888    905       }else if( zBefore ){
   889         -      blob_appendf(&desc, " occurring on or before %h.<br>", zBefore);
          906  +      blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
   890    907       }else if( zCirca ){
   891         -      blob_appendf(&desc, " occurring around %h.<br>", zCirca);
          908  +      blob_appendf(&desc, " occurring around %h.<br />", zCirca);
   892    909       }
   893    910       if( zSearch ){
   894    911         blob_appendf(&desc, " matching \"%h\"", zSearch);
   895    912       }
   896    913       if( g.okHistory ){
   897    914         if( zAfter || n==nEntry ){
   898    915           zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
................................................................................
   912    929           }
   913    930           if( zType[0]!='c' && g.okRead ){
   914    931             timeline_submenu(&url, "Checkins Only", "y", "ci", 0);
   915    932           }
   916    933           if( zType[0]!='t' && g.okRdTkt ){
   917    934             timeline_submenu(&url, "Tickets Only", "y", "t", 0);
   918    935           }
          936  +        if( zType[0]!='e' && g.okRdWiki ){
          937  +          timeline_submenu(&url, "Events Only", "y", "e", 0);
          938  +        }
   919    939         }
   920    940         if( nEntry>20 ){
   921         -        timeline_submenu(&url, "20 Events", "n", "20", 0);
          941  +        timeline_submenu(&url, "20 Entries", "n", "20", 0);
   922    942         }
   923    943         if( nEntry<200 ){
   924         -        timeline_submenu(&url, "200 Events", "n", "200", 0);
          944  +        timeline_submenu(&url, "200 Entries", "n", "200", 0);
   925    945         }
   926    946       }
   927    947     }
          948  +  if( P("showsql") ){
          949  +    @ <blockquote>%h(blob_str(&sql))</blockquote>
          950  +  }
   928    951     blob_zero(&sql);
   929    952     db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC /*scan*/");
   930    953     @ <h2>%b(&desc)</h2>
   931    954     blob_reset(&desc);
   932    955     www_print_timeline(&q, tmFlags, 0);
   933    956     db_finalize(&q);
   934    957     style_footer();
................................................................................
  1035   1058   ** Return true if the input string is a date in the ISO 8601 format:
  1036   1059   ** YYYY-MM-DD.
  1037   1060   */
  1038   1061   static int isIsoDate(const char *z){
  1039   1062     return strlen(z)==10
  1040   1063         && z[4]=='-'
  1041   1064         && z[7]=='-'
  1042         -      && isdigit(z[0])
  1043         -      && isdigit(z[5]);
         1065  +      && fossil_isdigit(z[0])
         1066  +      && fossil_isdigit(z[5]);
  1044   1067   }
  1045   1068   
  1046   1069   /*
  1047   1070   ** COMMAND: timeline
  1048   1071   **
  1049   1072   ** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?-n N? ?-t TYPE?
  1050   1073   **

Changes to src/tkt.c.

    51     51     int i;
    52     52     if( nField>0 ) return;
    53     53     db_prepare(&q, "PRAGMA table_info(ticket)");
    54     54     while( db_step(&q)==SQLITE_ROW ){
    55     55       const char *zField = db_column_text(&q, 1);
    56     56       if( strncmp(zField,"tkt_",4)==0 ) continue;
    57     57       if( nField%10==0 ){
    58         -      azField = realloc(azField, sizeof(azField)*3*(nField+10) );
    59         -      if( azField==0 ){
    60         -        fossil_fatal("out of memory");
    61         -      }
           58  +      azField = fossil_realloc(azField, sizeof(azField)*3*(nField+10) );
    62     59       }
    63     60       azField[nField] = mprintf("%s", zField);
    64     61       nField++;
    65     62     }
    66     63     db_finalize(&q);
    67     64     qsort(azField, nField, sizeof(azField[0]), nameCmpr);
    68     65     azAppend = &azField[nField];
................................................................................
   215    212   /*
   216    213   ** Rebuild an entire entry in the TICKET table
   217    214   */
   218    215   void ticket_rebuild_entry(const char *zTktUuid){
   219    216     char *zTag = mprintf("tkt-%s", zTktUuid);
   220    217     int tagid = tag_findid(zTag, 1);
   221    218     Stmt q;
   222         -  Manifest manifest;
   223         -  Blob content;
          219  +  Manifest *pTicket;
   224    220     int createFlag = 1;
   225    221     
   226    222     db_multi_exec(
   227    223        "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid
   228    224     );
   229    225     db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
   230    226     while( db_step(&q)==SQLITE_ROW ){
   231    227       int rid = db_column_int(&q, 0);
   232         -    content_get(rid, &content);
   233         -    manifest_parse(&manifest, &content);
   234         -    ticket_insert(&manifest, createFlag, rid);
   235         -    manifest_ticket_event(rid, &manifest, createFlag, tagid);
   236         -    manifest_clear(&manifest);
          228  +    pTicket = manifest_get(rid, CFTYPE_TICKET);
          229  +    if( pTicket ){
          230  +      ticket_insert(pTicket, createFlag, rid);
          231  +      manifest_ticket_event(rid, pTicket, createFlag, tagid);
          232  +      manifest_destroy(pTicket);
          233  +    }
   237    234       createFlag = 0;
   238    235     }
   239    236     db_finalize(&q);
   240    237   }
   241    238   
   242    239   /*
   243    240   ** Create the subscript interpreter and load the "common" code.
................................................................................
   311    308     }
   312    309     if( g.okNewTkt ){
   313    310       style_submenu_element("New Ticket", "Create a new ticket",
   314    311           "%s/tktnew", g.zTop);
   315    312     }
   316    313     if( g.okApndTkt && g.okAttach ){
   317    314       style_submenu_element("Attach", "Add An Attachment",
   318         -        "%s/attachadd?tkt=%T&from=%s/tktview/%t",
          315  +        "%s/attachadd?tkt=%T&amp;from=%s/tktview/%t",
   319    316           g.zTop, zUuid, g.zTop, zUuid);
   320    317     }
   321    318     style_header("View Ticket");
   322    319     if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
   323    320     ticket_init();
   324    321     initializeVariablesFromDb();
   325    322     zScript = ticket_viewpage_code();
................................................................................
   340    337          " ORDER BY mtime DESC",
   341    338          zFullName);
   342    339       while( db_step(&q)==SQLITE_ROW ){
   343    340         const char *zDate = db_column_text(&q, 0);
   344    341         const char *zFile = db_column_text(&q, 1);
   345    342         const char *zUser = db_column_text(&q, 2);
   346    343         if( cnt==0 ){
   347         -        @ <hr><h2>Attachments:</h2>
          344  +        @ <hr /><h2>Attachments:</h2>
   348    345           @ <ul>
   349    346         }
   350    347         cnt++;
   351         -      @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)">
   352         -      @ %h(zFile)</a> add by %h(zUser) on
          348  +      @ <li>
          349  +      if( g.okRead && g.okHistory ){
          350  +        @ <a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&amp;file=%t(zFile)">
          351  +        @ %h(zFile)</a>
          352  +      }else{
          353  +        @ %h(zFile)
          354  +      }
          355  +      @ added by %h(zUser) on
   353    356         hyperlink_to_date(zDate, ".");
   354    357         if( g.okWrTkt && g.okAttach ){
   355         -        @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>]
          358  +        @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&amp;file=%t(zFile)&amp;from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>]
   356    359         }
          360  +      @ </li>
   357    361       }
   358    362       if( cnt ){
   359    363         @ </ul>
   360    364       }
   361    365       db_finalize(&q);
   362    366     }
   363    367    
................................................................................
   436    440       int nValue;
   437    441       if( azAppend[i] ){
   438    442         blob_appendf(&tktchng, "J +%s %z\n", azField[i],
   439    443                      fossilize(azAppend[i], -1));
   440    444       }else{
   441    445         zValue = Th_Fetch(azField[i], &nValue);
   442    446         if( zValue ){
   443         -        while( nValue>0 && isspace(zValue[nValue-1]) ){ nValue--; }
          447  +        while( nValue>0 && fossil_isspace(zValue[nValue-1]) ){ nValue--; }
   444    448           if( strncmp(zValue, azValue[i], nValue) || strlen(azValue[i])!=nValue ){
   445    449             if( strncmp(azField[i], "private_", 8)==0 ){
   446    450               zValue = db_conceal(zValue, nValue);
   447    451               blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue);
   448    452             }else{
   449    453               blob_appendf(&tktchng, "J %s %#F\n", azField[i], nValue, zValue);
   450    454             }
................................................................................
   460    464       zUuid = db_text(0, "SELECT lower(hex(randomblob(20)))");
   461    465     }
   462    466     *(const char**)pUuid = zUuid;
   463    467     blob_appendf(&tktchng, "K %s\n", zUuid);
   464    468     blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : "");
   465    469     md5sum_blob(&tktchng, &cksum);
   466    470     blob_appendf(&tktchng, "Z %b\n", &cksum);
   467         -  if( g.thTrace ){
          471  +  if( g.zPath[0]=='d' ){
          472  +    /* If called from /debug_tktnew or /debug_tktedit... */
          473  +    @ <font color="blue">
          474  +    @ <p>Ticket artifact that would have been submitted:</p>
          475  +    @ <blockquote><pre>%h(blob_str(&tktchng))</pre></blockquote>
          476  +    @ <hr /></font>
          477  +    return TH_OK;
          478  +  }else if( g.thTrace ){
   468    479       Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
   469    480                "}<br />\n",
   470    481          blob_str(&tktchng));
   471    482     }else{
   472    483       rid = content_put(&tktchng, 0, 0);
   473    484       if( rid==0 ){
   474    485         fossil_panic("trouble committing ticket: %s", g.zErrMsg);
................................................................................
   504    515     }
   505    516     style_header("New Ticket");
   506    517     if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1);
   507    518     ticket_init();
   508    519     getAllTicketFields();
   509    520     initializeVariablesFromDb();
   510    521     initializeVariablesFromCGI();
   511         -  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
          522  +  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p>
   512    523     login_insert_csrf_secret();
          524  +  @ </p>
   513    525     zScript = ticket_newpage_code();
   514    526     Th_Store("login", g.zLogin);
   515    527     Th_Store("date", db_text(0, "SELECT datetime('now')"));
   516    528     Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
   517    529                      (void*)&zNewUuid, 0);
   518    530     if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
   519    531     if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
................................................................................
   547    559     zName = P("name");
   548    560     if( P("cancel") ){
   549    561       cgi_redirectf("tktview?name=%T", zName);
   550    562     }
   551    563     style_header("Edit Ticket");
   552    564     if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
   553    565             || !validate16(zName,nName) ){
   554         -    @ <font color="red"><b>Not a valid ticket id: \"%h(zName)\"</b></font>
          566  +    @ <span class="tktError">Not a valid ticket id: \"%h(zName)\"</span>
   555    567       style_footer();
   556    568       return;
   557    569     }
   558    570     nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'",
   559    571                   zName);
   560    572     if( nRec==0 ){
   561         -    @ <font color="red"><b>No such ticket: \"%h(zName)\"</b></font>
          573  +    @ <span class="tktError">No such ticket: \"%h(zName)\"</span>
   562    574       style_footer();
   563    575       return;
   564    576     }
   565    577     if( nRec>1 ){
   566         -    @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font>
          578  +    @ <span class="tktError">%d(nRec) tickets begin with:
          579  +    @ \"%h(zName)\"</span>
   567    580       style_footer();
   568    581       return;
   569    582     }
   570    583     if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
   571    584     ticket_init();
   572    585     getAllTicketFields();
   573    586     initializeVariablesFromCGI();
   574    587     initializeVariablesFromDb();
   575         -  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
   576         -  @ <input type="hidden" name="name" value="%s(zName)">
          588  +  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p>
          589  +  @ <input type="hidden" name="name" value="%s(zName)" />
   577    590     login_insert_csrf_secret();
          591  +  @ </p>
   578    592     zScript = ticket_editpage_code();
   579    593     Th_Store("login", g.zLogin);
   580    594     Th_Store("date", db_text(0, "SELECT datetime('now')"));
   581    595     Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
   582    596     Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
   583    597     if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
   584    598     if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
................................................................................
   617    631       }
   618    632     }
   619    633     return 0;
   620    634   }
   621    635   
   622    636   /*
   623    637   ** WEBPAGE: tkttimeline
   624         -** URL: /tkttimeline?name=TICKETUUID&y=TYPE
          638  +** URL: /tkttimeline?name=TICKETUUID&amp;y=TYPE
   625    639   **
   626    640   ** Show the change history for a single ticket in timeline format.
   627    641   */
   628    642   void tkttimeline_page(void){
   629    643     Stmt q;
   630    644     char *zTitle;
   631    645     char *zSQL;
................................................................................
   637    651   
   638    652     login_check_credentials();
   639    653     if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; }
   640    654     zUuid = PD("name","");
   641    655     zType = PD("y","a");
   642    656     if( zType[0]!='c' ){
   643    657       style_submenu_element("Check-ins", "Check-ins",
   644         -       "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
          658  +       "%s/tkttimeline?name=%T&amp;y=ci", g.zTop, zUuid);
   645    659     }else{
   646    660       style_submenu_element("Timeline", "Timeline",
   647    661          "%s/tkttimeline?name=%T", g.zTop, zUuid);
   648    662     }
   649    663     style_submenu_element("History", "History",
   650    664       "%s/tkthistory/%s", g.zTop, zUuid);
   651    665     style_submenu_element("Status", "Status",
................................................................................
   737    751       "  FROM attachment, blob"
   738    752       " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
   739    753       "   AND blob.rid=attachid"
   740    754       " ORDER BY 1 DESC",
   741    755       tagid, tagid
   742    756     );
   743    757     while( db_step(&q)==SQLITE_ROW ){
   744         -    Blob content;
   745         -    Manifest m;
          758  +    Manifest *pTicket;
   746    759       char zShort[12];
   747    760       const char *zDate = db_column_text(&q, 0);
   748    761       int rid = db_column_int(&q, 1);
   749    762       const char *zChngUuid = db_column_text(&q, 2);
   750    763       const char *zFile = db_column_text(&q, 4);
   751    764       memcpy(zShort, zChngUuid, 10);
   752    765       zShort[10] = 0;
................................................................................
   761    774           @ <p>Add attachment "%h(zFile)"
   762    775         }
   763    776         @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>]
   764    777         @ (rid %d(rid)) by
   765    778         hyperlink_to_user(zUser,zDate," on");
   766    779         hyperlink_to_date(zDate, ".</p>");
   767    780       }else{
   768         -      content_get(rid, &content);
   769         -      if( manifest_parse(&m, &content) && m.type==CFTYPE_TICKET ){
          781  +      pTicket = manifest_get(rid, CFTYPE_TICKET);
          782  +      if( pTicket ){
   770    783           @
   771    784           @ <p>Ticket change
   772    785           @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>]
   773    786           @ (rid %d(rid)) by
   774         -        hyperlink_to_user(m.zUser,zDate," on");
          787  +        hyperlink_to_user(pTicket->zUser,zDate," on");
   775    788           hyperlink_to_date(zDate, ":");
   776         -        ticket_output_change_artifact(&m);
   777    789           @ </p>
          790  +        ticket_output_change_artifact(pTicket);
   778    791         }
   779         -      manifest_clear(&m);
          792  +      manifest_destroy(pTicket);
   780    793       }
   781    794     }
   782    795     db_finalize(&q);
   783    796     style_footer();
   784    797   }
   785    798   
   786    799   /*
................................................................................
   818    831       }else{
   819    832         @ <li>Change %h(z) to "%h(blob_str(&val))"</li>
   820    833       }
   821    834       blob_reset(&val);
   822    835     }
   823    836     @ </ol>
   824    837   }
          838  +
          839  +/*
          840  +** COMMAND: ticket
          841  +** Usage: %fossil ticket SUBCOMMAND ...
          842  +**
          843  +** Run various subcommands to control tickets
          844  +**
          845  +**     %fossil ticket show (REPORTTITLE|REPORTNR) ?TICKETFILTER? ?options?
          846  +**
          847  +**         options can be:
          848  +**           ?-l|--limit LIMITCHAR?
          849  +**           ?-q|--quote?
          850  +**           ?-R|--repository FILE?
          851  +**
          852  +**         Run the ticket report, identified by the report format title
          853  +**         used in the gui. The data is written as flat file on stdout,
          854  +**         using "," as separator. The seperator "," can be changed using
          855  +**         the -l or --limit option.
          856  +**         If TICKETFILTER is given on the commandline, the query is
          857  +**         limited with a new WHERE-condition.
          858  +**           example:  Report lists a column # with the uuid
          859  +**                     TICKETFILTER may be [#]='uuuuuuuuu'
          860  +**           example:  Report only lists rows with status not open
          861  +**                     TICKETFILTER: status != 'open'
          862  +**         If the option -q|--quote is used, the tickets are encoded by
          863  +**         quoting special chars(space -> \\s, tab -> \\t, newline -> \\n,
          864  +**         cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\).
          865  +**         Otherwise, the simplified encoding as on the show report raw
          866  +**         page in the gui is used.
          867  +**
          868  +**         Instead of the report title its possible to use the report
          869  +**         number. Using the special report number 0 list all columns,
          870  +**         defined in the ticket table.
          871  +**
          872  +**     %fossil ticket list fields
          873  +**
          874  +**         list all fields, defined for ticket in the fossil repository
          875  +**
          876  +**     %fossil ticket list reports
          877  +**
          878  +**         list all ticket reports, defined in the fossil repository
          879  +**
          880  +**     %fossil ticket set TICKETUUID FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote?
          881  +**     %fossil ticket change TICKETUUID FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote?
          882  +**
          883  +**         change ticket identified by TICKETUUID and set the value of
          884  +**         field FIELD to VALUE. Valid field descriptions are:
          885  +**            status, type, severity, priority, resolution,
          886  +**            foundin, private_contact, resolution, title or comment
          887  +**         Field names given above are the ones, defined in a standard
          888  +**         fossil environment. If you have added, deleted columns, you
          889  +**         change the all your configured columns.
          890  +**         You can use more than one field/value pair on the commandline.
          891  +**         Using -q|--quote  enables the special character decoding as
          892  +**         in "ticket show". So it's possible, to set multiline text or
          893  +**         text with special characters.
          894  +**
          895  +**     %fossil ticket add FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote?
          896  +**
          897  +**         like set, but create a new ticket with the given values.
          898  +**
          899  +** The values in set|add are not validated against the definitions
          900  +** given in "Ticket Common Script".
          901  +*/
          902  +void ticket_cmd(void){
          903  +  int n;
          904  +
          905  +  /* do some ints, we want to be inside a checkout */
          906  +  db_find_and_open_repository(1);
          907  +  user_select();
          908  +  /*
          909  +  ** Check that the user exists.
          910  +  */
          911  +  if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
          912  +    fossil_fatal("no such user: %s", g.zLogin);
          913  +  }
          914  +
          915  +  if( g.argc<3 ){
          916  +    usage("add|fieldlist|set|show");
          917  +  }else{
          918  +    n = strlen(g.argv[2]);
          919  +    if( n==1 && g.argv[2][0]=='s' ){
          920  +      /* set/show cannot be distinguished, so show the usage */
          921  +      usage("add|fieldlist|set|show");
          922  +    }else if( strncmp(g.argv[2],"list",n)==0 ){
          923  +      if( g.argc==3 ){
          924  +        usage("list fields|reports");
          925  +      }else{
          926  +        n = strlen(g.argv[3]);
          927  +        if( !strncmp(g.argv[3],"fields",n) ){
          928  +          /* simply show all field names */
          929  +          int i;
          930  +
          931  +          /* read all available ticket fields */
          932  +          getAllTicketFields();
          933  +          for(i=0; i<nField; i++){
          934  +            printf("%s\n",azField[i]);
          935  +          }
          936  +        }else if( !strncmp(g.argv[3],"reports",n) ){
          937  +          rpt_list_reports();
          938  +        }else{
          939  +          fossil_fatal("unknown ticket list option '%s'!",g.argv[3]);
          940  +        }
          941  +      }
          942  +    }else{
          943  +      /* add a new ticket or set fields on existing tickets */
          944  +      tTktShowEncoding tktEncoding;
          945  +
          946  +      tktEncoding = find_option("quote","q",0) ? tktFossilize : tktNoTab;
          947  +      
          948  +      if( strncmp(g.argv[2],"show",n)==0 ){
          949  +        if( g.argc==3 ){
          950  +          usage("show REPORTNR");
          951  +        }else{
          952  +          const char *zRep = 0;
          953  +          const char *zSep = 0;
          954  +          const char *zFilterUuid = 0;
          955  +
          956  +          zSep = find_option("limit","l",1);
          957  +          zRep = g.argv[3];
          958  +          if( !strcmp(zRep,"0") ){
          959  +            zRep = 0;
          960  +          }
          961  +          if( g.argc>4 ){
          962  +            zFilterUuid = g.argv[4];
          963  +          }
          964  +
          965  +          rptshow( zRep, zSep, zFilterUuid, tktEncoding );
          966  +
          967  +        }
          968  +      }else{
          969  +        /* add a new ticket or update an existing ticket */
          970  +        enum { set,add,err } eCmd = err;
          971  +        int i = 0;
          972  +        int rid;
          973  +        const char *zTktUuid = 0;
          974  +        Blob tktchng, cksum;
          975  +
          976  +        /* get command type (set/add) and get uuid, if needed for set */
          977  +        if( strncmp(g.argv[2],"set",n)==0 || strncmp(g.argv[2],"change",n)==0 ){
          978  +          eCmd = set;
          979  +          if( g.argc==3 ){
          980  +            usage("set TICKETUUID");
          981  +          }
          982  +          zTktUuid = db_text(0, 
          983  +            "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
          984  +          );
          985  +          if( !zTktUuid ){
          986  +            fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
          987  +          }
          988  +          i=4;
          989  +        }else if( strncmp(g.argv[2],"add",n)==0 ){
          990  +          eCmd = add;
          991  +          i = 3;
          992  +          zTktUuid = db_text(0, "SELECT lower(hex(randomblob(20)))");
          993  +        }
          994  +        /* none of set/add, so show the usage! */
          995  +        if( eCmd==err ){
          996  +          usage("add|fieldlist|set|show");
          997  +        }
          998  +        
          999  +        /* read all given ticket field/value pairs from command line */
         1000  +        if( i==g.argc ){
         1001  +          fossil_fatal("empty %s command aborted!",g.argv[2]);
         1002  +        }
         1003  +        getAllTicketFields();
         1004  +        /* read commandline and assign fields in the azValue array */
         1005  +        while( i<g.argc ){
         1006  +          char *zFName;
         1007  +          char *zFValue;
         1008  +          int j;
         1009  +
         1010  +          zFName = g.argv[i++];
         1011  +          if( i==g.argc ){
         1012  +            fossil_fatal("missing value for '%s'!",zFName);
         1013  +          }
         1014  +          zFValue = g.argv[i++];
         1015  +          j = fieldId(zFName);
         1016  +          if( tktEncoding == tktFossilize ){
         1017  +            zFValue=mprintf("%s",zFValue);
         1018  +            defossilize(zFValue);
         1019  +          }
         1020  +          if( j == -1 ){
         1021  +            fossil_fatal("unknown field name '%s'!",zFName);
         1022  +          }else{
         1023  +            azValue[j] = zFValue;
         1024  +          }
         1025  +        }
         1026  +
         1027  +        /* now add the needed artifacts to the repository */
         1028  +        blob_zero(&tktchng);
         1029  +        { /* add the time to the ticket manifest */
         1030  +          char *zDate;
         1031  +
         1032  +          zDate = db_text(0, "SELECT datetime('now')");
         1033  +          zDate[10] = 'T';
         1034  +          blob_appendf(&tktchng, "D %s\n", zDate);
         1035  +          free(zDate);
         1036  +        }
         1037  +        /* append defined elements */
         1038  +        for(i=0; i<nField; i++){
         1039  +          char *zValue;
         1040  +
         1041  +          zValue = azValue[i];
         1042  +          if( azValue[i] && azValue[i][0] ){
         1043  +            if( strncmp(azField[i], "private_", 8)==0 ){
         1044  +              zValue = db_conceal(zValue, strlen(zValue));
         1045  +              blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue);
         1046  +            }else{
         1047  +              blob_appendf(&tktchng, "J %s %#F\n",
         1048  +                           azField[i], strlen(zValue), zValue);
         1049  +            }
         1050  +            if( tktEncoding == tktFossilize ){
         1051  +              free(azValue[i]);
         1052  +            }
         1053  +          }
         1054  +        }
         1055  +        blob_appendf(&tktchng, "K %s\n", zTktUuid);
         1056  +        blob_appendf(&tktchng, "U %F\n", g.zLogin);
         1057  +        md5sum_blob(&tktchng, &cksum);
         1058  +        blob_appendf(&tktchng, "Z %b\n", &cksum);
         1059  +        rid = content_put(&tktchng, 0, 0);
         1060  +        if( rid==0 ){
         1061  +          fossil_panic("trouble committing ticket: %s", g.zErrMsg);
         1062  +        }
         1063  +        manifest_crosslink_begin();
         1064  +        manifest_crosslink(rid, &tktchng);
         1065  +        manifest_crosslink_end();
         1066  +	printf("ticket %s succeeded for UID %s\n",
         1067  +	       (eCmd==set?"set":"add"),zTktUuid);
         1068  +      }
         1069  +    }
         1070  +  }
         1071  +}

Changes to src/tktsetup.c.

   121    121       db_unset(zDbField, 0);
   122    122       if( xRebuild ) xRebuild();
   123    123       z = zDfltValue;
   124    124     }else if( isSubmit ){
   125    125       char *zErr = 0;
   126    126       login_verify_csrf_secret();
   127    127       if( xText && (zErr = xText(z))!=0 ){
   128         -      @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
          128  +      @ <p class="tktsetupError">ERROR: %h(zErr)</p>
   129    129       }else{
   130    130         db_set(zDbField, z, 0);
   131    131         if( xRebuild ) xRebuild();
   132    132         cgi_redirect("tktsetup");
   133    133       }
   134    134     }
   135         -  @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
          135  +  @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="post"><div>
   136    136     login_insert_csrf_secret();
   137    137     @ <p>%s(zDesc)</p>
   138    138     @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
   139         -  @ <blockquote>
   140         -  @ <input type="submit" name="submit" value="Apply Changes">
   141         -  @ <input type="submit" name="clear" value="Revert To Default">
   142         -  @ <input type="submit" name="setup" value="Cancel">
   143         -  @ </blockquote>
   144         -  @ </form>
   145         -  @ <hr>
          139  +  @ <blockquote><p>
          140  +  @ <input type="submit" name="submit" value="Apply Changes" />
          141  +  @ <input type="submit" name="clear" value="Revert To Default" />
          142  +  @ <input type="submit" name="setup" value="Cancel" />
          143  +  @ </p></blockquote>
          144  +  @ </div></form>
          145  +  @ <hr />
   146    146     @ <h2>Default %s(zTitle)</h2>
   147    147     @ <blockquote><pre>
   148    148     @ %h(zDfltValue)
   149    149     @ </pre></blockquote>
   150    150     style_footer();
   151    151   }
   152    152   
   153    153   /*
   154    154   ** WEBPAGE: tktsetup_tab
   155    155   */
   156    156   void tktsetup_tab_page(void){
   157    157     static const char zDesc[] =
   158         -  @ <p>Enter a valid CREATE TABLE statement for the "ticket" table.  The
          158  +  @ Enter a valid CREATE TABLE statement for the "ticket" table.  The
   159    159     @ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime"
   160         -  @ with an unique index on "tkt_uuid" and "tkt_mtime".</p>
          160  +  @ with an unique index on "tkt_uuid" and "tkt_mtime".
   161    161     ;
   162    162     tktsetup_generic(
   163    163       "Ticket Table Schema",
   164    164       "ticket-table",
   165    165       zDefaultTicketTable,
   166    166       zDesc,
   167    167       ticket_schema_check,
................................................................................
   227    227   }
   228    228   
   229    229   /*
   230    230   ** WEBPAGE: tktsetup_com
   231    231   */
   232    232   void tktsetup_com_page(void){
   233    233     static const char zDesc[] =
   234         -  @ <p>Enter TH1 script that initializes variables prior to generating
   235         -  @ any of the ticket view, edit, or creation pages.</p>
          234  +  @ Enter TH1 script that initializes variables prior to generating
          235  +  @ any of the ticket view, edit, or creation pages.
   236    236     ;
   237    237     tktsetup_generic(
   238    238       "Ticket Common Script",
   239    239       "ticket-common",
   240    240       zDefaultTicketCommon,
   241    241       zDesc,
   242    242       0,
................................................................................
   248    248   static const char zDefaultNew[] =
   249    249   @ <th1>
   250    250   @   if {[info exists submit]} {
   251    251   @      set status Open
   252    252   @      submit_ticket
   253    253   @   }
   254    254   @ </th1>
   255         -@ <h1 align="center">Enter A New Ticket</h1>
          255  +@ <h1 style="text-align: center;">Enter A New Ticket</h1>
   256    256   @ <table cellpadding="5">
   257    257   @ <tr>
   258    258   @ <td colspan="2">
   259         -@ Enter a one-line summary of the ticket:<br>
   260         -@ <input type="text" name="title" size="60" value="$<title>">
          259  +@ Enter a one-line summary of the ticket:<br />
          260  +@ <input type="text" name="title" size="60" value="$<title>" />
   261    261   @ </td>
   262    262   @ </tr>
   263    263   @ 
   264    264   @ <tr>
   265         -@ <td align="right">Type:
          265  +@ <td style="text-align: center;">Type:
   266    266   @ <th1>combobox type $type_choices 1</th1>
   267    267   @ </td>
   268    268   @ <td>What type of ticket is this?</td>
   269    269   @ </tr>
   270    270   @ 
   271    271   @ <tr>
   272         -@ <td align="right">Version: 
   273         -@ <input type="text" name="foundin" size="20" value="$<foundin>">
          272  +@ <td style="text-align: center;">Version: 
          273  +@ <input type="text" name="foundin" size="20" value="$<foundin>" />
   274    274   @ </td>
   275    275   @ <td>In what version or build number do you observe the problem?</td>
   276    276   @ </tr>
   277    277   @ 
   278    278   @ <tr>
   279         -@ <td align="right">Severity:
          279  +@ <td style="text-align: center;">Severity:
   280    280   @ <th1>combobox severity $severity_choices 1</th1>
   281    281   @ </td>
   282    282   @ <td>How debilitating is the problem?  How badly does the problem
   283    283   @ affect the operation of the product?</td>
   284    284   @ </tr>
   285    285   @ 
   286    286   @ <tr>
   287         -@ <td align="right">EMail:
   288         -@ <input type="text" name="private_contact" value="$<private_contact>" size="30">
          287  +@ <td style="text-align: center;">EMail:
          288  +@ <input type="text" name="private_contact" value="$<private_contact>" size="30" />
   289    289   @ </td>
   290         -@ <td><u>Not publicly visible</u>. Used by developers to contact you with
   291         -@ questions.</td>
          290  +@ <td><span style="text-decoration: underline;">Not publicly visible</span>.
          291  +@ Used by developers to contact you with questions.</td>
   292    292   @ </tr>
   293    293   @ 
   294    294   @ <tr>
   295    295   @ <td colspan="2">
   296    296   @ Enter a detailed description of the problem.
   297    297   @ For code defects, be sure to provide details on exactly how
   298    298   @ the problem can be reproduced.  Provide as much detail as
   299    299   @ possible.
   300         -@ <br>
          300  +@ <br />
   301    301   @ <th1>set nline [linecount $comment 50 10]</th1>
   302    302   @ <textarea name="comment" cols="80" rows="$nline"
   303         -@  wrap="virtual" class="wikiedit">$<comment></textarea><br>
   304         -@ <input type="submit" name="preview" value="Preview">
          303  +@  wrap="virtual" class="wikiedit">$<comment></textarea><br />
          304  +@ <input type="submit" name="preview" value="Preview" /></td>
   305    305   @ </tr>
   306    306   @
   307    307   @ <th1>enable_output [info exists preview]</th1>
   308    308   @ <tr><td colspan="2">
   309         -@ Description Preview:<br><hr>
          309  +@ Description Preview:<br /><hr />
   310    310   @ <th1>wiki $comment</th1>
   311         -@ <hr>
          311  +@ <hr />
   312    312   @ </td></tr>
   313    313   @ <th1>enable_output 1</th1>
   314    314   @ 
   315    315   @ <tr>
   316         -@ <td align="right">
   317         -@ <input type="submit" name="submit" value="Submit">
          316  +@ <td style="text-align: center;">
          317  +@ <input type="submit" name="submit" value="Submit" />
   318    318   @ </td>
   319    319   @ <td>After filling in the information above, press this button to create
   320    320   @ the new ticket</td>
   321    321   @ </tr>
   322    322   @ <tr>
   323         -@ <td align="right">
   324         -@ <input type="submit" name="cancel" value="Cancel">
          323  +@ <td style="text-align: center;">
          324  +@ <input type="submit" name="cancel" value="Cancel" />
   325    325   @ </td>
   326    326   @ <td>Abandon and forget this ticket</td>
   327    327   @ </tr>
   328    328   @ </table>
   329    329   ;
   330    330   
   331    331   /*
................................................................................
   336    336   }
   337    337   
   338    338   /*
   339    339   ** WEBPAGE: tktsetup_newpage
   340    340   */
   341    341   void tktsetup_newpage_page(void){
   342    342     static const char zDesc[] =
   343         -  @ <p>Enter HTML with embedded TH1 script that will render the "new ticket"
   344         -  @ page</p>
          343  +  @ Enter HTML with embedded TH1 script that will render the "new ticket"
          344  +  @ page
   345    345     ;
   346    346     tktsetup_generic(
   347    347       "HTML For New Tickets",
   348    348       "ticket-newpage",
   349    349       zDefaultNew,
   350    350       zDesc,
   351    351       0,
................................................................................
   352    352       0,
   353    353       40
   354    354     );
   355    355   }
   356    356   
   357    357   static const char zDefaultView[] =
   358    358   @ <table cellpadding="5">
   359         -@ <tr><td align="right">Ticket&nbsp;UUID:</td><td bgcolor="#d0d0d0" colspan="3">
   360         -@ $<tkt_uuid>
   361         -@ </td></tr>
   362         -@ <tr><td align="right">Title:</td>
   363         -@ <td bgcolor="#d0d0d0" colspan="3" valign="top">
          359  +@ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
          360  +@ <td class="tktDspValue" colspan="3">$<tkt_uuid></td></tr>
          361  +@ <tr><td class="tktDspLabel">Title:</td>
          362  +@ <td class="tktDspValue" colspan="3">
   364    363   @ <th1>wiki $title</th1>
   365    364   @ </td></tr>
   366         -@ <tr><td align="right">Status:</td><td bgcolor="#d0d0d0">
          365  +@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
   367    366   @ $<status>
   368    367   @ </td>
   369         -@ <td align="right">Type:</td><td bgcolor="#d0d0d0">
          368  +@ <td class="tktDspLabel">Type:</td><td class="tktDspValue">
   370    369   @ $<type>
   371    370   @ </td></tr>
   372         -@ <tr><td align="right">Severity:</td><td bgcolor="#d0d0d0">
          371  +@ <tr><td class="tktDspLabel">Severity:</td><td class="tktDspValue">
   373    372   @ $<severity>
   374    373   @ </td>
   375         -@ <td align="right">Priority:</td><td bgcolor="#d0d0d0">
          374  +@ <td class="tktDspLabel">Priority:</td><td class="tktDspValue">
   376    375   @ $<priority>
   377    376   @ </td></tr>
   378         -@ <tr><td align="right">Subsystem:</td><td bgcolor="#d0d0d0">
          377  +@ <tr><td class="tktDspLabel">Subsystem:</td><td class="tktDspValue">
   379    378   @ $<subsystem>
   380    379   @ </td>
   381         -@ <td align="right">Resolution:</td><td bgcolor="#d0d0d0">
          380  +@ <td class="tktDspLabel">Resolution:</td><td class="tktDspValue">
   382    381   @ $<resolution>
   383    382   @ </td></tr>
   384         -@ <tr><td align="right">Last&nbsp;Modified:</td><td bgcolor="#d0d0d0">
          383  +@ <tr><td class="tktDspLabel">Last&nbsp;Modified:</td><td class="tktDspValue">
   385    384   @ $<tkt_datetime>
   386    385   @ </td>
   387    386   @ <th1>enable_output [hascap e]</th1>
   388         -@   <td align="right">Contact:</td><td bgcolor="#d0d0d0">
          387  +@   <td class="tktDspLabel">Contact:</td><td class="tktDspValue">
   389    388   @   $<private_contact>
   390    389   @   </td>
   391    390   @ <th1>enable_output 1</th1>
   392    391   @ </tr>
   393         -@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td>
   394         -@ <td colspan="3" valign="top" bgcolor="#d0d0d0">
          392  +@ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td>
          393  +@ <td colspan="3" valign="top" class="tktDspValue">
   395    394   @ $<foundin>
   396    395   @ </td></tr>
   397    396   @ <tr><td>Description &amp; Comments:</td></tr>
   398         -@ <tr><td colspan="4" bgcolor="#d0d0d0">
   399         -@ <span  bgcolor="#d0d0d0"><th1>wiki $comment</th1></span>
          397  +@ <tr><td colspan="4" class="tktDspValue">
          398  +@ <th1>wiki $comment</th1>
   400    399   @ </td></tr>
   401    400   @ </table>
   402    401   ;
   403    402   
   404    403   
   405    404   /*
   406    405   ** Return the code used to generate the view ticket page
................................................................................
   410    409   }
   411    410   
   412    411   /*
   413    412   ** WEBPAGE: tktsetup_viewpage
   414    413   */
   415    414   void tktsetup_viewpage_page(void){
   416    415     static const char zDesc[] =
   417         -  @ <p>Enter HTML with embedded TH1 script that will render the "view ticket"
   418         -  @ page</p>
          416  +  @ Enter HTML with embedded TH1 script that will render the "view ticket" page
   419    417     ;
   420    418     tktsetup_generic(
   421    419       "HTML For Viewing Tickets",
   422    420       "ticket-viewpage",
   423    421       zDefaultView,
   424    422       zDesc,
   425    423       0,
................................................................................
   430    428   
   431    429   static const char zDefaultEdit[] =
   432    430   @ <th1>
   433    431   @   if {![info exists username]} {set username $login}
   434    432   @   if {[info exists submit]} {
   435    433   @     if {[info exists cmappnd]} {
   436    434   @       if {[string length $cmappnd]>0} {
   437         -@         set ctxt "\n\n<hr><i>[htmlize $login]"
          435  +@         set ctxt "\n\n<hr /><i>[htmlize $login]"
   438    436   @         if {$username ne $login} {
   439    437   @           set ctxt "$ctxt claiming to be [htmlize $username]"
   440    438   @         }
   441         -@         set ctxt "$ctxt added on [date]:</i><br>\n$cmappnd"
          439  +@         set ctxt "$ctxt added on [date]:</i><br />\n$cmappnd"
   442    440   @         append_field comment $ctxt
   443    441   @       }
   444    442   @     }
   445    443   @     submit_ticket
   446    444   @   }
   447    445   @ </th1>
   448    446   @ <table cellpadding="5">
   449         -@ <tr><td align="right">Title:</td><td>
   450         -@ <input type="text" name="title" value="$<title>" size="60">
          447  +@ <tr><td class="tktDspLabel">Title:</td><td>
          448  +@ <input type="text" name="title" value="$<title>" size="60" />
   451    449   @ </td></tr>
   452         -@ <tr><td align="right">Status:</td><td>
          450  +@ <tr><td class="tktDspLabel">Status:</td><td>
   453    451   @ <th1>combobox status $status_choices 1</th1>
   454    452   @ </td></tr>
   455         -@ <tr><td align="right">Type:</td><td>
          453  +@ <tr><td class="tktDspLabel">Type:</td><td>
   456    454   @ <th1>combobox type $type_choices 1</th1>
   457    455   @ </td></tr>
   458         -@ <tr><td align="right">Severity:</td><td>
          456  +@ <tr><td class="tktDspLabel">Severity:</td><td>
   459    457   @ <th1>combobox severity $severity_choices 1</th1>
   460    458   @ </td></tr>
   461         -@ <tr><td align="right">Priority:</td><td>
          459  +@ <tr><td class="tktDspLabel">Priority:</td><td>
   462    460   @ <th1>combobox priority $priority_choices 1</th1>
   463    461   @ </td></tr>
   464         -@ <tr><td align="right">Resolution:</td><td>
          462  +@ <tr><td class="tktDspLabel">Resolution:</td><td>
   465    463   @ <th1>combobox resolution $resolution_choices 1</th1>
   466    464   @ </td></tr>
   467         -@ <tr><td align="right">Subsystem:</td><td>
          465  +@ <tr><td class="tktDspLabel">Subsystem:</td><td>
   468    466   @ <th1>combobox subsystem $subsystem_choices 1</th1>
   469    467   @ </td></tr>
   470    468   @ <th1>enable_output [hascap e]</th1>
   471         -@   <tr><td align="right">Contact:</td><td>
          469  +@   <tr><td class="tktDspLabel">Contact:</td><td>
   472    470   @   <input type="text" name="private_contact" size="40"
   473         -@    value="$<private_contact>">
          471  +@    value="$<private_contact>" />
   474    472   @   </td></tr>
   475    473   @ <th1>enable_output 1</th1>
   476         -@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
   477         -@ <input type="text" name="foundin" size="50" value="$<foundin>">
          474  +@ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td><td>
          475  +@ <input type="text" name="foundin" size="50" value="$<foundin>" />
   478    476   @ </td></tr>
   479    477   @ <tr><td colspan="2">
   480    478   @ <th1>
   481    479   @   if {![info exists eall]} {set eall 0}
   482    480   @   if {[info exists aonlybtn]} {set eall 0}
   483    481   @   if {[info exists eallbtn]} {set eall 1}
   484    482   @   if {![hascap w]} {set eall 0}
   485    483   @   if {![info exists cmappnd]} {set cmappnd {}}
   486    484   @   set nline [linecount $comment 15 10]
   487    485   @   enable_output $eall
   488    486   @ </th1>
   489         -@   Description And Comments:<br>
          487  +@   Description And Comments:<br />
   490    488   @   <textarea name="comment" cols="80" rows="$nline"
   491         -@    wrap="virtual" class="wikiedit">$<comment></textarea><br>
   492         -@   <input type="hidden" name="eall" value="1">
   493         -@   <input type="submit" name="aonlybtn" value="Append Remark">
   494         -@   <input type="submit" name="preview1btn" value="Preview">
          489  +@    wrap="virtual" class="wikiedit">$<comment></textarea><br />
          490  +@   <input type="hidden" name="eall" value="1" />
          491  +@   <input type="submit" name="aonlybtn" value="Append Remark" />
          492  +@   <input type="submit" name="preview1btn" value="Preview" />
   495    493   @ <th1>enable_output [expr {!$eall}]</th1>
   496    494   @   Append Remark from 
   497         -@   <input type="text" name="username" value="$<username>" size="30">:<br>
          495  +@   <input type="text" name="username" value="$<username>" size="30" />:<br />
   498    496   @   <textarea name="cmappnd" cols="80" rows="15"
   499         -@    wrap="virtual" class="wikiedit">$<cmappnd></textarea><br>
          497  +@    wrap="virtual" class="wikiedit">$<cmappnd></textarea><br />
   500    498   @ <th1>enable_output [expr {[hascap w] && !$eall}]</th1>
   501         -@   <input type="submit" name="eallbtn" value="Edit All">
          499  +@   <input type="submit" name="eallbtn" value="Edit All" />
   502    500   @ <th1>enable_output [expr {!$eall}]</th1>
   503         -@   <input type="submit" name="preview2btn" value="Preview">
          501  +@   <input type="submit" name="preview2btn" value="Preview" />
   504    502   @ <th1>enable_output 1</th1>
   505    503   @ </td></tr>
   506    504   @
   507    505   @ <th1>enable_output [info exists preview1btn]</th1>
   508    506   @ <tr><td colspan="2">
   509         -@ Description Preview:<br><hr>
          507  +@ Description Preview:<br /><hr />
   510    508   @ <th1>wiki $comment</th1>
   511         -@ <hr>
          509  +@ <hr />
   512    510   @ </td></tr>
   513    511   @ <th1>enable_output [info exists preview2btn]</th1>
   514    512   @ <tr><td colspan="2">
   515         -@ Description Preview:<br><hr>
          513  +@ Description Preview:<br /><hr />
   516    514   @ <th1>wiki $cmappnd</th1>
   517         -@ <hr>
          515  +@ <hr />
   518    516   @ </td></tr>
   519    517   @ <th1>enable_output 1</th1>
   520    518   @
   521    519   @ <tr><td align="right"></td><td>
   522         -@ <input type="submit" name="submit" value="Submit Changes">
   523         -@ <input type="submit" name="cancel" value="Cancel">
          520  +@ <input type="submit" name="submit" value="Submit Changes" />
          521  +@ <input type="submit" name="cancel" value="Cancel" />
   524    522   @ </td></tr>
   525    523   @ </table>
   526    524   ;
   527    525   
   528    526   /*
   529    527   ** Return the code used to generate the edit ticket page
   530    528   */
................................................................................
   533    531   }
   534    532   
   535    533   /*
   536    534   ** WEBPAGE: tktsetup_editpage
   537    535   */
   538    536   void tktsetup_editpage_page(void){
   539    537     static const char zDesc[] =
   540         -  @ <p>Enter HTML with embedded TH1 script that will render the "edit ticket"
   541         -  @ page</p>
          538  +  @ Enter HTML with embedded TH1 script that will render the "edit ticket" page
   542    539     ;
   543    540     tktsetup_generic(
   544    541       "HTML For Editing Tickets",
   545    542       "ticket-editpage",
   546    543       zDefaultEdit,
   547    544       zDesc,
   548    545       0,
................................................................................
   583    580   }
   584    581   
   585    582   /*
   586    583   ** WEBPAGE: tktsetup_reportlist
   587    584   */
   588    585   void tktsetup_reportlist(void){
   589    586     static const char zDesc[] =
   590         -  @ <p>Enter HTML with embedded TH1 script that will render the "report list"
   591         -  @ page</p>
          587  +  @ Enter HTML with embedded TH1 script that will render the "report list" page
   592    588     ;
   593    589     tktsetup_generic(
   594    590       "HTML For Report List",
   595    591       "ticket-reportlist",
   596    592       zDefaultReportList,
   597    593       zDesc,
   598    594       0,
................................................................................
   631    627   }
   632    628   
   633    629   /*
   634    630   ** WEBPAGE: tktsetup_rpttplt
   635    631   */
   636    632   void tktsetup_rpttplt_page(void){
   637    633     static const char zDesc[] =
   638         -  @ <p>Enter the default ticket report format template.  This is the
          634  +  @ Enter the default ticket report format template.  This is the
   639    635     @ the template report format that initially appears when creating a
   640         -  @ new ticket summary report.</p>
          636  +  @ new ticket summary report.
   641    637     ;
   642    638     tktsetup_generic(
   643    639       "Default Report Template",
   644    640       "ticket-report-template",
   645    641       zDefaultReport,
   646    642       zDesc,
   647    643       0,
................................................................................
   672    668   }
   673    669   
   674    670   /*
   675    671   ** WEBPAGE: tktsetup_keytplt
   676    672   */
   677    673   void tktsetup_keytplt_page(void){
   678    674     static const char zDesc[] =
   679         -  @ <p>Enter the default ticket report color-key template.  This is the
          675  +  @ Enter the default ticket report color-key template.  This is the
   680    676     @ the color-key that initially appears when creating a
   681         -  @ new ticket summary report.</p>
          677  +  @ new ticket summary report.
   682    678     ;
   683    679     tktsetup_generic(
   684    680       "Default Report Color-Key Template",
   685    681       "ticket-key-template",
   686    682       zDefaultKey,
   687    683       zDesc,
   688    684       0,
................................................................................
   701    697     }
   702    698   
   703    699     if( P("setup") ){
   704    700       cgi_redirect("tktsetup");
   705    701     }
   706    702     style_header("Ticket Display On Timelines");
   707    703     db_begin_transaction();
   708         -  @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST">
          704  +  @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="post"><div>
   709    705     login_insert_csrf_secret();
   710    706   
   711         -  @ <hr>
          707  +  @ <hr />
   712    708     entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title");
   713    709     @ <p>An SQL expression in a query against the TICKET table that will
   714    710     @ return the title of the ticket for display purposes.</p>
   715    711   
   716         -  @ <hr>
          712  +  @ <hr />
   717    713     entry_attribute("Ticket Status", 40, "ticket-status-column", "s", "status");
   718    714     @ <p>The name of the column in the TICKET table that contains the ticket
   719    715     @ status in human-readable form.  Case sensitive.</p>
   720    716   
   721         -  @ <hr>
          717  +  @ <hr />
   722    718     entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c",
   723    719                     "status='Closed'");
   724    720     @ <p>An SQL expression that evaluates to true in a TICKET table query if
   725    721     @ the ticket is closed.</p>
   726    722   
   727         -  @ <hr>
          723  +  @ <hr />
   728    724     @ <p>
   729         -  @ <input type="submit"  name="submit" value="Apply Changes">
   730         -  @ <input type="submit" name="setup" value="Cancel">
          725  +  @ <input type="submit"  name="submit" value="Apply Changes" />
          726  +  @ <input type="submit" name="setup" value="Cancel" />
   731    727     @ </p>
   732         -  @ </form>
          728  +  @ </div></form>
   733    729     db_end_transaction(0);
   734    730     style_footer();
   735    731     
   736    732   }

Changes to src/translate.c.

    64     64     }
    65     65   }
    66     66   
    67     67   /*
    68     68   ** Translate the input stream into the output stream
    69     69   */
    70     70   static void trans(FILE *in, FILE *out){
    71         -  int i, j, k;        /* Loop counters */
    72         -  char c1, c2;        /* Characters used to start a comment */
    73         -  int lastWasEq = 0;  /* True if last non-whitespace character was "=" */
    74         -  char zLine[2000];   /* A single line of input */
    75         -  char zOut[4000];    /* The input line translated into appropriate output */
           71  +  int i, j, k;          /* Loop counters */
           72  +  char c1, c2;          /* Characters used to start a comment */
           73  +  int lastWasEq = 0;    /* True if last non-whitespace character was "=" */
           74  +  int lastWasComma = 0; /* True if last non-whitespace character was "," */
           75  +  char zLine[2000];     /* A single line of input */
           76  +  char zOut[4000];      /* The input line translated into appropriate output */
    76     77   
    77     78     c1 = c2 = '-';
    78     79     while( fgets(zLine, sizeof(zLine), in) ){
    79     80       for(i=0; zLine[i] && isspace(zLine[i]); i++){}
    80     81       if( zLine[i]!='@' ){
    81     82         if( inPrint || inStr ) end_block(out);
    82     83         fprintf(out,"%s",zLine);
................................................................................
    83     84                          /* 0123456789 12345 */
    84     85         if( strncmp(zLine, "/* @-comment: ", 14)==0 ){
    85     86           c1 = zLine[14];
    86     87           c2 = zLine[15];
    87     88         }
    88     89         i += strlen(&zLine[i]);
    89     90         while( i>0 && isspace(zLine[i-1]) ){ i--; }
    90         -      lastWasEq = i>0 && zLine[i-1]=='=';
    91         -    }else if( lastWasEq ){
           91  +      lastWasEq    = i>0 && zLine[i-1]=='=';
           92  +      lastWasComma = i>0 && zLine[i-1]==',';
           93  +    }else if( lastWasEq || lastWasComma){
    92     94         /* If the last non-whitespace character before the first @ was
    93         -      ** an "=" then generate a string literal.  But skip comments
           95  +      ** an "="(var init/set) or a ","(const definition in list) then
           96  +      ** generate a string literal.  But skip comments
    94     97         ** consisting of all text between c1 and c2 (default "--")
    95     98         ** and end of line.
    96     99         */
    97    100         int indent, omitline;
    98    101         i++;
    99    102         if( isspace(zLine[i]) ){ i++; }
   100    103         indent = i - 2;

Changes to src/update.c.

    22     22   #include "update.h"
    23     23   #include <assert.h>
    24     24   
    25     25   /*
    26     26   ** Return true if artifact rid is a version
    27     27   */
    28     28   int is_a_version(int rid){
    29         -  return db_exists("SELECT 1 FROM plink WHERE cid=%d", rid);
           29  +  return db_exists("SELECT 1 FROM event WHERE objid=%d AND type='ci'", rid);
    30     30   }
    31     31   
    32     32   /*
    33     33   ** COMMAND: update
    34     34   **
    35     35   ** Usage: %fossil update ?VERSION? ?FILES...?
    36     36   **
................................................................................
   109    109         fossil_fatal("Multiple descendants");
   110    110       }
   111    111       tid = db_int(0, "SELECT rid FROM leaves, event"
   112    112                       " WHERE event.objid=leaves.rid"
   113    113                       " ORDER BY event.mtime DESC"); 
   114    114     }
   115    115   
          116  +  if( tid==vid ) return;  /* Nothing to update */
   116    117     db_begin_transaction();
   117    118     vfile_check_signature(vid, 1);
   118    119     if( !nochangeFlag ) undo_begin();
   119    120     load_vfile_from_rid(tid);
   120    121   
   121    122     /*
   122    123     ** The record.fn field is used to match files against each other.  The
................................................................................
   276    277     */
   277    278     if( nochangeFlag ){
   278    279       db_end_transaction(1);  /* With --nochange, rollback changes */
   279    280     }else{
   280    281       if( g.argc<=3 ){
   281    282         /* All files updated.  Shift the current checkout to the target. */
   282    283         db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
          284  +      checkout_set_all_exe(vid);
   283    285         manifest_to_disk(tid);
   284    286         db_lset_int("checkout", tid);
   285    287       }else{
   286    288         /* A subset of files have been checked out.  Keep the current
   287    289         ** checkout unchanged. */
   288    290         db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
   289    291       }
................................................................................
   299    301   */
   300    302   int historical_version_of_file(
   301    303     const char *revision,    /* The checkin containing the file */
   302    304     const char *file,        /* Full treename of the file */
   303    305     Blob *content,           /* Put the content here */
   304    306     int errCode              /* Error code if file not found.  Panic if 0. */
   305    307   ){
   306         -  Blob mfile;
   307         -  Manifest m;
   308         -  int i, rid=0;
          308  +  Manifest *pManifest;
          309  +  ManifestFile *pFile;
          310  +  int rid=0;
   309    311     
   310    312     if( revision ){
   311    313       rid = name_to_rid(revision);
   312    314     }else{
   313    315       rid = db_lget_int("checkout", 0);
   314    316     }
   315    317     if( !is_a_version(rid) ){
   316    318       if( errCode>0 ) return errCode;
   317    319       fossil_fatal("no such checkin: %s", revision);
   318    320     }
   319         -  content_get(rid, &mfile);
          321  +  pManifest = manifest_get(rid, CFTYPE_MANIFEST);
   320    322     
   321         -  if( manifest_parse(&m, &mfile) ){
   322         -    for(i=0; i<m.nFile; i++){
   323         -      if( strcmp(m.aFile[i].zName, file)==0 ){
   324         -        rid = uuid_to_rid(m.aFile[i].zUuid, 0);
   325         -        manifest_clear(&m);
          323  +  if( pManifest ){
          324  +    manifest_file_rewind(pManifest);
          325  +    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
          326  +      if( strcmp(pFile->zName, file)==0 ){
          327  +        rid = uuid_to_rid(pFile->zUuid, 0);
          328  +        manifest_destroy(pManifest);
   326    329           return content_get(rid, content);
   327    330         }
   328    331       }
   329         -    manifest_clear(&m);
          332  +    manifest_destroy(pManifest);
   330    333       if( errCode<=0 ){
   331    334         fossil_fatal("file %s does not exist in checkin: %s", file, revision);
   332    335       }
   333    336     }else if( errCode<=0 ){
   334    337       fossil_panic("could not parse manifest for checkin: %s", revision);
   335    338     }
   336    339     return errCode;
................................................................................
   383    386         blob_reset(&fname);
   384    387       }
   385    388     }else{
   386    389       int vid;
   387    390       vid = db_lget_int("checkout", 0);
   388    391       vfile_check_signature(vid, 0);
   389    392       db_multi_exec(
          393  +      "DELETE FROM vmerge;"
   390    394         "INSERT INTO torevert "
   391    395         "SELECT pathname"
   392    396         "  FROM vfile "
   393         -      " WHERE chnged OR deleted OR rid=0 OR pathname!=origname"
          397  +      " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
   394    398       );
   395    399     }
   396    400     blob_zero(&record);
   397    401     db_prepare(&q, "SELECT name FROM torevert");
   398    402     while( db_step(&q)==SQLITE_ROW ){
   399    403       zFile = db_column_text(&q, 0);
   400    404       if( zRevision!=0 ){

Changes to src/url.c.

    15     15   **
    16     16   *******************************************************************************
    17     17   **
    18     18   ** This file contains code for parsing URLs that appear on the command-line
    19     19   */
    20     20   #include "config.h"
    21     21   #include "url.h"
           22  +
           23  +/*
           24  +** Convert a string to lower-case.
           25  +*/
           26  +static void url_tolower(char *z){
           27  +  while( *z ){
           28  +     *z = fossil_tolower(*z);
           29  +     z++;
           30  +  }
           31  +}
    22     32   
    23     33   /*
    24     34   ** Parse the given URL.  Populate variables in the global "g" structure.
    25     35   **
    26     36   **      g.urlIsFile      True if FILE:
    27     37   **      g.urlIsHttps     True if HTTPS: 
           38  +**      g.urlIsSsh       True if SSH:
    28     39   **      g.urlProtocol    "http" or "https" or "file"
    29         -**      g.urlName        Hostname for HTTP: or HTTPS:.  Filename for FILE:
           40  +**      g.urlName        Hostname for HTTP:, HTTPS:, SSH:.  Filename for FILE:
    30     41   **      g.urlPort        TCP port number for HTTP or HTTPS.
    31     42   **      g.urlDfltPort    Default TCP port number (80 or 443).
    32     43   **      g.urlPath        Path name for HTTP or HTTPS.
    33     44   **      g.urlUser        Userid.
    34     45   **      g.urlPasswd      Password.
    35     46   **      g.urlHostname    HOST:PORT or just HOST if port is the default.
    36     47   **      g.urlCanonical   The URL in canonical form, omitting the password
    37     48   **
    38     49   ** HTTP url format is:
    39     50   **
    40         -**     http://userid:password@host:port/path?query#fragment
           51  +**     http://userid:password@host:port/path
           52  +**
           53  +** SSH url format is:
           54  +**
           55  +**     ssh://userid:password@host:port/path?fossil=path/to/fossil.exe
    41     56   **
    42     57   */
    43     58   void url_parse(const char *zUrl){
    44     59     int i, j, c;
    45     60     char *zFile = 0;
    46         -  if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 ){
           61  +  if( strncmp(zUrl, "http://", 7)==0
           62  +   || strncmp(zUrl, "https://", 8)==0
           63  +   || strncmp(zUrl, "ssh://", 6)==0
           64  +  ){
    47     65       int iStart;
    48     66       char *zLogin;
           67  +    char *zExe;
           68  +
    49     69       g.urlIsFile = 0;
    50     70       if( zUrl[4]=='s' ){
    51     71         g.urlIsHttps = 1;
    52     72         g.urlProtocol = "https";
    53     73         g.urlDfltPort = 443;
    54     74         iStart = 8;
           75  +    }else if( zUrl[0]=='s' ){
           76  +      g.urlIsSsh = 1;
           77  +      g.urlProtocol = "ssh";
           78  +      g.urlDfltPort = 22;
           79  +      g.urlFossil = "fossil";
           80  +      iStart = 6;
    55     81       }else{
    56     82         g.urlIsHttps = 0;
    57     83         g.urlProtocol = "http";
    58     84         g.urlDfltPort = 80;
    59     85         iStart = 7;
    60     86       }
    61     87       for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
    62     88       if( c=='@' ){
           89  +      /* Parse up the user-id and password */
    63     90         for(j=iStart; j<i && zUrl[j]!=':'; j++){}
    64     91         g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
    65     92         dehttpize(g.urlUser);
    66     93         if( j<i ){
    67     94           g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
    68     95           dehttpize(g.urlPasswd);
    69     96         }
           97  +      if( g.urlIsSsh && g.urlPasswd ){
           98  +        zLogin = mprintf("%t:*@", g.urlUser);
           99  +      }else{
          100  +        zLogin = mprintf("%t@", g.urlUser);
          101  +      }
    70    102         for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
    71    103         g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
    72    104         i = j;
    73         -      zLogin = mprintf("%t@", g.urlUser);
    74    105       }else{
    75    106         for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
    76    107         g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);
    77    108         zLogin = mprintf("");
    78    109       }
    79         -    for(j=0; g.urlName[j]; j++){ g.urlName[j] = tolower(g.urlName[j]); }
          110  +    url_tolower(g.urlName);
    80    111       if( c==':' ){
    81    112         g.urlPort = 0;
    82    113         i++;
    83         -      while( (c = zUrl[i])!=0 && isdigit(c) ){
          114  +      while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){
    84    115           g.urlPort = g.urlPort*10 + c - '0';
    85    116           i++;
    86    117         }
    87    118         g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort);
    88    119       }else{
    89    120         g.urlPort = g.urlDfltPort;
    90    121         g.urlHostname = g.urlName;
    91    122       }
    92         -    g.urlPath = mprintf(&zUrl[i]);
    93    123       dehttpize(g.urlName);
          124  +    g.urlPath = mprintf("%s", &zUrl[i]);
          125  +    for(i=0; g.urlPath[i] && g.urlPath[i]!='?'; i++){}
          126  +    if( g.urlPath[i] ){
          127  +      g.urlPath[i] = 0;
          128  +      i++;
          129  +    }
          130  +    zExe = mprintf("");
          131  +    while( g.urlPath[i]!=0 ){
          132  +      char *zName, *zValue;
          133  +      zName = &g.urlPath[i];
          134  +      zValue = zName;
          135  +      while( g.urlPath[i] && g.urlPath[i]!='=' ){ i++; }
          136  +      if( g.urlPath[i]=='=' ){
          137  +        g.urlPath[i] = 0;
          138  +        i++;
          139  +        zValue = &g.urlPath[i];
          140  +        while( g.urlPath[i] && g.urlPath[i]!='&' ){ i++; }
          141  +      }
          142  +      if( g.urlPath[i] ){
          143  +        g.urlPath[i] = 0;
          144  +        i++;
          145  +      }
          146  +      if( strcmp(zName,"fossil")==0 ){
          147  +        g.urlFossil = zValue;
          148  +        dehttpize(g.urlFossil);
          149  +        zExe = mprintf("?fossil=%T", g.urlFossil);
          150  +      }
          151  +    }
          152  +
    94    153       dehttpize(g.urlPath);
    95    154       if( g.urlDfltPort==g.urlPort ){
    96    155         g.urlCanonical = mprintf(
    97         -        "%s://%s%T%T", 
    98         -        g.urlProtocol, zLogin, g.urlName, g.urlPath
          156  +        "%s://%s%T%T%s", 
          157  +        g.urlProtocol, zLogin, g.urlName, g.urlPath, zExe
    99    158         );
   100    159       }else{
   101    160         g.urlCanonical = mprintf(
   102         -        "%s://%s%T:%d%T",
   103         -        g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath
          161  +        "%s://%s%T:%d%T%s",
          162  +        g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath, zExe
   104    163         );
   105    164       }
          165  +    if( g.urlIsSsh && g.urlPath[1] ) g.urlPath++;
   106    166       free(zLogin);
   107    167     }else if( strncmp(zUrl, "file:", 5)==0 ){
   108    168       g.urlIsFile = 1;
   109    169       if( zUrl[5]=='/' && zUrl[6]=='/' ){
   110    170         i = 7;
   111    171       }else{
   112    172         i = 5;
................................................................................
   148    208     if( g.argc!=3 && g.argc!=4 ){
   149    209       usage("URL");
   150    210     }
   151    211     url_parse(g.argv[2]);
   152    212     for(i=0; i<2; i++){
   153    213       printf("g.urlIsFile    = %d\n", g.urlIsFile);
   154    214       printf("g.urlIsHttps   = %d\n", g.urlIsHttps);
          215  +    printf("g.urlIsSsh     = %d\n", g.urlIsSsh);
   155    216       printf("g.urlProtocol  = %s\n", g.urlProtocol);
   156    217       printf("g.urlName      = %s\n", g.urlName);
   157    218       printf("g.urlPort      = %d\n", g.urlPort);
   158    219       printf("g.urlDfltPort  = %d\n", g.urlDfltPort);
   159    220       printf("g.urlHostname  = %s\n", g.urlHostname);
   160    221       printf("g.urlPath      = %s\n", g.urlPath);
   161    222       printf("g.urlUser      = %s\n", g.urlUser);
   162    223       printf("g.urlPasswd    = %s\n", g.urlPasswd);
   163    224       printf("g.urlCanonical = %s\n", g.urlCanonical);
          225  +    printf("g.urlFossil    = %s\n", g.urlFossil);
          226  +    if( g.urlIsFile || g.urlIsSsh ) break;
   164    227       if( i==0 ){
   165    228         printf("********\n");
   166    229         url_enable_proxy("Using proxy: ");
   167    230       }
   168    231     }
   169    232   }
   170    233   
................................................................................
   286    349       }
   287    350       if( zName2 && strcmp(zName2,p->azName[i])==0 ){
   288    351         zName2 = 0;
   289    352         z = zValue2;
   290    353         if( z==0 ) continue;
   291    354       }
   292    355       blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z);
   293         -    zSep = "&";
          356  +    zSep = "&amp;";
   294    357     }
   295    358     if( zName1 && zValue1 ){
   296    359       blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1);
   297    360     }
   298    361     if( zName2 && zValue2 ){
   299    362       blob_appendf(&p->url, "%s%s=%T", zSep, zName2, zValue2);
   300    363     }

Changes to src/user.c.

    25     25   /*
    26     26   ** Strip leading and trailing space from a string and add the string
    27     27   ** onto the end of a blob.
    28     28   */
    29     29   static void strip_string(Blob *pBlob, char *z){
    30     30     int i;
    31     31     blob_reset(pBlob);
    32         -  while( isspace(*z) ){ z++; }
           32  +  while( fossil_isspace(*z) ){ z++; }
    33     33     for(i=0; z[i]; i++){
    34     34       if( z[i]=='\r' || z[i]=='\n' ){
    35         -       while( i>0 && isspace(z[i-1]) ){ i--; }
           35  +       while( i>0 && fossil_isspace(z[i-1]) ){ i--; }
    36     36          z[i] = 0;
    37     37          break;
    38     38       }
    39     39       if( z[i]<' ' ) z[i] = ' ';
    40     40     }
    41     41     blob_append(pBlob, z, -1);
    42     42   }
    43     43   
           44  +#if defined(_WIN32)
    44     45   #ifdef __MINGW32__
           46  +#include <conio.h>
           47  +#endif
    45     48   /*
    46     49   ** getpass for Windows
    47     50   */
    48     51   static char *getpass(const char *prompt){
    49     52     static char pwd[64];
    50     53     size_t i;
    51     54   

Changes to src/vfile.c.

    17     17   **
    18     18   ** Procedures for managing the VFILE table.
    19     19   */
    20     20   #include "config.h"
    21     21   #include "vfile.h"
    22     22   #include <assert.h>
    23     23   #include <sys/types.h>
           24  +#if defined(__DMC__)
           25  +#include "dirent.h"
           26  +#else
    24     27   #include <dirent.h>
           28  +#endif
    25     29   
    26     30   /*
    27     31   ** Given a UUID, return the corresponding record ID.  If the UUID
    28     32   ** does not exist, then return 0.
    29     33   **
    30     34   ** For this routine, the UUID must be exact.  For a match against
    31     35   ** user input with mixed case, use resolve_uuid().
................................................................................
    79     83           fossil_panic("bad object id: %d", rid);
    80     84         }
    81     85       }
    82     86     }
    83     87   }
    84     88   
    85     89   /*
    86         -** Build a catalog of all files in a baseline.
    87         -** We scan the baseline file for lines of the form:
    88         -**
    89         -**     F NAME UUID
    90         -**
    91         -** Each such line makes an entry in the VFILE table.
           90  +** Build a catalog of all files in a checkin.
    92     91   */
    93         -void vfile_build(int vid, Blob *p){
           92  +void vfile_build(int vid){
    94     93     int rid;
    95         -  char *zName, *zUuid;
    96     94     Stmt ins;
    97         -  Blob line, token, name, uuid;
    98         -  int seenHeader = 0;
           95  +  Manifest *p;
           96  +  ManifestFile *pFile;
           97  +
    99     98     db_begin_transaction();
   100     99     vfile_verify_not_phantom(vid, 0, 0);
          100  +  p = manifest_get(vid, CFTYPE_MANIFEST);
          101  +  if( p==0 ) return;
   101    102     db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
   102    103     db_prepare(&ins,
   103    104       "INSERT INTO vfile(vid,rid,mrid,pathname) "
   104    105       " VALUES(:vid,:id,:id,:name)");
   105    106     db_bind_int(&ins, ":vid", vid);
   106         -  while( blob_line(p, &line) ){
   107         -    char *z = blob_buffer(&line);
   108         -    if( z[0]=='-' ){
   109         -      if( seenHeader ) break;
   110         -      while( blob_line(p, &line)>2 ){}
   111         -      if( blob_line(p, &line)==0 ) break;
   112         -    }
   113         -    seenHeader = 1;
   114         -    if( z[0]!='F' || z[1]!=' ' ) continue;
   115         -    blob_token(&line, &token);  /* Skip the "F" token */
   116         -    if( blob_token(&line, &name)==0 ) break;
   117         -    if( blob_token(&line, &uuid)==0 ) break;
   118         -    zName = blob_str(&name);
   119         -    defossilize(zName);
   120         -    zUuid = blob_str(&uuid);
   121         -    rid = uuid_to_rid(zUuid, 0);
   122         -    vfile_verify_not_phantom(rid, zName, zUuid);
   123         -    if( rid>0 && file_is_simple_pathname(zName) ){
   124         -      db_bind_int(&ins, ":id", rid);
   125         -      db_bind_text(&ins, ":name", zName);
   126         -      db_step(&ins);
   127         -      db_reset(&ins);
   128         -    }
   129         -    blob_reset(&name);
   130         -    blob_reset(&uuid);
          107  +  manifest_file_rewind(p);
          108  +  while( (pFile = manifest_file_next(p,0))!=0 ){
          109  +    rid = uuid_to_rid(pFile->zUuid, 0);
          110  +    vfile_verify_not_phantom(rid, pFile->zName, pFile->zUuid);
          111  +    db_bind_int(&ins, ":id", rid);
          112  +    db_bind_text(&ins, ":name", pFile->zName);
          113  +    db_step(&ins);
          114  +    db_reset(&ins);
   131    115     }
   132    116     db_finalize(&ins);
          117  +  manifest_destroy(p);
   133    118     db_end_transaction(0);
   134    119   }
   135    120   
   136    121   /*
   137    122   ** Check the file signature of the disk image for every VFILE of vid.
   138    123   **
   139    124   ** Set the VFILE.CHNGED field on every file that has changed.  Also 
................................................................................
   363    348           md5sum_step_text(" 0\n", -1);
   364    349           continue;
   365    350         }
   366    351         fseek(in, 0L, SEEK_END);
   367    352         sprintf(zBuf, " %ld\n", ftell(in));
   368    353         fseek(in, 0L, SEEK_SET);
   369    354         md5sum_step_text(zBuf, -1);
          355  +      /*printf("%s %s %s",md5sum_current_state(),zName,zBuf); fflush(stdout);*/
   370    356         for(;;){
   371    357           int n;
   372    358           n = fread(zBuf, 1, sizeof(zBuf), in);
   373    359           if( n<=0 ) break;
   374    360           md5sum_step_text(zBuf, n);
   375    361         }
   376    362         fclose(in);
................................................................................
   416    402     while( db_step(&q)==SQLITE_ROW ){
   417    403       const char *zName = db_column_text(&q, 0);
   418    404       int rid = db_column_int(&q, 1);
   419    405       md5sum_step_text(zName, -1);
   420    406       content_get(rid, &file);
   421    407       sprintf(zBuf, " %d\n", blob_size(&file));
   422    408       md5sum_step_text(zBuf, -1);
          409  +    /*printf("%s %s %s",md5sum_current_state(),zName,zBuf); fflush(stdout);*/
   423    410       md5sum_step_blob(&file);
   424    411       blob_reset(&file);
   425    412     }
   426    413     db_finalize(&q);
   427    414     md5sum_finish(pOut);
   428    415   }
   429    416   
................................................................................
   432    419   ** file in manifest vid.  The file names are part of the checksum.
   433    420   ** Return the resulting checksum in blob pOut.
   434    421   **
   435    422   ** If pManOut is not NULL then fill it with the checksum found in the
   436    423   ** "R" card near the end of the manifest.  
   437    424   */
   438    425   void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
   439         -  int i, fid;
   440         -  Blob file, mfile;
   441         -  Manifest m;
          426  +  int fid;
          427  +  Blob file;
          428  +  Manifest *pManifest;
          429  +  ManifestFile *pFile;
   442    430     char zBuf[100];
   443    431   
   444    432     blob_zero(pOut);
   445    433     if( pManOut ){
   446    434       blob_zero(pManOut);
   447    435     }
   448    436     db_must_be_within_tree();
   449         -  content_get(vid, &mfile);
   450         -  if( manifest_parse(&m, &mfile)==0 ){
          437  +  pManifest = manifest_get(vid, CFTYPE_MANIFEST);
          438  +  if( pManifest==0 ){
   451    439       fossil_panic("manifest file (%d) is malformed", vid);
   452    440     }
   453         -  for(i=0; i<m.nFile; i++){
   454         -    fid = uuid_to_rid(m.aFile[i].zUuid, 0);
   455         -    md5sum_step_text(m.aFile[i].zName, -1);
          441  +  manifest_file_rewind(pManifest);
          442  +  while( (pFile = manifest_file_next(pManifest,0))!=0 ){
          443  +    fid = uuid_to_rid(pFile->zUuid, 0);
          444  +    md5sum_step_text(pFile->zName, -1);
   456    445       content_get(fid, &file);
   457    446       sprintf(zBuf, " %d\n", blob_size(&file));
   458    447       md5sum_step_text(zBuf, -1);
   459    448       md5sum_step_blob(&file);
   460    449       blob_reset(&file);
   461    450     }
   462    451     if( pManOut ){
   463         -    blob_append(pManOut, m.zRepoCksum, -1);
          452  +    if( pManifest->zRepoCksum ){
          453  +      blob_append(pManOut, pManifest->zRepoCksum, -1);
          454  +    }else{
          455  +      blob_zero(pManOut);
          456  +    }
   464    457     }
   465         -  manifest_clear(&m);
          458  +  manifest_destroy(pManifest);
   466    459     md5sum_finish(pOut);
   467    460   }
   468    461   
   469    462   /*
   470    463   ** COMMAND: test-agg-cksum
   471    464   */
   472    465   void test_agg_cksum_cmd(void){

Changes to src/wiki.c.

    46     46   }
    47     47   
    48     48   /*
    49     49   ** Output rules for well-formed wiki pages
    50     50   */
    51     51   static void well_formed_wiki_name_rules(void){
    52     52     @ <ul>
    53         -  @ <li> Must not begin or end with a space.
           53  +  @ <li> Must not begin or end with a space.</li>
    54     54     @ <li> Must not contain any control characters, including tab or
    55         -  @      newline.
    56         -  @ <li> Must not have two or more spaces in a row internally.
    57         -  @ <li> Must be between 3 and 100 characters in length.
           55  +  @      newline.</li>
           56  +  @ <li> Must not have two or more spaces in a row internally.</li>
           57  +  @ <li> Must be between 3 and 100 characters in length.</li>
    58     58     @ </ul>
    59     59   }
    60     60   
    61     61   /*
    62     62   ** Check a wiki name.  If it is not well-formed, then issue an error
    63     63   ** and return true.  If it is well-formed, return false.
    64     64   */
    65     65   static int check_name(const char *z){
    66     66     if( !wiki_name_is_wellformed((const unsigned char *)z) ){
    67     67       style_header("Wiki Page Name Error");
    68         -    @ The wiki name "<b>%h(z)</b>" is not well-formed.  Rules for
    69         -    @ wiki page names:
           68  +    @ The wiki name "<span class="wikiError">%h(z)</span>" is not well-formed.
           69  +    @ Rules for wiki page names:
    70     70       well_formed_wiki_name_rules();
    71     71       style_footer();
    72     72       return 1;
    73     73     }
    74     74     return 0;
    75     75   }
    76     76   
................................................................................
    77     77   /*
    78     78   ** WEBPAGE: home
    79     79   ** WEBPAGE: index
    80     80   ** WEBPAGE: not_found
    81     81   */
    82     82   void home_page(void){
    83     83     char *zPageName = db_get("project-name",0);
           84  +  char *zIndexPage = db_get("index-page",0);
    84     85     login_check_credentials();
    85     86     if( !g.okRdWiki ){
    86     87       cgi_redirectf("%s/login?g=%s/home", g.zBaseURL, g.zBaseURL);
    87     88     }
           89  +  if( zIndexPage ){
           90  +    const char *zPathInfo = P("PATH_INFO");
           91  +    while( zIndexPage[0]=='/' ) zIndexPage++;
           92  +    if( strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0;
           93  +  }
           94  +  if( zIndexPage ){
           95  +    cgi_redirectf("%s/%s", g.zBaseURL, zIndexPage);
           96  +  }
    88     97     if( zPageName ){
    89     98       login_check_credentials();
    90     99       g.zExtra = zPageName;
    91    100       cgi_set_parameter_nocopy("name", g.zExtra);
    92    101       g.isHome = 1;
    93    102       wiki_page();
    94    103       return;
................................................................................
    95    104     }
    96    105     style_header("Home");
    97    106     @ <p>This is a stub home-page for the project.
    98    107     @ To fill in this page, first go to
    99    108     @ <a href="%s(g.zBaseURL)/setup_config">setup/config</a>
   100    109     @ and establish a "Project Name".  Then create a
   101    110     @ wiki page with that name.  The content of that wiki page
   102         -  @ will be displayed in place of this message.
          111  +  @ will be displayed in place of this message.</p>
   103    112     style_footer();
   104    113   }
   105    114   
   106    115   /*
   107    116   ** Return true if the given pagename is the name of the sandbox
   108    117   */
   109    118   static int is_sandbox(const char *zPagename){
................................................................................
   116    125   ** URL: /wiki?name=PAGENAME
   117    126   */
   118    127   void wiki_page(void){
   119    128     char *zTag;
   120    129     int rid = 0;
   121    130     int isSandbox;
   122    131     Blob wiki;
   123         -  Manifest m;
          132  +  Manifest *pWiki = 0;
   124    133     const char *zPageName;
   125    134     char *zBody = mprintf("%s","<i>Empty Page</i>");
   126    135     Stmt q;
   127    136     int cnt = 0;
   128    137   
   129    138     login_check_credentials();
   130    139     if( !g.okRdWiki ){ login_needed(); return; }
................................................................................
   142    151       @      pages. </li>
   143    152       @ <li> <a href="%s(g.zBaseURL)/wiki_rules">Formatting rules</a> for 
   144    153       @      wiki.</li>
   145    154       @ <li> Use the <a href="%s(g.zBaseURL)/wiki?name=Sandbox">Sandbox</a>
   146    155       @      to experiment.</li>
   147    156       if( g.okNewWiki ){
   148    157         @ <li>  Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li>
          158  +      if( g.okWrite ){
          159  +        @ <li>   Create a <a href="%s(g.zTop)/eventedit">new event</a>.</li>
          160  +      }
   149    161       }
   150    162       @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
   151    163       @      available on this server.</li>
   152         -	@ <li> <form method="GET" action="%s(g.zBaseURL)/wfind">
   153         -	@     Search wiki titles: <input type="text" name="title"/>
   154         -        @  &nbsp; <input type="submit" />
   155         -	@ </li>
          164  +    @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
          165  +    @     Search wiki titles: <input type="text" name="title"/>
          166  +    @  &nbsp; <input type="submit" /></div></form>
          167  +    @ </li>
   156    168       @ </ul>
   157    169       style_footer();
   158    170       return;
   159    171     }
   160    172     if( check_name(zPageName) ) return;
   161    173     isSandbox = is_sandbox(zPageName);
   162    174     if( isSandbox ){
................................................................................
   165    177       zTag = mprintf("wiki-%s", zPageName);
   166    178       rid = db_int(0, 
   167    179         "SELECT rid FROM tagxref"
   168    180         " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
   169    181         " ORDER BY mtime DESC", zTag
   170    182       );
   171    183       free(zTag);
   172         -    memset(&m, 0, sizeof(m));
   173         -    blob_zero(&m.content);
   174         -    if( rid ){
   175         -      Blob content;
   176         -      content_get(rid, &content);
   177         -      manifest_parse(&m, &content);
   178         -      if( m.type==CFTYPE_WIKI && m.zWiki ){
   179         -        while( isspace(m.zWiki[0]) ) m.zWiki++;
   180         -        if( m.zWiki[0] ) zBody = m.zWiki;
   181         -      }
          184  +    pWiki = manifest_get(rid, CFTYPE_WIKI);
          185  +    if( pWiki ){
          186  +      while( fossil_isspace(pWiki->zWiki[0]) ) pWiki->zWiki++;
          187  +      if( pWiki->zWiki[0] ) zBody = pWiki->zWiki;
   182    188       }
   183    189     }
   184    190     if( !g.isHome ){
   185    191       if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){
   186    192         style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
   187    193              g.zTop, zPageName);
   188    194       }
   189    195       if( rid && g.okApndWiki && g.okAttach ){
   190    196         style_submenu_element("Attach", "Add An Attachment",
   191         -           "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
          197  +           "%s/attachadd?page=%T&amp;from=%s/wiki%%3fname=%T",
   192    198              g.zTop, zPageName, g.zTop, zPageName);
   193    199       }
   194    200       if( rid && g.okApndWiki ){
   195    201         style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T",
   196    202              g.zTop, zPageName);
   197    203       }
   198    204       if( g.okHistory ){
................................................................................
   212    218        " ORDER BY mtime DESC",
   213    219        zPageName);
   214    220     while( db_step(&q)==SQLITE_ROW ){
   215    221       const char *zDate = db_column_text(&q, 0);
   216    222       const char *zFile = db_column_text(&q, 1);
   217    223       const char *zUser = db_column_text(&q, 2);
   218    224       if( cnt==0 ){
   219         -      @ <hr><h2>Attachments:</h2>
          225  +      @ <hr /><h2>Attachments:</h2>
   220    226         @ <ul>
   221    227       }
   222    228       cnt++;
   223         -    if( g.okHistory ){
   224         -      @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)">
          229  +    @ <li>
          230  +    if( g.okHistory && g.okRead ){
          231  +      @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&amp;file=%t(zFile)">
          232  +      @ %h(zFile)</a>
   225    233       }else{
   226         -      @ <li>
          234  +      @ <li>%h(zFile)
   227    235       }
   228         -    @ %h(zFile)</a> add by %h(zUser) on
          236  +    @ added by %h(zUser) on
   229    237       hyperlink_to_date(zDate, ".");
   230    238       if( g.okWrWiki && g.okAttach ){
   231         -      @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>]
          239  +      @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&amp;file=%t(zFile)&amp;from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>]
   232    240       }
          241  +    @ </li>
   233    242     }
   234    243     if( cnt ){
   235    244       @ </ul>
   236    245     }
   237    246     db_finalize(&q);
   238    247    
   239         -  if( !isSandbox ){
   240         -    manifest_clear(&m);
   241         -  }
          248  +  manifest_destroy(pWiki);
   242    249     style_footer();
   243    250   }
   244    251   
   245    252   /*
   246    253   ** WEBPAGE: wikiedit
   247    254   ** URL: /wikiedit?name=PAGENAME
   248    255   */
   249    256   void wikiedit_page(void){
   250    257     char *zTag;
   251    258     int rid = 0;
   252    259     int isSandbox;
   253    260     Blob wiki;
   254         -  Manifest m;
          261  +  Manifest *pWiki = 0;
   255    262     const char *zPageName;
   256    263     char *zHtmlPageName;
   257    264     int n;
   258    265     const char *z;
   259    266     char *zBody = (char*)P("w");
   260    267   
   261    268     if( zBody ){
................................................................................
   281    288         " ORDER BY mtime DESC", zTag
   282    289       );
   283    290       free(zTag);
   284    291       if( (rid && !g.okWrWiki) || (!rid && !g.okNewWiki) ){
   285    292         login_needed();
   286    293         return;
   287    294       }
   288         -    memset(&m, 0, sizeof(m));
   289         -    blob_zero(&m.content);
   290         -    if( rid && zBody==0 ){
   291         -      Blob content;
   292         -      content_get(rid, &content);
   293         -      manifest_parse(&m, &content);
   294         -      if( m.type==CFTYPE_WIKI ){
   295         -        zBody = m.zWiki;
   296         -      }
          295  +    if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
          296  +      zBody = pWiki->zWiki;
   297    297       }
   298    298     }
   299    299     if( P("submit")!=0 && zBody!=0 ){
   300    300       char *zDate;
   301    301       Blob cksum;
   302    302       int nrid;
   303    303       blob_zero(&wiki);
................................................................................
   340    340       zBody = mprintf("<i>Empty Page</i>");
   341    341     }
   342    342     zHtmlPageName = mprintf("Edit: %s", zPageName);
   343    343     style_header(zHtmlPageName);
   344    344     if( P("preview")!=0 ){
   345    345       blob_zero(&wiki);
   346    346       blob_append(&wiki, zBody, -1);
   347         -    @ Preview:<hr>
          347  +    @ Preview:<hr />
   348    348       wiki_convert(&wiki, 0, 0);
   349         -    @ <hr>
          349  +    @ <hr />
   350    350       blob_reset(&wiki);
   351    351     }
   352    352     for(n=2, z=zBody; z[0]; z++){
   353    353       if( z[0]=='\n' ) n++;
   354    354     }
   355    355     if( n<20 ) n = 20;
   356    356     if( n>40 ) n = 40;
   357         -  @ <form method="POST" action="%s(g.zBaseURL)/wikiedit">
          357  +  @ <form method="post" action="%s(g.zBaseURL)/wikiedit"><div>
   358    358     login_insert_csrf_secret();
   359         -  @ <input type="hidden" name="name" value="%h(zPageName)">
          359  +  @ <input type="hidden" name="name" value="%h(zPageName)" />
   360    360     @ <textarea name="w" class="wikiedit" cols="80" 
   361    361     @  rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
   362         -  @ <br>
   363         -  @ <input type="submit" name="preview" value="Preview Your Changes">
   364         -  @ <input type="submit" name="submit" value="Apply These Changes">
   365         -  @ <input type="submit" name="cancel" value="Cancel">
   366         -  @ </form>
   367         -  if( !isSandbox ){
   368         -    manifest_clear(&m);
   369         -  }
          362  +  @ <br />
          363  +  @ <input type="submit" name="preview" value="Preview Your Changes" />
          364  +  @ <input type="submit" name="submit" value="Apply These Changes" />
          365  +  @ <input type="submit" name="cancel" value="Cancel" />
          366  +  @ </div></form>
          367  +  manifest_destroy(pWiki);
   370    368     style_footer();
   371    369   }
   372    370   
   373    371   /*
   374    372   ** WEBPAGE: wikinew
   375    373   ** URL /wikinew
   376    374   **
................................................................................
   385    383       return;
   386    384     }  
   387    385     zName = PD("name","");
   388    386     if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
   389    387       cgi_redirectf("wikiedit?name=%T", zName);
   390    388     }
   391    389     style_header("Create A New Wiki Page");
   392         -  @ <p>Rules for wiki page names:
          390  +  @ <p>Rules for wiki page names:</p>
   393    391     well_formed_wiki_name_rules();
   394         -  @ </p>
   395         -  @ <form method="POST" action="%s(g.zBaseURL)/wikinew">
          392  +  @ <form method="post" action="%s(g.zBaseURL)/wikinew">
   396    393     @ <p>Name of new wiki page:
   397         -  @ <input type="text" width="35" name="name" value="%h(zName)">
   398         -  @ <input type="submit" value="Create">
          394  +  @ <input style="width: 35;" type="text" name="name" value="%h(zName)" />
          395  +  @ <input type="submit" value="Create" />
   399    396     @ </p></form>
   400    397     if( zName[0] ){
   401         -    @ <p><b><font color="red">
   402         -    @ "%h(zName)" is not a valid wiki page name!</font></b></p>
          398  +    @ <p><span class="wikiError">
          399  +    @ "%h(zName)" is not a valid wiki page name!</span></p>
   403    400     }
   404    401     style_footer();
   405    402   }
   406    403   
   407    404   
   408    405   /*
   409    406   ** Append the wiki text for an remark to the end of the given BLOB.
................................................................................
   461    458       return;
   462    459     }
   463    460     if( P("submit")!=0 && P("r")!=0 && P("u")!=0 ){
   464    461       char *zDate;
   465    462       Blob cksum;
   466    463       int nrid;
   467    464       Blob body;
   468         -    Blob content;
   469    465       Blob wiki;
   470         -    Manifest m;
          466  +    Manifest *pWiki = 0;
   471    467   
   472    468       blob_zero(&body);
   473    469       if( isSandbox ){
   474    470         blob_appendf(&body, db_get("sandbox",""));
   475    471         appendRemark(&body);
   476    472         db_set("sandbox", blob_str(&body), 0);
   477    473       }else{
   478    474         login_verify_csrf_secret();
   479         -      content_get(rid, &content);
   480         -      manifest_parse(&m, &content);
   481         -      if( m.type==CFTYPE_WIKI ){
   482         -        blob_append(&body, m.zWiki, -1);
          475  +      pWiki = manifest_get(rid, CFTYPE_WIKI);
          476  +      if( pWiki ){
          477  +        blob_append(&body, pWiki->zWiki, -1);
          478  +        manifest_destroy(pWiki);
   483    479         }
   484         -      manifest_clear(&m);
   485    480         blob_zero(&wiki);
   486    481         db_begin_transaction();
   487    482         zDate = db_text(0, "SELECT datetime('now')");
   488    483         zDate[10] = 'T';
   489    484         blob_appendf(&wiki, "D %s\n", zDate);
   490    485         blob_appendf(&wiki, "L %F\n", zPageName);
   491    486         if( rid ){
................................................................................
   522    517       appendRemark(&preview);
   523    518       @ Preview:<hr>
   524    519       wiki_convert(&preview, 0, 0);
   525    520       @ <hr>
   526    521       blob_reset(&preview);
   527    522     }
   528    523     zUser = PD("u", g.zLogin);
   529         -  @ <form method="POST" action="%s(g.zBaseURL)/wikiappend">
          524  +  @ <form method="post" action="%s(g.zBaseURL)/wikiappend">
   530    525     login_insert_csrf_secret();
   531         -  @ <input type="hidden" name="name" value="%h(zPageName)">
          526  +  @ <input type="hidden" name="name" value="%h(zPageName)" />
   532    527     @ Your Name:
   533         -  @ <input type="text" name="u" size="20" value="%h(zUser)"><br>
   534         -  @ Comment to append:<br>
          528  +  @ <input type="text" name="u" size="20" value="%h(zUser)" /><br />
          529  +  @ Comment to append:<br />
   535    530     @ <textarea name="r" class="wikiedit" cols="80" 
   536    531     @  rows="10" wrap="virtual">%h(PD("r",""))</textarea>
   537         -  @ <br>
   538         -  @ <input type="submit" name="preview" value="Preview Your Comment">
   539         -  @ <input type="submit" name="submit" value="Append Your Changes">
   540         -  @ <input type="submit" name="cancel" value="Cancel">
          532  +  @ <br />
          533  +  @ <input type="submit" name="preview" value="Preview Your Comment" />
          534  +  @ <input type="submit" name="submit" value="Append Your Changes" />
          535  +  @ <input type="submit" name="cancel" value="Cancel" />
   541    536     @ </form>
   542    537     style_footer();
   543    538   }
   544    539   
   545    540   /*
   546    541   ** Name of the wiki history page being generated
   547    542   */
................................................................................
   549    544   
   550    545   /*
   551    546   ** Function called to output extra text at the end of each line in
   552    547   ** a wiki history listing.
   553    548   */
   554    549   static void wiki_history_extra(int rid){
   555    550     if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
   556         -    @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a>
          551  +    @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&amp;a=%d(rid)">[diff]</a>
   557    552     }
   558    553   }
   559    554   
   560    555   /*
   561    556   ** WEBPAGE: whistory
   562    557   ** URL: /whistory?name=PAGENAME
   563    558   **
................................................................................
   596    591   **
   597    592   ** Show the difference between two wiki pages.
   598    593   */
   599    594   void wdiff_page(void){
   600    595     char *zTitle;
   601    596     int rid1, rid2;
   602    597     const char *zPageName;
   603         -  Blob content1, content2;
   604         -  Manifest m1, m2;
          598  +  Manifest *pW1, *pW2 = 0;
   605    599     Blob w1, w2, d;
   606    600   
   607    601     login_check_credentials();
   608    602     rid1 = atoi(PD("a","0"));
   609    603     if( !g.okHistory ){ login_needed(); return; }
   610    604     if( rid1==0 ) fossil_redirect_home();
   611    605     rid2 = atoi(PD("b","0"));
................................................................................
   619    613         "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
   620    614                           "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
   621    615         " WHERE event.mtime<(SELECT mtime FROM event WHERE objid=%d)"
   622    616         " ORDER BY event.mtime DESC LIMIT 1",
   623    617         zPageName, rid1
   624    618       );
   625    619     }
   626         -  content_get(rid1, &content1);
   627         -  manifest_parse(&m1, &content1);
   628         -  if( m1.type!=CFTYPE_WIKI ) fossil_redirect_home();
   629         -  blob_init(&w1, m1.zWiki, -1);
          620  +  pW1 = manifest_get(rid1, CFTYPE_WIKI);
          621  +  if( pW1==0 ) fossil_redirect_home();
          622  +  blob_init(&w1, pW1->zWiki, -1);
   630    623     blob_zero(&w2);
   631         -  if( rid2 ){
   632         -    content_get(rid2, &content2);
   633         -    manifest_parse(&m2, &content2);
   634         -    if( m2.type==CFTYPE_WIKI ){
   635         -      blob_init(&w2, m2.zWiki, -1);
   636         -    }
          624  +  if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
          625  +    blob_init(&w2, pW2->zWiki, -1);
   637    626     }
   638    627     blob_zero(&d);
   639         -  text_diff(&w2, &w1, &d, 5);
          628  +  text_diff(&w2, &w1, &d, 5, 1);
   640    629     @ <pre>
   641    630     @ %h(blob_str(&d))
   642    631     @ </pre>
          632  +  manifest_destroy(pW1);
          633  +  manifest_destroy(pW2);
   643    634     style_footer();
   644    635   }
   645    636   
   646    637   /*
   647    638   ** WEBPAGE: wcontent
   648    639   **
   649    640   **     all=1         Show deleted pages
................................................................................
   729    720     @ <li>Most ordinary HTML works.</li>
   730    721     @ <li>&lt;verbatim&gt; and &lt;nowiki&gt;.</li>
   731    722     @ </ol>
   732    723     @ <p>We call the first five rules above "wiki" formatting rules.  The
   733    724     @ last two rules are the HTML formatting rule.</p>
   734    725     @ <h2>Formatting Rule Details</h2>
   735    726     @ <ol>
   736         -  @ <li> <p><b>Paragraphs</b>.  Any sequence of one or more blank lines forms
          727  +  @ <li> <p><span class="wikiruleHead">Paragraphs</span>.  Any sequence of one or more blank lines forms
   737    728     @ a paragraph break.  Centered or right-justified paragraphs are not
   738    729     @ supported by wiki markup, but you can do these things if you need them
   739         -  @ using HTML.</p>
   740         -  @ <li> <p><b>Bullet Lists</b>.
          730  +  @ using HTML.</p></li>
          731  +  @ <li> <p><span class="wikiruleHead">Bullet Lists</span>.
   741    732     @ A bullet list item is a line that begins with a single "*" character
   742    733     @ surrounded on
   743    734     @ both sides by two or more spaces or by a tab.  Only a single level
   744         -  @ of bullet list is supported by wiki.  For nested lists, use HTML.</p>
   745         -  @ <li> <p><b>Enumeration Lists</b>.
          735  +  @ of bullet list is supported by wiki.  For nested lists, use HTML.</p></li>
          736  +  @ <li> <p><span class="wikiruleHead">Enumeration Lists</span>.
   746    737     @ An enumeration list item is a line that begins with a single "#" character
   747    738     @ surrounded on both sides by two or more spaces or by a tab.  Only a single
   748    739     @ level of enumeration list is supported by wiki.  For nested lists or for
   749         -  @ enumerations that count using letters or roman numerials, use HTML.</p>
   750         -  @ <li> <p><b>Indented Paragraphs</b>.
          740  +  @ enumerations that count using letters or roman numerials, use HTML.</p></li>
          741  +  @ <li> <p><span class="wikiruleHead">Indented Paragraphs</span>.
   751    742     @ Any paragraph that begins with two or more spaces or a tab and
   752    743     @ which is not a bullet or enumeration list item is rendered 
   753    744     @ indented.  Only a single level of indentation is supported by wiki; use
   754         -  @ HTML for deeper indentation.</p>
   755         -  @ <li> <p><b>Hyperlinks</b>.
          745  +  @ HTML for deeper indentation.</p></li>
          746  +  @ <li> <p><span class="wikiruleHead">Hyperlinks</span>.
   756    747     @ Text within square brackets ("[...]") becomes a hyperlink.  The
   757    748     @ target can be a wiki page name, the artifact ID of a check-in or ticket,
   758    749     @ the name of an image, or a URL.  By default, the target is displayed
   759    750     @ as the text of the hyperlink.  But you can specify alternative text
   760    751     @ after the target name separated by a "|" character.</p>
   761    752     @ <p>You can also link to internal anchor names using [#anchor-name], providing
   762    753     @ you have added the necessary "&lt;a name="anchor-name"&gt;&lt;/a&gt;"
   763         -  @ tag to your wiki page.</p>
   764         -  @ <li> <p><b>HTML</b>.
          754  +  @ tag to your wiki page.</p></li>
          755  +  @ <li> <p><span class="wikiruleHead">HTML</span>.
   765    756     @ The following standard HTML elements may be used:
   766         -  @ &lt;a&gt;
   767         -  @ &lt;address&gt;
   768         -  @ &lt;b&gt;
   769         -  @ &lt;big&gt;
   770         -  @ &lt;blockquote&gt;
   771         -  @ &lt;br&gt;
   772         -  @ &lt;center&gt;
   773         -  @ &lt;cite&gt;
   774         -  @ &lt;code&gt;
   775         -  @ &lt;dd&gt;
   776         -  @ &lt;dfn&gt;
   777         -  @ &lt;div&gt;
   778         -  @ &lt;dl&gt;
   779         -  @ &lt;dt&gt;
   780         -  @ &lt;em&gt;
   781         -  @ &lt;font&gt;
   782         -  @ &lt;h1&gt;
   783         -  @ &lt;h2&gt;
   784         -  @ &lt;h3&gt;
   785         -  @ &lt;h4&gt;
   786         -  @ &lt;h5&gt;
   787         -  @ &lt;h6&gt;
   788         -  @ &lt;hr&gt;
   789         -  @ &lt;img&gt;
   790         -  @ &lt;i&gt;
   791         -  @ &lt;kbd&gt;
   792         -  @ &lt;li&gt;
   793         -  @ &lt;nobr&gt;
   794         -  @ &lt;ol&gt;
   795         -  @ &lt;p&gt;
   796         -  @ &lt;pre&gt;
   797         -  @ &lt;s&gt;
   798         -  @ &lt;samp&gt;
   799         -  @ &lt;small&gt;
   800         -  @ &lt;strike&gt;
   801         -  @ &lt;strong&gt;
   802         -  @ &lt;sub&gt;
   803         -  @ &lt;sup&gt;
   804         -  @ &lt;table&gt;
   805         -  @ &lt;td&gt;
   806         -  @ &lt;th&gt;
   807         -  @ &lt;tr&gt;
   808         -  @ &lt;tt&gt;
   809         -  @ &lt;u&gt;
   810         -  @ &lt;ul&gt;
   811         -  @ &lt;var&gt;.
   812         -  @ In addition, there are two non-standard elements available:
          757  +  show_allowed_wiki_markup();
          758  +  @ . There are two non-standard elements available:
   813    759     @ &lt;verbatim&gt; and &lt;nowiki&gt;.
   814    760     @ No other elements are allowed.  All attributes are checked and
   815    761     @ only a few benign attributes are allowed on each element.
   816    762     @ In particular, any attributes that specify javascript or CSS
   817    763     @ are elided.</p></li>
   818         -  @ <li><p><b>Special Markup.</b>
          764  +  @ <li><p><span class="wikiruleHead">Special Markup.</span>
   819    765     @ The &lt;nowiki&gt; tag disables all wiki formatting rules
   820    766     @ through the matching &lt;/nowiki&gt; element.
   821    767     @ The &lt;verbatim&gt; tag works like &lt;pre&gt; with the addition
   822    768     @ that it also disables all wiki and HTML markup
   823         -  @ through the matching &lt;/verbatim&gt;.
          769  +  @ through the matching &lt;/verbatim&gt;.</p></li>
   824    770     @ </ol>
   825    771     style_footer();
   826    772   }
   827    773   
   828    774   /*
   829    775   ** Add a new wiki page to the respository.  The page name is
   830    776   ** given by the zPageName parameter.  isNew must be true to create
................................................................................
   943    889     if( n==0 ){
   944    890       goto wiki_cmd_usage;
   945    891     }
   946    892   
   947    893     if( strncmp(g.argv[2],"export",n)==0 ){
   948    894       char const *zPageName;        /* Name of the wiki page to export */
   949    895       char const *zFile;            /* Name of the output file (0=stdout) */
   950         -    int rid;                /* Artifact ID of the wiki page */
   951         -    int i;                  /* Loop counter */
   952         -    char *zBody = 0;        /* Wiki page content */
   953         -    Manifest m;             /* Parsed wiki page content */
          896  +    int rid;                      /* Artifact ID of the wiki page */
          897  +    int i;                        /* Loop counter */
          898  +    char *zBody = 0;              /* Wiki page content */
          899  +    Manifest *pWiki = 0;          /* Parsed wiki page content */
          900  +
   954    901       if( (g.argc!=4) && (g.argc!=5) ){
   955    902         usage("export PAGENAME ?FILE?");
   956    903       }
   957    904       zPageName = g.argv[3];
   958    905       rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
   959    906         " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
   960    907         " ORDER BY x.mtime DESC LIMIT 1",
   961    908         zPageName 
   962    909       );
   963         -    if( rid ){
   964         -      Blob content;
   965         -      content_get(rid, &content);
   966         -      manifest_parse(&m, &content);
   967         -      if( m.type==CFTYPE_WIKI ){
   968         -        zBody = m.zWiki;
   969         -      }
          910  +    if( (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
          911  +      zBody = pWiki->zWiki;
   970    912       }
   971    913       if( zBody==0 ){
   972    914         fossil_fatal("wiki page [%s] not found",zPageName);
   973    915       }
   974         -    for(i=strlen(zBody); i>0 && isspace(zBody[i-1]); i--){}
          916  +    for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
   975    917       zFile  = (g.argc==4) ? 0 : g.argv[4];
   976    918       if( zFile ){
   977    919         FILE * zF;
   978    920         short doClose = 0;
   979    921         if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){
   980    922           zF = stdout;
   981    923         }else{
................................................................................
   984    926         }
   985    927         if( ! zF ){
   986    928           fossil_fatal("wiki export could not open output file for writing.");
   987    929         }
   988    930         fprintf(zF,"%.*s\n", i, zBody);
   989    931         if( doClose ) fclose(zF);
   990    932       }else{
   991         -	printf("%.*s\n", i, zBody);
          933  +      printf("%.*s\n", i, zBody);
   992    934       }
          935  +    manifest_destroy(pWiki);
   993    936       return;
   994    937     }else
   995    938     if( strncmp(g.argv[2],"commit",n)==0
   996    939         || strncmp(g.argv[2],"create",n)==0 ){
   997    940       char *zPageName;
   998    941       Blob content;
   999    942       if( g.argc!=4 && g.argc!=5 ){

Changes to src/wikiformat.c.

   148    148   ** Allowed markup.
   149    149   **
   150    150   ** Except for MARKUP_INVALID, this must all be in alphabetical order
   151    151   ** and in numerical sequence.  The first markup type must be zero.
   152    152   ** The value for MARKUP_XYZ must correspond to the <xyz> entry
   153    153   ** in aAllowedMarkup[].
   154    154   */
   155         -#define MARKUP_INVALID           0
   156         -#define MARKUP_A                 1
   157         -#define MARKUP_ADDRESS           2
   158         -#define MARKUP_B                 3
   159         -#define MARKUP_BIG               4
   160         -#define MARKUP_BLOCKQUOTE        5
   161         -#define MARKUP_BR                6
   162         -#define MARKUP_CENTER            7
   163         -#define MARKUP_CITE              8
   164         -#define MARKUP_CODE              9
   165         -#define MARKUP_DD               10
   166         -#define MARKUP_DFN              11
   167         -#define MARKUP_DIV              12
   168         -#define MARKUP_DL               13
   169         -#define MARKUP_DT               14
   170         -#define MARKUP_EM               15
   171         -#define MARKUP_FONT             16
   172         -#define MARKUP_H1               17
   173         -#define MARKUP_H2               18
   174         -#define MARKUP_H3               19
   175         -#define MARKUP_H4               20
   176         -#define MARKUP_H5               21
   177         -#define MARKUP_H6               22
   178         -#define MARKUP_HR               23
   179         -#define MARKUP_I                24
   180         -#define MARKUP_IMG              25
   181         -#define MARKUP_KBD              26
   182         -#define MARKUP_LI               27
   183         -#define MARKUP_NOBR             28
   184         -#define MARKUP_NOWIKI           29
   185         -#define MARKUP_OL               30
   186         -#define MARKUP_P                31
   187         -#define MARKUP_PRE              32
   188         -#define MARKUP_S                33
   189         -#define MARKUP_SAMP             34
   190         -#define MARKUP_SMALL            35
   191         -#define MARKUP_STRIKE           36
   192         -#define MARKUP_STRONG           37
   193         -#define MARKUP_SUB              38
   194         -#define MARKUP_SUP              39
   195         -#define MARKUP_TABLE            40
   196         -#define MARKUP_TD               41
   197         -#define MARKUP_TH               42
   198         -#define MARKUP_TR               43
   199         -#define MARKUP_TT               44
   200         -#define MARKUP_U                45
   201         -#define MARKUP_UL               46
   202         -#define MARKUP_VAR              47
   203         -#define MARKUP_VERBATIM         48
          155  +#define MARKUP_INVALID            0
          156  +#define MARKUP_A                  1
          157  +#define MARKUP_ADDRESS            2
          158  +#define MARKUP_B                  3
          159  +#define MARKUP_BIG                4
          160  +#define MARKUP_BLOCKQUOTE         5
          161  +#define MARKUP_BR                 6
          162  +#define MARKUP_CENTER             7
          163  +#define MARKUP_CITE               8
          164  +#define MARKUP_CODE               9
          165  +#define MARKUP_COL                10
          166  +#define MARKUP_COLGROUP           11
          167  +#define MARKUP_DD                 12
          168  +#define MARKUP_DFN                13
          169  +#define MARKUP_DIV                14
          170  +#define MARKUP_DL                 15
          171  +#define MARKUP_DT                 16
          172  +#define MARKUP_EM                 17
          173  +#define MARKUP_FONT               18
          174  +#define MARKUP_H1                 19
          175  +#define MARKUP_H2                 20
          176  +#define MARKUP_H3                 21
          177  +#define MARKUP_H4                 22
          178  +#define MARKUP_H5                 23
          179  +#define MARKUP_H6                 24
          180  +#define MARKUP_HR                 25
          181  +#define MARKUP_I                  26
          182  +#define MARKUP_IMG                27
          183  +#define MARKUP_KBD                28
          184  +#define MARKUP_LI                 29
          185  +#define MARKUP_NOBR               30
          186  +#define MARKUP_NOWIKI             31
          187  +#define MARKUP_OL                 32
          188  +#define MARKUP_P                  33
          189  +#define MARKUP_PRE                34
          190  +#define MARKUP_S                  35
          191  +#define MARKUP_SAMP               36
          192  +#define MARKUP_SMALL              37
          193  +#define MARKUP_SPAN               38
          194  +#define MARKUP_STRIKE             39
          195  +#define MARKUP_STRONG             40
          196  +#define MARKUP_SUB                41
          197  +#define MARKUP_SUP                42
          198  +#define MARKUP_TABLE              43
          199  +#define MARKUP_TBODY              44
          200  +#define MARKUP_TD                 45
          201  +#define MARKUP_TFOOT              46
          202  +#define MARKUP_TH                 47
          203  +#define MARKUP_THEAD              48
          204  +#define MARKUP_TR                 49
          205  +#define MARKUP_TT                 50
          206  +#define MARKUP_U                  51
          207  +#define MARKUP_UL                 52
          208  +#define MARKUP_VAR                53
          209  +#define MARKUP_VERBATIM           54
   204    210   
   205    211   /*
   206    212   ** The various markup is divided into the following types:
   207    213   */
   208    214   #define MUTYPE_SINGLE      0x0001   /* <img>, <br>, or <hr> */
   209    215   #define MUTYPE_BLOCK       0x0002   /* Forms a new paragraph. ex: <p>, <h2> */
   210    216   #define MUTYPE_FONT        0x0004   /* Font changes. ex: <b>, <font>, <sub> */
................................................................................
   239    245    { "b",             MARKUP_B,            MUTYPE_FONT,          0  },
   240    246    { "big",           MARKUP_BIG,          MUTYPE_FONT,          0  },
   241    247    { "blockquote",    MARKUP_BLOCKQUOTE,   MUTYPE_BLOCK,         0  },
   242    248    { "br",            MARKUP_BR,           MUTYPE_SINGLE,        AMSK_CLEAR  },
   243    249    { "center",        MARKUP_CENTER,       MUTYPE_BLOCK,         0  },
   244    250    { "cite",          MARKUP_CITE,         MUTYPE_FONT,          0  },
   245    251    { "code",          MARKUP_CODE,         MUTYPE_FONT,          0  },
          252  + { "col",           MARKUP_COL,          MUTYPE_SINGLE,
          253  +                    AMSK_ALIGN|AMSK_CLASS|AMSK_COLSPAN|AMSK_WIDTH  },
          254  + { "colgroup",      MARKUP_COLGROUP,     MUTYPE_BLOCK,
          255  +                    AMSK_ALIGN|AMSK_CLASS|AMSK_COLSPAN|AMSK_WIDTH},
   246    256    { "dd",            MARKUP_DD,           MUTYPE_LI,            0  },
   247    257    { "dfn",           MARKUP_DFN,          MUTYPE_FONT,          0  },
   248    258    { "div",           MARKUP_DIV,          MUTYPE_BLOCK,         AMSK_ID|AMSK_CLASS      },
   249    259    { "dl",            MARKUP_DL,           MUTYPE_LIST,          AMSK_COMPACT },
   250    260    { "dt",            MARKUP_DT,           MUTYPE_LI,            0  },
   251    261    { "em",            MARKUP_EM,           MUTYPE_FONT,          0  },
   252    262    { "font",          MARKUP_FONT,         MUTYPE_FONT,
................................................................................
   271    281    { "ol",            MARKUP_OL,           MUTYPE_LIST,
   272    282                       AMSK_START|AMSK_TYPE|AMSK_COMPACT  },
   273    283    { "p",             MARKUP_P,            MUTYPE_BLOCK,         AMSK_ALIGN|AMSK_CLASS  },
   274    284    { "pre",           MARKUP_PRE,          MUTYPE_BLOCK,         0  },
   275    285    { "s",             MARKUP_S,            MUTYPE_FONT,          0  },
   276    286    { "samp",          MARKUP_SAMP,         MUTYPE_FONT,          0  },
   277    287    { "small",         MARKUP_SMALL,        MUTYPE_FONT,          0  },
          288  + { "span",          MARKUP_SPAN,         MUTYPE_BLOCK,         AMSK_ALIGN|AMSK_CLASS  },
   278    289    { "strike",        MARKUP_STRIKE,       MUTYPE_FONT,          0  },
   279    290    { "strong",        MARKUP_STRONG,       MUTYPE_FONT,          0  },
   280    291    { "sub",           MARKUP_SUB,          MUTYPE_FONT,          0  },
   281    292    { "sup",           MARKUP_SUP,          MUTYPE_FONT,          0  },
   282    293    { "table",         MARKUP_TABLE,        MUTYPE_TABLE,
   283    294                       AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING|
   284    295                       AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE|AMSK_CLASS  },
          296  + { "tbody",         MARKUP_TBODY,        MUTYPE_BLOCK,         AMSK_ALIGN|AMSK_CLASS  },
   285    297    { "td",            MARKUP_TD,           MUTYPE_TD,
   286    298                       AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
   287    299                       AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS  },
          300  + { "tfoot",         MARKUP_TFOOT,        MUTYPE_BLOCK,         AMSK_ALIGN|AMSK_CLASS  },
   288    301    { "th",            MARKUP_TH,           MUTYPE_TD,
   289    302                       AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
   290    303                       AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS  },
          304  + { "thead",         MARKUP_THEAD,        MUTYPE_BLOCK,         AMSK_ALIGN|AMSK_CLASS  },
   291    305    { "tr",            MARKUP_TR,           MUTYPE_TR,
   292    306                       AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN|AMSK_CLASS  },
   293    307    { "tt",            MARKUP_TT,           MUTYPE_FONT,          0  },
   294    308    { "u",             MARKUP_U,            MUTYPE_FONT,          0  },
   295    309    { "ul",            MARKUP_UL,           MUTYPE_LIST,
   296    310                       AMSK_TYPE|AMSK_COMPACT  },
   297    311    { "var",           MARKUP_VAR,          MUTYPE_FONT,          0  },
   298    312    { "verbatim",      MARKUP_VERBATIM,     MUTYPE_SPECIAL,       AMSK_ID|AMSK_TYPE },
   299    313   };
          314  +
          315  +void show_allowed_wiki_markup( void ){
          316  +  int i; /* loop over allowedAttr */
          317  +
          318  +  for( i=1 ; i<=sizeof(aMarkup)/sizeof(aMarkup[0]) - 1 ; i++ ){
          319  +    @ &lt;%s(aMarkup[i].zName)&gt;
          320  +  }
          321  +}
   300    322   
   301    323   /*
   302    324   ** Use binary search to locate a tag in the aMarkup[] table.
   303    325   */
   304    326   static int findTag(const char *z){
   305    327     int i, c, first, last;
   306    328     first = 1;
................................................................................
   319    341     }
   320    342     return MARKUP_INVALID;
   321    343   }
   322    344   
   323    345   /*
   324    346   ** Token types
   325    347   */
   326         -#define TOKEN_MARKUP        1    /* <...> */
   327         -#define TOKEN_CHARACTER     2    /* "&" or "<" not part of markup */
   328         -#define TOKEN_LINK          3    /* [...] */
   329         -#define TOKEN_PARAGRAPH     4    /* blank lines */
   330         -#define TOKEN_NEWLINE       5    /* A single "\n" */
   331         -#define TOKEN_BUL_LI        6    /*  "  *  " */
   332         -#define TOKEN_NUM_LI        7    /*  "  #  " */
   333         -#define TOKEN_ENUM          8    /*  "  \(?\d+[.)]?  " */
   334         -#define TOKEN_INDENT        9    /*  "   " */
   335         -#define TOKEN_RAW           10   /* Output exactly (used when wiki-use-html==1) */
   336         -#define TOKEN_TEXT          11   /* None of the above */
          348  +#define TOKEN_MARKUP        1  /* <...> */
          349  +#define TOKEN_CHARACTER     2  /* "&" or "<" not part of markup */
          350  +#define TOKEN_LINK          3  /* [...] */
          351  +#define TOKEN_PARAGRAPH     4  /* blank lines */
          352  +#define TOKEN_NEWLINE       5  /* A single "\n" */
          353  +#define TOKEN_BUL_LI        6  /*  "  *  " */
          354  +#define TOKEN_NUM_LI        7  /*  "  #  " */
          355  +#define TOKEN_ENUM          8  /*  "  \(?\d+[.)]?  " */
          356  +#define TOKEN_INDENT        9  /*  "   " */
          357  +#define TOKEN_RAW           10 /* Output exactly (used when wiki-use-html==1) */
          358  +#define TOKEN_TEXT          11 /* None of the above */
   337    359   
   338    360   /*
   339    361   ** State flags
   340    362   */
   341    363   #define AT_NEWLINE          0x001  /* At start of a line */
   342    364   #define AT_PARAGRAPH        0x002  /* At start of a paragraph */
   343    365   #define ALLOW_WIKI          0x004  /* Allow wiki markup */
................................................................................
   377    399   */
   378    400   static int wikiUsesHtml(void){
   379    401     static int r = -1;
   380    402     if( r<0 ) r = db_get_boolean("wiki-use-html", 0);
   381    403     return r;
   382    404   }
   383    405   
   384         -
   385    406   /*
   386    407   ** z points to a "<" character.  Check to see if this is the start of
   387    408   ** a valid markup.  If it is, return the total number of characters in
   388    409   ** the markup including the initial "<" and the terminating ">".  If
   389    410   ** it is not well-formed markup, return 0.
   390    411   */
   391    412   static int markupLength(const char *z){
   392    413     int n = 1;
   393    414     int inparen = 0;
   394    415     int c;
   395    416     if( z[n]=='/' ){ n++; }
   396         -  if( !isalpha(z[n]) ) return 0;
   397         -  while( isalnum(z[n]) ){ n++; }
   398         -  if( (c = z[n])!='>' && !isspace(c) ) return 0;
          417  +  if( !fossil_isalpha(z[n]) ) return 0;
          418  +  while( fossil_isalnum(z[n]) ){ n++; }
          419  +  c = z[n];
          420  +  if( c=='/' && z[n+1]=='>' ){ return n+2; }
          421  +  if( c!='>' && !fossil_isspace(c) ) return 0;
   399    422     while( (c = z[n])!=0 && (c!='>' || inparen) ){
   400    423       if( c==inparen ){
   401    424         inparen = 0;
   402         -    }else if( c=='"' || c=='\'' ){
          425  +    }else if( inparen==0 && (c=='"' || c=='\'') ){
   403    426         inparen = c;
   404    427       }
   405    428       n++;
   406    429     }
   407    430     if( z[n]!='>' ) return 0;
   408    431     return n+1;
   409    432   }
................................................................................
   412    435   ** z points to a "\n" character.  Check to see if this newline is
   413    436   ** followed by one or more blank lines.  If it is, return the number
   414    437   ** of characters through the closing "\n".  If not, return 0.
   415    438   */
   416    439   static int paragraphBreakLength(const char *z){
   417    440     int i, n;
   418    441     int nNewline = 1;
   419         -  for(i=1, n=0; isspace(z[i]); i++){
          442  +  for(i=1, n=0; fossil_isspace(z[i]); i++){
   420    443       if( z[i]=='\n' ){
   421    444         nNewline++;
   422    445         n = i;
   423    446       }
   424    447     }
   425    448     if( nNewline>=2 ){
   426    449       return n+1;
................................................................................
   457    480   /*
   458    481   ** Return true if z[] begins with an HTML character element.
   459    482   */
   460    483   static int isElement(const char *z){
   461    484     int i;
   462    485     assert( z[0]=='&' );
   463    486     if( z[1]=='#' ){
   464         -    for(i=2; isdigit(z[i]); i++){}
          487  +    for(i=2; fossil_isdigit(z[i]); i++){}
   465    488       return i>2 && z[i]==';';
   466    489     }else{
   467         -    for(i=1; isalpha(z[i]); i++){}
          490  +    for(i=1; fossil_isalpha(z[i]); i++){}
   468    491       return i>1 && z[i]==';';
   469    492     }
   470    493   }
   471    494   
   472    495   /*
   473    496   ** Check to see if the z[] string is the beginning of a wiki list item.
   474    497   ** If it is, return the length of the bullet text.  Otherwise return 0.
................................................................................
   486    509     n++;
   487    510     i = 0;
   488    511     while( z[n]==' ' || z[n]=='\t' ){
   489    512       if( z[n]=='\t' ) i++;
   490    513       i++;
   491    514       n++;
   492    515     }
   493         -  if( i<2 || isspace(z[n]) ) return 0;
          516  +  if( i<2 || fossil_isspace(z[n]) ) return 0;
   494    517     return n;
   495    518   }
   496    519   
   497    520   /*
   498    521   ** Check to see if the z[] string is the beginning of a enumeration value.
   499    522   ** If it is, return the length of the bullet text.  Otherwise return 0.
   500    523   **
................................................................................
   511    534     i = 0;
   512    535     while( z[n]==' ' || z[n]=='\t' ){
   513    536       if( z[n]=='\t' ) i++;
   514    537       i++;
   515    538       n++;
   516    539     }
   517    540     if( i<2 ) return 0;
   518         -  for(i=0; isdigit(z[n]); i++, n++){}
          541  +  for(i=0; fossil_isdigit(z[n]); i++, n++){}
   519    542     if( i==0 ) return 0;
   520    543     if( z[n]=='.' ){
   521    544       n++;
   522    545     }
   523    546     i = 0;
   524    547     while( z[n]==' ' || z[n]=='\t' ){
   525    548       if( z[n]=='\t' ) i++;
   526    549       i++;
   527    550       n++;
   528    551     }
   529         -  if( i<2 || isspace(z[n]) ) return 0;
          552  +  if( i<2 || fossil_isspace(z[n]) ) return 0;
   530    553     return n;
   531    554   }
   532    555   
   533    556   /*
   534    557   ** Check to see if the z[] string is the beginning of an indented
   535    558   ** paragraph.  If it is, return the length of the indent.  Otherwise
   536    559   ** return 0.
................................................................................
   540    563     n = 0;
   541    564     i = 0;
   542    565     while( z[n]==' ' || z[n]=='\t' ){
   543    566       if( z[n]=='\t' ) i++;
   544    567       i++;
   545    568       n++;
   546    569     }
   547         -  if( i<2 || isspace(z[n]) ) return 0;
          570  +  if( i<2 || fossil_isspace(z[n]) ) return 0;
   548    571     return n;
   549    572   }
   550    573   
   551    574   /*
   552    575   ** Check to see if the z[] string is a wiki hyperlink.  If it is,
   553    576   ** return the length of the hyperlink.  Otherwise return 0.
   554    577   */
................................................................................
   587    610     }
   588    611     if( (p->state & ALLOW_WIKI)!=0 ){
   589    612       if( z[0]=='\n' ){
   590    613         n = paragraphBreakLength(z);
   591    614         if( n>0 ){
   592    615           *pTokenType = TOKEN_PARAGRAPH;
   593    616           return n;
   594         -      }else if( isspace(z[1]) ){
          617  +      }else if( fossil_isspace(z[1]) ){
   595    618           *pTokenType = TOKEN_NEWLINE;
   596    619           return 1;
   597    620         }
   598    621       }
   599         -    if( (p->state & AT_NEWLINE)!=0 && isspace(z[0]) ){
          622  +    if( (p->state & AT_NEWLINE)!=0 && fossil_isspace(z[0]) ){
   600    623         n = listItemLength(z, '*');
   601    624         if( n>0 ){
   602    625           *pTokenType = TOKEN_BUL_LI;
   603    626           return n;
   604    627         }
   605    628         n = listItemLength(z, '#');
   606    629         if( n>0 ){
................................................................................
   609    632         }
   610    633         n = enumLength(z);
   611    634         if( n>0 ){
   612    635           *pTokenType = TOKEN_ENUM;
   613    636           return n;
   614    637         }
   615    638       }
   616         -    if( (p->state & AT_PARAGRAPH)!=0 && isspace(z[0]) ){
          639  +    if( (p->state & AT_PARAGRAPH)!=0 && fossil_isspace(z[0]) ){
   617    640         n = indentLength(z);
   618    641         if( n>0 ){
   619    642           *pTokenType = TOKEN_INDENT;
   620    643           return n;
   621    644         }
   622    645       }
   623    646       if( z[0]=='[' && (n = linkLength(z))>0 ){
................................................................................
   680    703       p->endTag = 1;
   681    704       i = 2;
   682    705     }else{
   683    706       p->endTag = 0;
   684    707       i = 1;
   685    708     }
   686    709     j = 0;
   687         -  while( isalnum(z[i]) ){
   688         -    if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
          710  +  while( fossil_isalnum(z[i]) ){
          711  +    if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
   689    712       i++;
   690    713     }
   691    714     zTag[j] = 0;
   692    715     p->iCode = findTag(zTag);
   693    716     p->iType = aMarkup[p->iCode].iType;
   694    717     p->nAttr = 0;
   695         -  while( isspace(z[i]) ){ i++; }
   696         -  while( p->nAttr<8 && isalpha(z[i]) ){
          718  +  while( fossil_isspace(z[i]) ){ i++; }
          719  +  while( p->nAttr<8 && fossil_isalpha(z[i]) ){
   697    720       int attrOk;    /* True to preserver attribute.  False to ignore it */
   698    721       j = 0;
   699         -    while( isalnum(z[i]) ){
   700         -      if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
          722  +    while( fossil_isalnum(z[i]) ){
          723  +      if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
   701    724         i++;
   702    725       }
   703    726       zTag[j] = 0;
   704    727       p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
   705    728       attrOk = iACode!=0 && (seen & aAttribute[iACode].iMask)==0;
   706         -    while( isspace(z[i]) ){ z++; }
          729  +    while( fossil_isspace(z[i]) ){ z++; }
   707    730       if( z[i]!='=' ){
   708    731         p->aAttr[p->nAttr].zValue = 0;
   709    732         p->aAttr[p->nAttr].cTerm = 0;
   710    733         c = 0;
   711    734       }else{
   712    735         i++;
   713         -      while( isspace(z[i]) ){ z++; }
          736  +      while( fossil_isspace(z[i]) ){ z++; }
   714    737         if( z[i]=='"' ){
   715    738           i++;
   716    739           zValue = &z[i];
   717    740           while( z[i] && z[i]!='"' ){ i++; }
   718    741         }else if( z[i]=='\'' ){
   719    742           i++;
   720    743           zValue = &z[i];
   721    744           while( z[i] && z[i]!='\'' ){ i++; }
   722    745         }else{
   723    746           zValue = &z[i];
   724         -        while( !isspace(z[i]) && z[i]!='>' ){ z++; }
          747  +        while( !fossil_isspace(z[i]) && z[i]!='>' ){ z++; }
   725    748         }
   726    749         if( attrOk ){
   727    750           p->aAttr[p->nAttr].zValue = zValue;
   728    751           p->aAttr[p->nAttr].cTerm = c = z[i];
   729    752           z[i] = 0;
   730    753         }
   731    754         i++;
   732    755       }
   733    756       if( attrOk ){
   734    757         seen |= aAttribute[iACode].iMask;
   735    758         p->nAttr++;
   736    759       }
   737         -    while( isspace(z[i]) ){ i++; }
          760  +    while( fossil_isspace(z[i]) ){ i++; }
   738    761       if( z[i]=='>' || (z[i]=='/' && z[i+1]=='>') ) break;
   739    762     }
   740    763   }
   741    764   
   742    765   /*
   743    766   ** Render markup on the given blob.
   744    767   */
................................................................................
   754    777           const char *zVal = p->aAttr[i].zValue;
   755    778           if( p->aAttr[i].iACode==ATTR_SRC && zVal[0]=='/' ){
   756    779             blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal);
   757    780           }else{
   758    781             blob_appendf(pOut, "=\"%s\"", zVal);
   759    782           }
   760    783         }
          784  +    }
          785  +    if (p->iType & MUTYPE_SINGLE){
          786  +      blob_append(pOut, " /", 2);
   761    787       }
   762    788       blob_append(pOut, ">", 1);
   763    789     }
   764    790   }
   765    791   
   766    792   /*
   767    793   ** When the markup was parsed, some "\000" may have been inserted.
................................................................................
   810    836   /*
   811    837   ** Push a new markup value onto the stack.  Enlarge the stack
   812    838   ** if necessary.
   813    839   */
   814    840   static void pushStackWithId(Renderer *p, int elem, const char *zId, int w){
   815    841     if( p->nStack>=p->nAlloc ){
   816    842       p->nAlloc = p->nAlloc*2 + 100;
   817         -    p->aStack = realloc(p->aStack, p->nAlloc*sizeof(p->aStack[0]));
   818         -    if( p->aStack==0 ){
   819         -      fossil_panic("out of memory");
   820         -    }
          843  +    p->aStack = fossil_realloc(p->aStack, p->nAlloc*sizeof(p->aStack[0]));
   821    844     }
   822    845     p->aStack[p->nStack].iCode = elem;
   823    846     p->aStack[p->nStack].zId = zId;
   824    847     p->aStack[p->nStack].allowWiki = w;
   825    848     p->nStack++;
   826    849   }
   827    850   static void pushStack(Renderer *p, int elem){
................................................................................
   883    906     return p->aStack[i-1].iCode;
   884    907   }
   885    908   
   886    909   /*
   887    910   ** Begin a new paragraph if that something that is needed.
   888    911   */
   889    912   static void startAutoParagraph(Renderer *p){
   890         -  if( p->wantAutoParagraph==0 || p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
          913  +  if( p->wantAutoParagraph==0 ) return;
          914  +  if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
   891    915     blob_appendf(p->pOut, "<p>", -1);
   892    916     pushStack(p, MARKUP_P);
   893    917     p->wantAutoParagraph = 0;
   894    918     p->inAutoParagraph = 1;
   895    919   }
   896    920   
   897    921   /*
................................................................................
  1017   1041       int isClosed = 0;
  1018   1042       if( is_ticket(zTarget, &isClosed) ){
  1019   1043         /* Special display processing for tickets.  Display the hyperlink
  1020   1044         ** as crossed out if the ticket is closed.
  1021   1045         */
  1022   1046         if( isClosed ){
  1023   1047           if( g.okHistory ){
  1024         -          blob_appendf(p->pOut,"<a href=\"%s/info/%s\"><s>",
  1025         -              g.zBaseURL, zTarget
         1048  +          blob_appendf(p->pOut,
         1049  +             "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">",
         1050  +             g.zBaseURL, zTarget
  1026   1051             );
  1027         -          zTerm = "</s></a>";
         1052  +          zTerm = "</span></a>";
  1028   1053           }else{
  1029         -          blob_appendf(p->pOut,"<s>");
  1030         -          zTerm = "</s>";
         1054  +          blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">");
         1055  +          zTerm = "</span>";
  1031   1056           }
  1032   1057         }else{
  1033   1058           if( g.okHistory ){
  1034   1059             blob_appendf(p->pOut,"<a href=\"%s/info/%s\">",
  1035   1060                 g.zBaseURL, zTarget
  1036   1061             );
  1037   1062           }else{
  1038   1063             zTerm = "";
  1039   1064           }
  1040   1065         }
  1041   1066       }else if( g.okHistory ){
  1042   1067         blob_appendf(p->pOut, "<a href=\"%s/info/%s\">", g.zBaseURL, zTarget);
  1043   1068       }
  1044         -  }else if( strlen(zTarget)>=10 && isdigit(zTarget[0]) && zTarget[4]=='-'
         1069  +  }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
  1045   1070               && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
  1046   1071       blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zBaseURL, zTarget);
  1047   1072     }else if( strncmp(zTarget, "wiki:", 5)==0 
  1048   1073           && wiki_name_is_wellformed((const unsigned char*)zTarget) ){
  1049   1074       zTarget += 5;
  1050   1075       blob_appendf(p->pOut, "<a href=\"%s/wiki?name=%T\">", g.zBaseURL, zTarget);
  1051   1076     }else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
................................................................................
  1131   1156           if( inlineOnly ){
  1132   1157             blob_append(p->pOut, " &bull; ", -1);
  1133   1158           }else{
  1134   1159             if( p->wikiList!=MARKUP_UL ){
  1135   1160               if( p->wikiList ){
  1136   1161                 popStackToTag(p, p->wikiList);
  1137   1162               }
         1163  +            endAutoParagraph(p);
  1138   1164               pushStack(p, MARKUP_UL);
  1139   1165               blob_append(p->pOut, "<ul>", 4);
  1140   1166               p->wikiList = MARKUP_UL;
  1141   1167             }
  1142   1168             popStackToTag(p, MARKUP_LI);
  1143   1169             startAutoParagraph(p);
  1144   1170             pushStack(p, MARKUP_LI);
................................................................................
  1150   1176           if( inlineOnly ){
  1151   1177             blob_append(p->pOut, " # ", -1);
  1152   1178           }else{
  1153   1179             if( p->wikiList!=MARKUP_OL ){
  1154   1180               if( p->wikiList ){
  1155   1181                 popStackToTag(p, p->wikiList);
  1156   1182               }
         1183  +            endAutoParagraph(p);
  1157   1184               pushStack(p, MARKUP_OL);
  1158   1185               blob_append(p->pOut, "<ol>", 4);
  1159   1186               p->wikiList = MARKUP_OL;
  1160   1187             }
  1161   1188             popStackToTag(p, MARKUP_LI);
  1162   1189             startAutoParagraph(p);
  1163   1190             pushStack(p, MARKUP_LI);
................................................................................
  1169   1196           if( inlineOnly ){
  1170   1197             blob_appendf(p->pOut, " (%d) ", atoi(z));
  1171   1198           }else{
  1172   1199             if( p->wikiList!=MARKUP_OL ){
  1173   1200               if( p->wikiList ){
  1174   1201                 popStackToTag(p, p->wikiList);
  1175   1202               }
         1203  +            endAutoParagraph(p);
  1176   1204               pushStack(p, MARKUP_OL);
  1177   1205               blob_append(p->pOut, "<ol>", 4);
  1178   1206               p->wikiList = MARKUP_OL;
  1179   1207             }
  1180   1208             popStackToTag(p, MARKUP_LI);
  1181   1209             startAutoParagraph(p);
  1182   1210             pushStack(p, MARKUP_LI);
................................................................................
  1212   1240   
  1213   1241           startAutoParagraph(p);
  1214   1242           zTarget = &z[1];
  1215   1243           for(i=1; z[i] && z[i]!=']'; i++){
  1216   1244             if( z[i]=='|' && zDisplay==0 ){
  1217   1245               zDisplay = &z[i+1];
  1218   1246               z[i] = 0;
  1219         -            for(j=i-1; j>0 && isspace(z[j]); j--){ z[j] = 0; }
         1247  +            for(j=i-1; j>0 && fossil_isspace(z[j]); j--){ z[j] = 0; }
  1220   1248             }
  1221   1249           }
  1222   1250           z[i] = 0;
  1223   1251           if( zDisplay==0 ){
  1224   1252             zDisplay = zTarget;
  1225   1253           }else{
  1226         -          while( isspace(*zDisplay) ) zDisplay++;
         1254  +          while( fossil_isspace(*zDisplay) ) zDisplay++;
  1227   1255           }
  1228   1256           openHyperlink(p, zTarget, zClose, sizeof(zClose));
  1229   1257           savedState = p->state;
  1230   1258           p->state &= ~ALLOW_WIKI;
  1231   1259           p->state |= FONT_MARKUP_ONLY;
  1232   1260           wiki_render(p, zDisplay);
  1233   1261           p->state = savedState;
  1234   1262           blob_append(p->pOut, zClose, -1);
  1235   1263           break;
  1236   1264         }
  1237   1265         case TOKEN_TEXT: {
  1238         -        startAutoParagraph(p);
         1266  +        int i;
         1267  +        for(i=0; i<n && fossil_isspace(z[i]); i++){}
         1268  +        if( i<n ) startAutoParagraph(p);
  1239   1269           blob_append(p->pOut, z, n);
  1240   1270           break;
  1241   1271         }
  1242   1272         case TOKEN_RAW: {
  1243   1273           blob_append(p->pOut, z, n);
  1244   1274           break;
  1245   1275         }
................................................................................
  1345   1375                 p->zVerbatimId = markup.aAttr[0].zValue;
  1346   1376               }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
  1347   1377                 blob_appendf(p->pOut, "<pre name='code' class='%s'>",
  1348   1378                   markup.aAttr[vAttrIdx].zValue);
  1349   1379                 vAttrDidAppend=1;
  1350   1380               }
  1351   1381             }
  1352         -          if( !vAttrDidAppend )
         1382  +          if( !vAttrDidAppend ) {
         1383  +            endAutoParagraph(p);
  1353   1384               blob_append(p->pOut, "<pre class='verbatim'>",-1);
         1385  +          }
  1354   1386             p->wantAutoParagraph = 0;
  1355   1387           }else
  1356   1388           if( markup.iType==MUTYPE_LI ){
  1357   1389             if( backupToType(p, MUTYPE_LIST)==0 ){
         1390  +            endAutoParagraph(p);
  1358   1391               pushStack(p, MARKUP_UL);
  1359   1392               blob_append(p->pOut, "<ul>", 4);
  1360   1393             }
  1361   1394             pushStack(p, MARKUP_LI);
  1362   1395             renderMarkup(p->pOut, &markup);
  1363   1396           }else
  1364   1397           if( markup.iType==MUTYPE_TR ){
................................................................................
  1382   1415             startAutoParagraph(p);
  1383   1416             renderMarkup(p->pOut, &markup);
  1384   1417             pushStack(p, markup.iCode);
  1385   1418           }else
  1386   1419           {
  1387   1420             if( markup.iType==MUTYPE_FONT ){
  1388   1421               startAutoParagraph(p);
  1389         -          }else if( markup.iType==MUTYPE_BLOCK ){
         1422  +          }else if( markup.iType==MUTYPE_BLOCK || markup.iType==MUTYPE_LIST ){
  1390   1423               p->wantAutoParagraph = 0;
         1424  +          }
         1425  +          if(   markup.iCode==MARKUP_HR
         1426  +             || markup.iCode==MARKUP_H1
         1427  +             || markup.iCode==MARKUP_H2
         1428  +             || markup.iCode==MARKUP_H3
         1429  +             || markup.iCode==MARKUP_H4
         1430  +             || markup.iCode==MARKUP_H5
         1431  +             || markup.iCode==MARKUP_P
         1432  +          ){
         1433  +            endAutoParagraph(p);
  1391   1434             }
  1392   1435             if( (markup.iType & MUTYPE_STACK )!=0 ){
  1393   1436               pushStack(p, markup.iCode);
  1394   1437             }
  1395   1438             renderMarkup(p->pOut, &markup);
  1396   1439           }
  1397   1440           break;
................................................................................
  1473   1516   ** title.
  1474   1517   */
  1475   1518   int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
  1476   1519     char *z;
  1477   1520     int i;
  1478   1521     int iStart;
  1479   1522     z = skip_bom(blob_str(pIn));
  1480         -  for(i=0; isspace(z[i]); i++){}
         1523  +  for(i=0; fossil_isspace(z[i]); i++){}
  1481   1524     if( z[i]!='<' ) return 0;
  1482   1525     i++;
  1483   1526     if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
  1484   1527     iStart = i+6;
  1485   1528     for(i=iStart; z[i] && (z[i]!='<' || strncmp(&z[i],"</title>",8)!=0); i++){}
  1486   1529     if( z[i]!='<' ) return 0;
  1487   1530     blob_init(pTitle, &z[iStart], i-iStart);

Changes to src/winhttp.c.

    14     14   **   http://www.hwaci.com/drh/
    15     15   **
    16     16   *******************************************************************************
    17     17   **
    18     18   ** This file implements a very simple (and low-performance) HTTP server
    19     19   ** for windows.
    20     20   */
    21         -#ifdef __MINGW32__           /* This code is for win32 only */
    22     21   #include "config.h"
           22  +#ifdef _WIN32
           23  +/* This code is for win32 only */
    23     24   #include "winhttp.h"
    24     25   #include <windows.h>
    25     26   
    26     27   /*
    27     28   ** The HttpRequest structure holds information about each incoming
    28     29   ** HTTP request.
    29     30   */
................................................................................
   103    104         break;
   104    105       }
   105    106       wanted -= got;
   106    107     }
   107    108     fclose(out);
   108    109     out = 0;
   109    110     sprintf(zCmd, "\"%s\" http \"%s\" %s %s %s%s",
   110         -    g.argv[0], g.zRepositoryName, zRequestFName, zReplyFName, 
          111  +    _pgmptr, g.zRepositoryName, zRequestFName, zReplyFName, 
   111    112       inet_ntoa(p->addr.sin_addr), p->zNotFound
   112    113     );
   113         -  portable_system(zCmd);
          114  +  fossil_system(zCmd);
   114    115     in = fopen(zReplyFName, "rb");
   115    116     if( in ){
   116    117       while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
   117    118         send(p->s, zHdr, got, 0);
   118    119       }
   119    120     }
   120    121   
................................................................................
   131    132   ** Start a listening socket and process incoming HTTP requests on
   132    133   ** that socket.
   133    134   */
   134    135   void win32_http_server(
   135    136     int mnPort, int mxPort,   /* Range of allowed TCP port numbers */
   136    137     const char *zBrowser,     /* Command to launch browser.  (Or NULL) */
   137    138     const char *zStopper,     /* Stop server when this file is exists (Or NULL) */
   138         -  const char *zNotFound     /* The --notfound option, or NULL */
          139  +  const char *zNotFound,    /* The --notfound option, or NULL */
          140  +  int flags                 /* One or more HTTP_SERVER_ flags */
   139    141   ){
   140    142     WSADATA wd;
   141    143     SOCKET s = INVALID_SOCKET;
   142    144     SOCKADDR_IN addr;
   143    145     int idCnt = 0;
   144    146     int iPort = mnPort;
   145    147     char *zNotFoundOption;
................................................................................
   156    158     while( iPort<=mxPort ){
   157    159       s = socket(AF_INET, SOCK_STREAM, 0);
   158    160       if( s==INVALID_SOCKET ){
   159    161         fossil_fatal("unable to create a socket");
   160    162       }
   161    163       addr.sin_family = AF_INET;
   162    164       addr.sin_port = htons(iPort);
   163         -    addr.sin_addr.s_addr = htonl(INADDR_ANY);
          165  +    if( flags & HTTP_SERVER_LOCALHOST ){
          166  +      addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
          167  +    }else{
          168  +      addr.sin_addr.s_addr = htonl(INADDR_ANY);
          169  +    }
   164    170       if( bind(s, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR ){
   165    171         closesocket(s);
   166    172         iPort++;
   167    173         continue;
   168    174       }
   169    175       if( listen(s, SOMAXCONN)==SOCKET_ERROR ){
   170    176         closesocket(s);
................................................................................
   182    188       }
   183    189     }
   184    190     zTempPrefix = mprintf("fossil_server_P%d_", iPort);
   185    191     printf("Listening for HTTP requests on TCP port %d\n", iPort);
   186    192     if( zBrowser ){
   187    193       zBrowser = mprintf(zBrowser, iPort);
   188    194       printf("Launch webbrowser: %s\n", zBrowser);
   189         -    portable_system(zBrowser);
          195  +    fossil_system(zBrowser);
   190    196     }
   191    197     printf("Type Ctrl-C to stop the HTTP server\n");
   192    198     for(;;){
   193    199       SOCKET client;
   194    200       SOCKADDR_IN client_addr;
   195    201       HttpRequest *p;
   196    202       int len = sizeof(client_addr);
................................................................................
   199    205       if( zStopper && file_size(zStopper)>=0 ){
   200    206         break;
   201    207       }
   202    208       if( client==INVALID_SOCKET ){
   203    209         closesocket(s);
   204    210         fossil_fatal("error from accept()");
   205    211       }
   206         -    p = malloc( sizeof(*p) );
   207         -    if( p==0 ){
   208         -      fossil_fatal("out of memory");
   209         -    }
          212  +    p = fossil_malloc( sizeof(*p) );
   210    213       p->id = ++idCnt;
   211    214       p->s = client;
   212    215       p->addr = client_addr;
   213    216       p->zNotFound = zNotFoundOption;
   214    217       _beginthread(win32_process_one_http_request, 0, (void*)p);
   215    218     }
   216    219     closesocket(s);
   217    220     WSACleanup();
   218    221   }
   219    222   
   220         -#endif /* __MINGW32__  -- This code is for win32 only */
          223  +#endif /* _WIN32  -- This code is for win32 only */

Changes to src/xfer.c.

    70     70   }
    71     71   
    72     72   /*
    73     73   ** Remember that the other side of the connection already has a copy
    74     74   ** of the file rid.
    75     75   */
    76     76   static void remote_has(int rid){
    77         -  if( rid ) db_multi_exec("INSERT OR IGNORE INTO onremote VALUES(%d)", rid);
           77  +  if( rid ){
           78  +    static Stmt q;
           79  +    db_static_prepare(&q, "INSERT OR IGNORE INTO onremote VALUES(:r)");
           80  +    db_bind_int(&q, ":r", rid);
           81  +    db_step(&q);
           82  +    db_reset(&q);
           83  +  }
    78     84   }
    79     85   
    80     86   /*
    81     87   ** The aToken[0..nToken-1] blob array is a parse of a "file" line 
    82     88   ** message.  This routine finishes parsing that message and does
    83     89   ** a record insert of the file.
    84     90   **
................................................................................
    93     99   **
    94    100   ** If any error occurs, write a message into pErr which has already
    95    101   ** be initialized to an empty string.
    96    102   **
    97    103   ** Any artifact successfully received by this routine is considered to
    98    104   ** be public and is therefore removed from the "private" table.
    99    105   */
   100         -static void xfer_accept_file(Xfer *pXfer){
          106  +static void xfer_accept_file(Xfer *pXfer, int cloneFlag){
   101    107     int n;
   102    108     int rid;
   103    109     int srcid = 0;
   104    110     Blob content, hash;
   105    111     
   106    112     if( pXfer->nToken<3 
   107    113      || pXfer->nToken>4
................................................................................
   112    118     ){
   113    119       blob_appendf(&pXfer->err, "malformed file line");
   114    120       return;
   115    121     }
   116    122     blob_zero(&content);
   117    123     blob_zero(&hash);
   118    124     blob_extract(pXfer->pIn, n, &content);
   119         -  if( uuid_is_shunned(blob_str(&pXfer->aToken[1])) ){
          125  +  if( !cloneFlag && uuid_is_shunned(blob_str(&pXfer->aToken[1])) ){
   120    126       /* Ignore files that have been shunned */
   121    127       return;
          128  +  }
          129  +  if( cloneFlag ){
          130  +    if( pXfer->nToken==4 ){
          131  +      srcid = rid_from_uuid(&pXfer->aToken[2], 1);
          132  +      pXfer->nDeltaRcvd++;
          133  +    }else{
          134  +      srcid = 0;
          135  +      pXfer->nFileRcvd++;
          136  +    }
          137  +    rid = content_put(&content, blob_str(&pXfer->aToken[1]), srcid);
          138  +    remote_has(rid);
          139  +    blob_reset(&content);
          140  +    return;
   122    141     }
   123    142     if( pXfer->nToken==4 ){
   124         -    Blob src;
          143  +    Blob src, next;
   125    144       srcid = rid_from_uuid(&pXfer->aToken[2], 1);
   126    145       if( content_get(srcid, &src)==0 ){
   127    146         rid = content_put(&content, blob_str(&pXfer->aToken[1]), srcid);
   128    147         pXfer->nDanglingFile++;
   129    148         db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
   130    149         content_make_public(rid);
   131    150         return;
   132    151       }
   133    152       pXfer->nDeltaRcvd++;
   134         -    blob_delta_apply(&src, &content, &content);
          153  +    blob_delta_apply(&src, &content, &next);
   135    154       blob_reset(&src);
          155  +    blob_reset(&content);
          156  +    content = next;
   136    157     }else{
   137    158       pXfer->nFileRcvd++;
   138    159     }
   139    160     sha1sum_blob(&content, &hash);
   140    161     if( !blob_eq_str(&pXfer->aToken[1], blob_str(&hash), -1) ){
   141    162       blob_appendf(&pXfer->err, "content does not match sha1 hash");
   142    163     }
................................................................................
   463    484   
   464    485   /*
   465    486   ** Check to see if the number of unclustered entries is greater than
   466    487   ** 100 and if it is, form a new cluster.  Unclustered phantoms do not
   467    488   ** count toward the 100 total.  And phantoms are never added to a new
   468    489   ** cluster.
   469    490   */
   470         -static void create_cluster(void){
          491  +void create_cluster(void){
   471    492     Blob cluster, cksum;
   472    493     Stmt q;
   473    494     int nUncl;
          495  +  int nRow = 0;
   474    496   
   475    497     /* We should not ever get any private artifacts in the unclustered table.
   476    498     ** But if we do (because of a bug) now is a good time to delete them. */
   477    499     db_multi_exec(
   478    500       "DELETE FROM unclustered WHERE rid IN (SELECT rid FROM private)"
   479    501     );
   480    502   
   481         -  nUncl = db_int(0, "SELECT count(*) FROM unclustered"
          503  +  nUncl = db_int(0, "SELECT count(*) FROM unclustered /*scan*/"
   482    504                       " WHERE NOT EXISTS(SELECT 1 FROM phantom"
   483    505                                         " WHERE rid=unclustered.rid)");
   484         -  if( nUncl<100 ){
   485         -    return;
   486         -  }
   487         -  blob_zero(&cluster);
   488         -  db_prepare(&q, "SELECT uuid FROM unclustered, blob"
   489         -                 " WHERE NOT EXISTS(SELECT 1 FROM phantom"
   490         -                 "                   WHERE rid=unclustered.rid)"
   491         -                 "   AND unclustered.rid=blob.rid"
   492         -                 "   AND NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
   493         -                 " ORDER BY 1");
   494         -  while( db_step(&q)==SQLITE_ROW ){
   495         -    blob_appendf(&cluster, "M %s\n", db_column_text(&q, 0));
   496         -  }
   497         -  db_finalize(&q);
   498         -  md5sum_blob(&cluster, &cksum);
   499         -  blob_appendf(&cluster, "Z %b\n", &cksum);
   500         -  blob_reset(&cksum);
   501         -  db_multi_exec("DELETE FROM unclustered");
   502         -  content_put(&cluster, 0, 0);
   503         -  blob_reset(&cluster);
          506  +  if( nUncl>=100 ){
          507  +    blob_zero(&cluster);
          508  +    db_prepare(&q, "SELECT uuid FROM unclustered, blob"
          509  +                   " WHERE NOT EXISTS(SELECT 1 FROM phantom"
          510  +                   "                   WHERE rid=unclustered.rid)"
          511  +                   "   AND unclustered.rid=blob.rid"
          512  +                   "   AND NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
          513  +                   " ORDER BY 1");
          514  +    while( db_step(&q)==SQLITE_ROW ){
          515  +      blob_appendf(&cluster, "M %s\n", db_column_text(&q, 0));
          516  +      nRow++;
          517  +      if( nRow>=800 && nUncl>nRow+100 ){
          518  +        md5sum_blob(&cluster, &cksum);
          519  +        blob_appendf(&cluster, "Z %b\n", &cksum);
          520  +        blob_reset(&cksum);
          521  +        content_put(&cluster, 0, 0);
          522  +        blob_reset(&cluster);
          523  +        nUncl -= nRow;
          524  +        nRow = 0;
          525  +      }
          526  +    }
          527  +    db_finalize(&q);
          528  +    db_multi_exec("DELETE FROM unclustered");
          529  +    if( nRow>0 ){
          530  +      md5sum_blob(&cluster, &cksum);
          531  +      blob_appendf(&cluster, "Z %b\n", &cksum);
          532  +      blob_reset(&cksum);
          533  +      content_put(&cluster, 0, 0);
          534  +      blob_reset(&cluster);
          535  +    }
          536  +  }
   504    537   }
   505    538   
   506    539   /*
   507    540   ** Send an igot message for every entry in unclustered table.
   508    541   ** Return the number of cards sent.
   509    542   */
   510    543   static int send_unclustered(Xfer *pXfer){
................................................................................
   591    624     int nErr = 0;
   592    625     Xfer xfer;
   593    626     int deltaFlag = 0;
   594    627     int isClone = 0;
   595    628     int nGimme = 0;
   596    629     int size;
   597    630     int recvConfig = 0;
          631  +  char *zNow;
   598    632   
   599    633     if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){
   600    634        fossil_redirect_home();
   601    635     }
   602    636     memset(&xfer, 0, sizeof(xfer));
   603    637     blobarray_zero(xfer.aToken, count(xfer.aToken));
   604    638     cgi_set_content_type(g.zContentType);
   605    639     blob_zero(&xfer.err);
   606    640     xfer.pIn = &g.cgiIn;
   607    641     xfer.pOut = cgi_output_blob();
   608         -  xfer.mxSend = db_get_int("max-download", 5000000);
          642  +  xfer.mxSend = db_get_int("max-download", 20000000);
   609    643     g.xferPanic = 1;
   610    644   
   611    645     db_begin_transaction();
   612    646     db_multi_exec(
   613    647        "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
   614    648     );
   615    649     manifest_crosslink_begin();
................................................................................
   625    659       if( blob_eq(&xfer.aToken[0], "file") ){
   626    660         if( !isPush ){
   627    661           cgi_reset_content();
   628    662           @ error not\sauthorized\sto\swrite
   629    663           nErr++;
   630    664           break;
   631    665         }
   632         -      xfer_accept_file(&xfer);
          666  +      xfer_accept_file(&xfer, 0);
   633    667         if( blob_size(&xfer.err) ){
   634    668           cgi_reset_content();
   635    669           @ error %T(blob_str(&xfer.err))
   636    670           nErr++;
   637    671           break;
   638    672         }
   639    673       }else
................................................................................
   711    745             }
   712    746           }else{
   713    747             isPush = 1;
   714    748           }
   715    749         }
   716    750       }else
   717    751   
   718         -    /*    clone
          752  +    /*    clone   ?PROTOCOL-VERSION?  ?SEQUENCE-NUMBER?
   719    753       **
   720    754       ** The client knows nothing.  Tell all.
   721    755       */
   722    756       if( blob_eq(&xfer.aToken[0], "clone") ){
          757  +      int iVers;
   723    758         login_check_credentials();
   724    759         if( !g.okClone ){
   725    760           cgi_reset_content();
   726    761           @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x"))
   727    762           @ error not\sauthorized\sto\sclone
   728    763           nErr++;
   729    764           break;
   730    765         }
   731         -      isClone = 1;
   732         -      isPull = 1;
   733         -      deltaFlag = 1;
          766  +      if( xfer.nToken==3
          767  +       && blob_is_int(&xfer.aToken[1], &iVers)
          768  +       && iVers>=2
          769  +      ){
          770  +        int seqno, max;
          771  +        blob_is_int(&xfer.aToken[2], &seqno);
          772  +        max = db_int(0, "SELECT max(rid) FROM blob");
          773  +        while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
          774  +          send_file(&xfer, seqno, 0, 1);
          775  +          seqno++;
          776  +        }
          777  +        if( seqno>=max ) seqno = 0;
          778  +        @ clone_seqno %d(seqno)
          779  +      }else{
          780  +        isClone = 1;
          781  +        isPull = 1;
          782  +        deltaFlag = 1;
          783  +      }
   734    784         @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x"))
   735    785       }else
   736    786   
   737    787       /*    login  USER  NONCE  SIGNATURE
   738    788       **
   739    789       ** Check for a valid login.  This has to happen before anything else.
   740    790       ** The client can send multiple logins.  Permissions are cumulative.
................................................................................
   867    917       create_cluster();
   868    918       send_unclustered(&xfer);
   869    919     }
   870    920     if( recvConfig ){
   871    921       configure_finalize_receive();
   872    922     }
   873    923     manifest_crosslink_end();
          924  +
          925  +  /* Send the server timestamp last, in case prior processing happened
          926  +  ** to use up a significant fraction of our time window.
          927  +  */
          928  +  zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')");
          929  +  @ # timestamp %s(zNow)
          930  +  free(zNow);
          931  +
   874    932     db_end_transaction(0);
   875    933   }
   876    934   
   877    935   /*
   878    936   ** COMMAND: test-xfer
   879    937   **
   880    938   ** This command is used for debugging the server.  There is a single
................................................................................
   936    994     int size;               /* Size of a config value */
   937    995     int nFileSend = 0;
   938    996     int origConfigRcvMask;  /* Original value of configRcvMask */
   939    997     int nFileRecv;          /* Number of files received */
   940    998     int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
   941    999     const char *zCookie;    /* Server cookie */
   942   1000     int nSent, nRcvd;       /* Bytes sent and received (after compression) */
         1001  +  int cloneSeqno = 1;     /* Sequence number for clones */
   943   1002     Blob send;              /* Text we are sending to the server */
   944   1003     Blob recv;              /* Reply we got back from the server */
   945   1004     Xfer xfer;              /* Transfer data */
         1005  +  int pctDone;            /* Percentage done with a message */
         1006  +  int lastPctDone = -1;   /* Last displayed pctDone */
         1007  +  double rArrivalTime;    /* Time at which a message arrived */
   946   1008     const char *zSCode = db_get("server-code", "x");
   947   1009     const char *zPCode = db_get("project-code", 0);
   948   1010   
   949   1011     if( db_get_boolean("dont-push", 0) ) pushFlag = 0;
   950   1012     if( pushFlag + pullFlag + cloneFlag == 0 
   951   1013        && configRcvMask==0 && configSendMask==0 ) return;
   952   1014   
................................................................................
   970   1032     blob_zero(&xfer.line);
   971   1033     origConfigRcvMask = 0;
   972   1034   
   973   1035     /*
   974   1036     ** Always begin with a clone, pull, or push message
   975   1037     */
   976   1038     if( cloneFlag ){
   977         -    blob_appendf(&send, "clone\n");
         1039  +    blob_appendf(&send, "clone 2 %d\n", cloneSeqno);
   978   1040       pushFlag = 0;
   979   1041       pullFlag = 0;
   980   1042       nCardSent++;
   981   1043       /* TBD: Request all transferable configuration values */
         1044  +    content_enable_dephantomize(0);
   982   1045     }else if( pullFlag ){
   983   1046       blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
   984   1047       nCardSent++;
   985   1048     }
   986   1049     if( pushFlag ){
   987   1050       blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
   988   1051       nCardSent++;
   989   1052     }
   990   1053     manifest_crosslink_begin();
         1054  +  transport_global_startup();
   991   1055     fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
   992   1056   
   993   1057     while( go ){
   994   1058       int newPhantom = 0;
   995   1059       char *zRandomness;
   996   1060   
   997   1061       /* Send make the most recently received cookie.  Let the server
................................................................................
  1001   1065       if( zCookie ){
  1002   1066         blob_appendf(&send, "cookie %s\n", zCookie);
  1003   1067       }
  1004   1068       
  1005   1069       /* Generate gimme cards for phantoms and leaf cards
  1006   1070       ** for all leaves.
  1007   1071       */
  1008         -    if( pullFlag || cloneFlag ){
         1072  +    if( pullFlag || (cloneFlag && cloneSeqno==1) ){
  1009   1073         request_phantoms(&xfer, mxPhantomReq);
  1010   1074       }
  1011   1075       if( pushFlag ){
  1012   1076         send_unsent(&xfer);
  1013   1077         nCardSent += send_unclustered(&xfer);
  1014   1078       }
  1015   1079   
................................................................................
  1050   1114       */
  1051   1115       zRandomness = db_text(0, "SELECT hex(randomblob(20))");
  1052   1116       blob_appendf(&send, "# %s\n", zRandomness);
  1053   1117       free(zRandomness);
  1054   1118   
  1055   1119       /* Exchange messages with the server */
  1056   1120       nFileSend = xfer.nFileSent + xfer.nDeltaSent;
  1057         -    fossil_print(zValueFormat, "Send:",
         1121  +    fossil_print(zValueFormat, "Sent:",
  1058   1122                    blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
  1059   1123                    xfer.nFileSent, xfer.nDeltaSent);
  1060   1124       nCardSent = 0;
  1061   1125       nCardRcvd = 0;
  1062   1126       xfer.nFileSent = 0;
  1063   1127       xfer.nDeltaSent = 0;
  1064   1128       xfer.nGimmeSent = 0;
  1065   1129       xfer.nIGotSent = 0;
         1130  +    if( !g.cgiOutput && !g.fQuiet ){
         1131  +      printf("waiting for server...");
         1132  +    }
  1066   1133       fflush(stdout);
  1067   1134       http_exchange(&send, &recv, cloneFlag==0 || nCycle>0);
         1135  +    lastPctDone = -1;
  1068   1136       blob_reset(&send);
         1137  +    rArrivalTime = db_double(0.0, "SELECT julianday('now')");
  1069   1138   
  1070   1139       /* Begin constructing the next message (which might never be
  1071   1140       ** sent) by beginning with the pull or push cards
  1072   1141       */
  1073   1142       if( pullFlag ){
  1074   1143         blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
  1075   1144         nCardSent++;
................................................................................
  1078   1147         blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
  1079   1148         nCardSent++;
  1080   1149       }
  1081   1150       go = 0;
  1082   1151   
  1083   1152       /* Process the reply that came back from the server */
  1084   1153       while( blob_line(&recv, &xfer.line) ){
         1154  +      if( g.fHttpTrace ){
         1155  +        printf("\rGOT: %.*s", (int)blob_size(&xfer.line),
         1156  +                              blob_buffer(&xfer.line));
         1157  +      }
  1085   1158         if( blob_buffer(&xfer.line)[0]=='#' ){
         1159  +        const char *zLine = blob_buffer(&xfer.line);
         1160  +        if( memcmp(zLine, "# timestamp ", 12)==0 ){
         1161  +          char zTime[20];
         1162  +          double rDiff;
         1163  +          sqlite3_snprintf(sizeof(zTime), zTime, "%.19s", &zLine[12]);
         1164  +          rDiff = db_double(9e99, "SELECT julianday('%q') - %.17g",
         1165  +                            zTime, rArrivalTime);
         1166  +          if( rDiff<0.0 ) rDiff = -rDiff;
         1167  +          if( rDiff>9e98 ) rDiff = 0.0;
         1168  +          if( (rDiff*24.0*3600.0)>=60.0 ){
         1169  +            fossil_warning("*** time skew *** server time differs by %s",
         1170  +                           db_timespan_name(rDiff));
         1171  +            g.clockSkewSeen = 1;
         1172  +          }
         1173  +        }
  1086   1174           continue;
  1087   1175         }
  1088   1176         xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
  1089   1177         nCardRcvd++;
  1090         -      if( !g.cgiOutput && !g.fQuiet ){
  1091         -        printf("\r%d", nCardRcvd);
  1092         -        fflush(stdout);
         1178  +      if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){
         1179  +        pctDone = (recv.iCursor*100)/recv.nUsed;
         1180  +        if( pctDone!=lastPctDone ){
         1181  +          printf("\rprocessed: %d%%         ", pctDone);
         1182  +          lastPctDone = pctDone;
         1183  +          fflush(stdout);
         1184  +        }
  1093   1185         }
  1094   1186   
  1095   1187         /*   file UUID SIZE \n CONTENT
  1096   1188         **   file UUID DELTASRC SIZE \n CONTENT
  1097   1189         **
  1098   1190         ** Receive a file transmitted from the server.
  1099   1191         */
  1100   1192         if( blob_eq(&xfer.aToken[0],"file") ){
  1101         -        xfer_accept_file(&xfer);
         1193  +        xfer_accept_file(&xfer, cloneFlag);
  1102   1194         }else
  1103   1195   
  1104   1196         /*   gimme UUID
  1105   1197         **
  1106   1198         ** Server is requesting a file.  If the file is a manifest, assume
  1107   1199         ** that the server will also want to know all of the content files
  1108   1200         ** associated with the manifest and send those too.
................................................................................
  1154   1246           if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){
  1155   1247             fossil_fatal("server loop");
  1156   1248           }
  1157   1249           if( zPCode==0 ){
  1158   1250             zPCode = mprintf("%b", &xfer.aToken[2]);
  1159   1251             db_set("project-code", zPCode, 0);
  1160   1252           }
  1161         -        blob_appendf(&send, "clone\n");
         1253  +        blob_appendf(&send, "clone 2 %d\n", cloneSeqno);
  1162   1254           nCardSent++;
  1163   1255         }else
  1164   1256         
  1165   1257         /*   config NAME SIZE \n CONTENT
  1166   1258         **
  1167   1259         ** Receive a configuration value from the server.
  1168   1260         */
................................................................................
  1213   1305         **
  1214   1306         ** Each cookie received overwrites the prior cookie from the
  1215   1307         ** same server.
  1216   1308         */
  1217   1309         if( blob_eq(&xfer.aToken[0], "cookie") && xfer.nToken==2 ){
  1218   1310           db_set("cookie", blob_str(&xfer.aToken[1]), 0);
  1219   1311         }else
         1312  +
         1313  +      /*    clone_seqno N
         1314  +      **
         1315  +      ** When doing a clone, the server tries to send all of its artifacts
         1316  +      ** in sequence.  This card indicates the sequence number of the next
         1317  +      ** blob that needs to be sent.  If N<=0 that indicates that all blobs
         1318  +      ** have been sent.
         1319  +      */
         1320  +      if( blob_eq(&xfer.aToken[0], "clone_seqno") && xfer.nToken==2 ){
         1321  +        blob_is_int(&xfer.aToken[1], &cloneSeqno);
         1322  +      }else
  1220   1323   
  1221   1324         /*   message MESSAGE
  1222   1325         **
  1223   1326         ** Print a message.  Similar to "error" but does not stop processing.
  1224   1327         **
  1225   1328         ** If the "login failed" message is seen, clear the sync password prior
  1226   1329         ** to the next cycle.
................................................................................
  1291   1394       ** there are still phantoms, then go another round.
  1292   1395       */
  1293   1396       nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile;
  1294   1397       if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){
  1295   1398         go = 1;
  1296   1399         mxPhantomReq = nFileRecv*2;
  1297   1400         if( mxPhantomReq<200 ) mxPhantomReq = 200;
         1401  +    }else if( cloneFlag && nFileRecv>0 ){
         1402  +      go = 1;
  1298   1403       }
  1299   1404       nCardRcvd = 0;
  1300   1405       xfer.nFileRcvd = 0;
  1301   1406       xfer.nDeltaRcvd = 0;
  1302   1407       xfer.nDanglingFile = 0;
  1303   1408   
  1304   1409       /* If we have one or more files queued to send, then go
................................................................................
  1306   1411       */
  1307   1412       if( xfer.nFileSent+xfer.nDeltaSent>0 ){
  1308   1413         go = 1;
  1309   1414       }
  1310   1415   
  1311   1416       /* If this is a clone, the go at least two rounds */
  1312   1417       if( cloneFlag && nCycle==1 ) go = 1;
         1418  +
         1419  +    /* Stop the cycle if the server sends a "clone_seqno 0" card */
         1420  +    if( cloneSeqno<=0 ) go = 0;   
  1313   1421     };
  1314   1422     transport_stats(&nSent, &nRcvd, 1);
  1315   1423     fossil_print("Total network traffic: %d bytes sent, %d bytes received\n",
  1316   1424                  nSent, nRcvd);
  1317   1425     transport_close();
  1318   1426     transport_global_shutdown();
  1319   1427     db_multi_exec("DROP TABLE onremote");
  1320   1428     manifest_crosslink_end();
         1429  +  content_enable_dephantomize(1);
  1321   1430     db_end_transaction(0);
  1322   1431   }

Changes to src/zip.c.

   100    100         c = zName[i+1];
   101    101         zName[i+1] = 0;
   102    102         for(j=0; j<nDir; j++){
   103    103           if( strcmp(zName, azDir[j])==0 ) break;
   104    104         }
   105    105         if( j>=nDir ){
   106    106           nDir++;
   107         -        azDir = realloc(azDir, sizeof(azDir[0])*nDir);
          107  +        azDir = fossil_realloc(azDir, sizeof(azDir[0])*nDir);
   108    108           azDir[j] = mprintf("%s", zName);
   109    109           zip_add_file(zName, 0);
   110    110         }
   111    111         zName[i+1] = c;
   112    112       }
   113    113     }
   114    114   }
................................................................................
   311    311   ** added to as part of the zip file. It may be 0 or an empty string,
   312    312   ** in which case it is ignored. The intention is to create a zip which
   313    313   ** politely expands into a subdir instead of filling your current dir
   314    314   ** with source files. For example, pass a UUID or "ProjectName".
   315    315   **
   316    316   */
   317    317   void zip_of_baseline(int rid, Blob *pZip, const char *zDir){
   318         -  int i;
   319         -  Blob mfile, file, hash;
   320         -  Manifest m;
          318  +  Blob mfile, hash, file;
          319  +  Manifest *pManifest;
          320  +  ManifestFile *pFile;
   321    321     Blob filename;
   322    322     int nPrefix;
   323    323     
   324    324     content_get(rid, &mfile);
   325    325     if( blob_size(&mfile)==0 ){
   326    326       blob_zero(pZip);
   327    327       return;
   328    328     }
   329         -  blob_zero(&file);
   330    329     blob_zero(&hash);
   331         -  blob_copy(&file, &mfile);
   332    330     blob_zero(&filename);
   333    331     zip_open();
   334    332   
   335    333     if( zDir && zDir[0] ){
   336    334       blob_appendf(&filename, "%s/", zDir);
   337    335     }
   338    336     nPrefix = blob_size(&filename);
   339    337   
   340         -  if( manifest_parse(&m, &mfile) ){
          338  +  pManifest = manifest_get(rid, CFTYPE_MANIFEST);
          339  +  if( pManifest ){
   341    340       char *zName;
   342         -    zip_set_timedate(m.rDate);
   343         -    blob_append(&filename, "manifest", -1);
   344         -    zName = blob_str(&filename);
   345         -    zip_add_folders(zName);
   346         -    zip_add_file(zName, &file);
   347         -    sha1sum_blob(&file, &hash);
   348         -    blob_reset(&file);
   349         -    blob_append(&hash, "\n", 1);
   350         -    blob_resize(&filename, nPrefix);
   351         -    blob_append(&filename, "manifest.uuid", -1);
   352         -    zName = blob_str(&filename);
   353         -    zip_add_file(zName, &hash);
   354         -    blob_reset(&hash);
   355         -    for(i=0; i<m.nFile; i++){
   356         -      int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
          341  +    zip_set_timedate(pManifest->rDate);
          342  +    if( db_get_boolean("manifest", 0) ){
          343  +      blob_append(&filename, "manifest", -1);
          344  +      zName = blob_str(&filename);
          345  +      zip_add_folders(zName);
          346  +      zip_add_file(zName, &mfile);
          347  +      sha1sum_blob(&mfile, &hash);
          348  +      blob_reset(&mfile);
          349  +      blob_append(&hash, "\n", 1);
          350  +      blob_resize(&filename, nPrefix);
          351  +      blob_append(&filename, "manifest.uuid", -1);
          352  +      zName = blob_str(&filename);
          353  +      zip_add_file(zName, &hash);
          354  +      blob_reset(&hash);
          355  +    }
          356  +    manifest_file_rewind(pManifest);
          357  +    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
          358  +      int fid = uuid_to_rid(pFile->zUuid, 0);
   357    359         if( fid ){
   358    360           content_get(fid, &file);
   359    361           blob_resize(&filename, nPrefix);
   360         -        blob_append(&filename, m.aFile[i].zName, -1);
          362  +        blob_append(&filename, pFile->zName, -1);
   361    363           zName = blob_str(&filename);
   362    364           zip_add_folders(zName);
   363    365           zip_add_file(zName, &file);
   364    366           blob_reset(&file);
   365    367         }
   366    368       }
   367         -    manifest_clear(&m);
   368    369     }else{
   369    370       blob_reset(&mfile);
   370         -    blob_reset(&file);
   371    371     }
          372  +  manifest_destroy(pManifest);
   372    373     blob_reset(&filename);
   373    374     zip_close(pZip);
   374    375   }
   375    376   
   376    377   /*
   377    378   ** COMMAND: zip
   378    379   **

Changes to test/delta1.test.

    30     30   # some random changes in "./t2".  Then call test-delta on the
    31     31   # two files to make sure that deltas between these two files
    32     32   # work properly.
    33     33   #
    34     34   set filelist [glob $testdir/*]
    35     35   foreach f $filelist {
    36     36     set base [file root [file tail $f]]
    37         -puts "base=$base f=$f"
           37  +protOut "base=$base f=$f"
    38     38     set f1 [read_file $f]
    39     39     write_file t1 $f1
    40     40     for {set i 0} {$i<100} {incr i} {
    41     41       write_file t2 [random_changes $f1 1 1 0 0.1]
    42     42       fossil test-delta t1 t2
    43     43       test delta-$base-$i-1 {$RESULT=="ok"}
    44     44       write_file t2 [random_changes $f1 1 1 0 0.2]

Changes to test/merge1.test.

    75     75     111 - This is line one OF the demo program - 1111
    76     76     222 - The second line program line in code - 2222
    77     77     333 - This is a test of the merging algohm - 3333
    78     78     444 - If all goes well, we will be pleased - 4444
    79     79     555 - we think it well and other stuff too - 5555
    80     80   }
    81     81   write_file_indented t23 {
    82         -  >>>>>>> BEGIN MERGE CONFLICT
           82  +  <<<<<<< BEGIN MERGE CONFLICT
    83     83     111 - This is line ONE of the demo program - 1111
    84     84     ============================
    85     85     111 - This is line one OF the demo program - 1111
    86         -  <<<<<<< END MERGE CONFLICT
           86  +  >>>>>>> END MERGE CONFLICT
    87     87     222 - The second line program line in code - 2222
    88     88     333 - This is a test of the merging algohm - 3333
    89     89     444 - If all goes well, we will be pleased - 4444
    90     90     555 - we think it well and other stuff too - 5555
    91     91   }
    92     92   write_file_indented t32 {
    93         -  >>>>>>> BEGIN MERGE CONFLICT
           93  +  <<<<<<< BEGIN MERGE CONFLICT
    94     94     111 - This is line one OF the demo program - 1111
    95     95     ============================
    96     96     111 - This is line ONE of the demo program - 1111
    97         -  <<<<<<< END MERGE CONFLICT
           97  +  >>>>>>> END MERGE CONFLICT
    98     98     222 - The second line program line in code - 2222
    99     99     333 - This is a test of the merging algohm - 3333
   100    100     444 - If all goes well, we will be pleased - 4444
   101    101     555 - we think it well and other stuff too - 5555
   102    102   }
   103    103   fossil test-3 t1 t3 t2 a32
   104    104   test merge1-2.1 {[same_file t32 a32]}
................................................................................
   156    156   write_file_indented t3 {
   157    157     222 - The second line program line in code - 2222
   158    158     333 - This is a test of the merging algohm - 3333
   159    159     444 - If all goes well, we will be pleased - 4444
   160    160     555 - we think it well and other stuff too - 5555
   161    161   }
   162    162   write_file_indented t32 {
   163         -  >>>>>>> BEGIN MERGE CONFLICT
          163  +  <<<<<<< BEGIN MERGE CONFLICT
   164    164     ============================
   165    165     000 - Zero lines added to the beginning of - 0000
   166    166     111 - This is line one of the demo program - 1111
   167         -  <<<<<<< END MERGE CONFLICT
          167  +  >>>>>>> END MERGE CONFLICT
   168    168     222 - The second line program line in code - 2222
   169    169     333 - This is a test of the merging algohm - 3333
   170    170     444 - If all goes well, we will be pleased - 4444
   171    171     555 - we think it well and other stuff too - 5555
   172    172   }
   173    173   write_file_indented t23 {
   174         -  >>>>>>> BEGIN MERGE CONFLICT
          174  +  <<<<<<< BEGIN MERGE CONFLICT
   175    175     000 - Zero lines added to the beginning of - 0000
   176    176     111 - This is line one of the demo program - 1111
   177    177     ============================
   178         -  <<<<<<< END MERGE CONFLICT
          178  +  >>>>>>> END MERGE CONFLICT
   179    179     222 - The second line program line in code - 2222
   180    180     333 - This is a test of the merging algohm - 3333
   181    181     444 - If all goes well, we will be pleased - 4444
   182    182     555 - we think it well and other stuff too - 5555
   183    183   }
   184    184   fossil test-3 t1 t3 t2 a32
   185    185   test merge1-4.1 {[same_file t32 a32]}
................................................................................
   291    291     KLMN
   292    292     OPQR
   293    293     STUV
   294    294     XYZ.
   295    295   }
   296    296   write_file_indented t23 {
   297    297     abcd
   298         -  >>>>>>> BEGIN MERGE CONFLICT
          298  +  <<<<<<< BEGIN MERGE CONFLICT
   299    299     efgh 2
   300    300     ijkl 2
   301    301     mnop 2
   302    302     qrst
   303    303     uvwx
   304    304     yzAB 2
   305    305     CDEF 2
................................................................................
   309    309     ijkl
   310    310     mnop 3
   311    311     qrst 3
   312    312     uvwx 3
   313    313     yzAB 3
   314    314     CDEF
   315    315     GHIJ
   316         -  <<<<<<< END MERGE CONFLICT
          316  +  >>>>>>> END MERGE CONFLICT
   317    317     KLMN
   318    318     OPQR
   319    319     STUV
   320    320     XYZ.
   321    321   }
   322    322   fossil test-3 t1 t2 t3 a23
   323    323   test merge1-7.1 {[same_file t23 a23]}
................................................................................
   352    352     STUV
   353    353     XYZ.
   354    354   }
   355    355   write_file_indented t23 {
   356    356     abcd
   357    357     efgh 2
   358    358     ijkl 2
   359         -  >>>>>>> BEGIN MERGE CONFLICT
          359  +  <<<<<<< BEGIN MERGE CONFLICT
   360    360     mnop
   361    361     qrst
   362    362     uvwx
   363    363     yzAB 2
   364    364     CDEF 2
   365    365     GHIJ 2
   366    366     ============================
   367    367     mnop 3
   368    368     qrst 3
   369    369     uvwx 3
   370    370     yzAB 3
   371    371     CDEF
   372    372     GHIJ
   373         -  <<<<<<< END MERGE CONFLICT
          373  +  >>>>>>> END MERGE CONFLICT
   374    374     KLMN
   375    375     OPQR
   376    376     STUV
   377    377     XYZ.
   378    378   }
   379    379   fossil test-3 t1 t2 t3 a23
   380    380   test merge1-7.2 {[same_file t23 a23]}

Changes to test/merge3.test.

    26     26   
    27     27   proc merge-test {testid basis v1 v2 result} {
    28     28     write_file t1 [join [string trim $basis] \n]\n
    29     29     write_file t2 [join [string trim $v1] \n]\n
    30     30     write_file t3 [join [string trim $v2] \n]\n
    31     31     fossil test-3-way-merge t1 t2 t3 t4
    32     32     set x [read_file t4]
    33         -  regsub -all {>>>>>>> BEGIN MERGE CONFLICT} $x {>} x
           33  +  regsub -all {<<<<<<< BEGIN MERGE CONFLICT} $x {>} x
    34     34     regsub -all {============================} $x {=} x
    35         -  regsub -all {<<<<<<< END MERGE CONFLICT} $x {<} x
           35  +  regsub -all {>>>>>>> END MERGE CONFLICT} $x {<} x
    36     36     set x [split [string trim $x] \n]
    37     37     set result [string trim $result]
    38     38     if {$x!=$result} {
    39         -    puts "  Expected \[$result\]"
    40         -    puts "       Got \[$x\]"
           39  +    protOut "  Expected \[$result\]"
           40  +    protOut "       Got \[$x\]"
    41     41       test merge3-$testid 0
    42     42     } else {
    43     43       test merge3-$testid 1
    44     44     }
    45     45   }
    46     46   
    47     47   merge-test 1 {

Changes to test/merge4.test.

    27     27   proc merge-test {testid basis v1 v2 result1 result2} {
    28     28     write_file t1 [join [string trim $basis] \n]\n
    29     29     write_file t2 [join [string trim $v1] \n]\n
    30     30     write_file t3 [join [string trim $v2] \n]\n
    31     31     fossil test-3-way-merge t1 t2 t3 t4
    32     32     fossil test-3-way-merge t1 t3 t2 t5
    33     33     set x [read_file t4]
    34         -  regsub -all {>>>>>>> BEGIN MERGE CONFLICT} $x {>} x
           34  +  regsub -all {<<<<<<< BEGIN MERGE CONFLICT} $x {>} x
    35     35     regsub -all {============================} $x {=} x
    36         -  regsub -all {<<<<<<< END MERGE CONFLICT} $x {<} x
           36  +  regsub -all {>>>>>>> END MERGE CONFLICT} $x {<} x
    37     37     set x [split [string trim $x] \n]
    38     38     set y [read_file t5]
    39         -  regsub -all {>>>>>>> BEGIN MERGE CONFLICT} $y {>} y
           39  +  regsub -all {<<<<<<< BEGIN MERGE CONFLICT} $y {>} y
    40     40     regsub -all {============================} $y {=} y
    41         -  regsub -all {<<<<<<< END MERGE CONFLICT} $y {<} y
           41  +  regsub -all {>>>>>>> END MERGE CONFLICT} $y {<} y
    42     42     set y [split [string trim $y] \n]
    43     43     set result1 [string trim $result1]
    44     44     if {$x!=$result1} {
    45         -    puts "  Expected \[$result1\]"
    46         -    puts "       Got \[$x\]"
           45  +    protOut "  Expected \[$result1\]"
           46  +    protOut "       Got \[$x\]"
    47     47       test merge3-$testid 0
    48     48     } else {
    49     49       set result2 [string trim $result2]
    50     50       if {$y!=$result2} {
    51         -      puts "  Expected \[$result2\]"
    52         -      puts "       Got \[$y\]"
           51  +      protOut "  Expected \[$result2\]"
           52  +      protOut "       Got \[$y\]"
    53     53         test merge3-$testid 0
    54     54       } else {
    55     55         test merge3-$testid 1
    56     56       }
    57     57     }
    58     58   }
    59     59   

Changes to test/tester.tcl.

    36     36   set i [lsearch $argv -halt]
    37     37   if {$i>=0} {
    38     38     set HALT 1
    39     39     set argv [lreplace $argv $i $i]
    40     40   } else {
    41     41     set HALT 0
    42     42   }
           43  +
           44  +set i [lsearch $argv -prot]
           45  +if {$i>=0} {
           46  +  set PROT 1
           47  +  set argv [lreplace $argv $i $i]
           48  +} else {
           49  +  set PROT 0
           50  +}
    43     51   
    44     52   if {[llength $argv]==0} {
    45     53     foreach f [lsort [glob $testdir/*.test]] {
    46     54       set base [file root [file tail $f]]
    47     55       lappend argv $base
    48     56     }
    49     57   }
           58  +
           59  +# start protocol
           60  +#
           61  +proc protInit {cmd} {
           62  +  if {$::PROT} {
           63  +    set out [open "prot" w]
           64  +    fconfigure $out -translation platform
           65  +    puts $out "starting tests with:$cmd"
           66  +    close $out
           67  +  }
           68  +}
           69  +
           70  +# write protocol
           71  +#
           72  +proc protOut {msg} {
           73  +  puts "$msg"
           74  +  if {$::PROT} {
           75  +    set out [open "prot" a]
           76  +    fconfigure $out -translation platform
           77  +    puts $out "$msg"
           78  +    close $out
           79  +  }
           80  +}
    50     81   
    51     82   # Run the fossil program
    52     83   #
    53     84   proc fossil {args} {
    54     85     global fossilexe
    55     86     set cmd $fossilexe
    56     87     foreach a $args {
    57     88       lappend cmd $a
    58     89     }
    59         -  puts $cmd
           90  +  protOut $cmd
           91  +
    60     92     flush stdout
    61     93     set rc [catch {eval exec $cmd} result]
    62     94     global RESULT CODE
    63     95     set CODE $rc
    64     96     set RESULT $result
    65     97   }
    66     98   
................................................................................
    98    130   
    99    131   # Perform a test
   100    132   #
   101    133   proc test {name expr} {
   102    134     global bad_test
   103    135     set r [uplevel 1 [list expr $expr]]
   104    136     if {$r} {
   105         -    puts "test $name OK"
          137  +    protOut "test $name OK"
   106    138     } else {
   107         -    puts "test $name FAILED!"
          139  +    protOut "test $name FAILED!"
   108    140       lappend bad_test $name
   109    141       if {$::HALT} exit
   110    142     }
   111    143   }
   112    144   set bad_test {}
   113    145   
   114    146   # Return a random string N characters long.
................................................................................
   165    197         }
   166    198       }
   167    199       append out \n$line
   168    200     }
   169    201     return [string range $out 1 end]
   170    202   }
   171    203   
          204  +protInit $fossilexe
   172    205   foreach testfile $argv {
   173         -  puts "***** $testfile ******"
          206  +  protOut "***** $testfile ******"
   174    207     source $testdir/$testfile.test
   175    208   }
   176         -puts "[llength $bad_test] errors: $bad_test"
          209  +protOut "[llength $bad_test] errors: $bad_test"

Added win/Makefile.PellesCGMake.

            1  +# ###########################################################################
            2  +#
            3  +# HowTo
            4  +# -----
            5  +#
            6  +# This is a Makefile to compile fossil with PellesC from
            7  +#  http://www.smorgasbordet.com/pellesc/index.htm
            8  +# In addition to the Compiler envrionment, you need
            9  +#  gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
           10  +#        couldn't handle the complex dependencies in this build
           11  +#  zlib sources
           12  +# Then you do
           13  +# 1. create a directory PellesC in the project root directory
           14  +# 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
           15  +# 3. open a dos prompt window and change working directory into PellesC (step 1)
           16  +# 4. run gmake -f ..\win\Makefile.PellesCGMake
           17  +#
           18  +# this file is tested with
           19  +#   PellesC         5.00.13
           20  +#   gmake           3.80
           21  +#   zlib sources    1.2.5
           22  +#   Windows XP SP 2
           23  +# and
           24  +#   PellesC         6.00.4
           25  +#   gmake           3.80
           26  +#   zlib sources    1.2.5
           27  +#   Windows 7 Home Premium
           28  +#  
           29  +# ###########################################################################
           30  +
           31  +#  
           32  +PellesCDir=c:\Programme\PellesC
           33  +
           34  +# Select between 32/64 bit code, default is 32 bit
           35  +#TARGETVERSION=64
           36  +
           37  +ifeq ($(TARGETVERSION),64)
           38  +# 64 bit version
           39  +TARGETMACHINE_CC=amd64
           40  +TARGETMACHINE_LN=amd64
           41  +TARGETEXTEND=64
           42  +else
           43  +# 32 bit version
           44  +TARGETMACHINE_CC=x86
           45  +TARGETMACHINE_LN=ix86
           46  +TARGETEXTEND=
           47  +endif
           48  +
           49  +# define the project directories
           50  +B=..
           51  +SRCDIR=$(B)/src/
           52  +WINDIR=$(B)/win/
           53  +ZLIBSRCDIR=../../zlib/
           54  +
           55  +# define linker command and options
           56  +LINK=$(PellesCDir)/bin/polink.exe
           57  +LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib Crtmt$(TARGETEXTEND).lib
           58  +
           59  +# define standard C-compiler and flags, used to compile
           60  +# the fossil binary. Some special definitions follow for
           61  +# special files follow
           62  +CC=$(PellesCDir)\bin\pocc.exe
           63  +DEFINES=-DFOSSIL_I18N=0 -Dstrncasecmp=memicmp -Dstrcasecmp=stricmp 
           64  +CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
           65  +INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR)
           66  +
           67  +# define commands for building the windows resource files
           68  +RESOURCE=fossil.res
           69  +RC=$(PellesCDir)\bin\porc.exe
           70  +RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
           71  +
           72  +# define the special utilities files, needed to generate
           73  +# the automatically generated source files
           74  +UTILS=translate.exe mkindex.exe makeheaders.exe
           75  +UTILS_OBJ=$(UTILS:.exe=.obj)
           76  +UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
           77  +
           78  +# define the sqlite files, which need special flags on compile
           79  +SQLITESRC=sqlite3.c
           80  +ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
           81  +SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
           82  +SQLITEDEFINES=-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
           83  +
           84  +# define the th scripting files, which need special flags on compile
           85  +THSRC=th.c th_lang.c
           86  +ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
           87  +THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
           88  +
           89  +# define the zlib files, needed by this compile
           90  +ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
           91  +ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
           92  +ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
           93  +
           94  +# define all fossil sources, using the standard compile and
           95  +# source generation. These are all files in SRCDIR, which are not
           96  +# mentioned as special files above:
           97  +ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC),$(wildcard $(SRCDIR)*.c))
           98  +SRC=$(subst $(SRCDIR),,$(ORIGSRC))
           99  +TRANSLATEDSRC=$(SRC:.c=_.c)
          100  +TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
          101  +
          102  +# main target file is the application
          103  +APPLICATION=fossil.exe
          104  +
          105  +# ###########################################################################
          106  +# define the standard make target
          107  +.PHONY:	default
          108  +default:	page_index.h headers $(APPLICATION)
          109  +
          110  +# ###########################################################################
          111  +# symbolic target to generate the source generate utils
          112  +.PHONY:	utils
          113  +utils:	$(UTILS)
          114  +
          115  +# link utils
          116  +$(UTILS) version.exe:	%.exe:	%.obj
          117  +	$(LINK) $(LINKFLAGS) -out:"$@" $<
          118  +
          119  +# compiling standard fossil utils
          120  +$(UTILS_OBJ):	%.obj:	$(SRCDIR)%.c
          121  +	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
          122  +
          123  +# compile special windows utils
          124  +version.obj:	$(WINDIR)version.c
          125  +	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
          126  +
          127  +# ###########################################################################
          128  +# generate the translated c-source files
          129  +$(TRANSLATEDSRC):	%_.c:	$(SRCDIR)%.c translate.exe
          130  +	translate.exe $< >$@
          131  +
          132  +# ###########################################################################
          133  +# generate the index source, containing all web references,..
          134  +page_index.h:	$(TRANSLATEDSRC) mkindex.exe
          135  +	mkindex.exe $(TRANSLATEDSRC) >$@
          136  +
          137  +# ###########################################################################
          138  +# extracting version info from manifest
          139  +VERSION.h:	version.exe ..\manifest.uuid ..\manifest
          140  +	version.exe ..\manifest.uuid ..\manifest  > $@
          141  +
          142  +# ###########################################################################
          143  +# generate the simplified headers
          144  +headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
          145  +	makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
          146  +	echo Done >$@
          147  +
          148  +# ###########################################################################
          149  +# compile C sources with relevant options
          150  +
          151  +$(TRANSLATEDOBJ):	%_.obj:	%_.c %.h
          152  +	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
          153  +
          154  +$(SQLITEOBJ):	%.obj:	$(SRCDIR)%.c $(SRCDIR)%.h
          155  +	$(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
          156  +
          157  +$(THOBJ):	%.obj:	$(SRCDIR)%.c $(SRCDIR)th.h
          158  +	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
          159  +
          160  +$(ZLIBOBJ):	%.obj:	$(ZLIBSRCDIR)%.c
          161  +	$(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
          162  +
          163  +# ###########################################################################
          164  +# create the windows resource with icon and version info
          165  +$(RESOURCE):	%.res:	../win/%.rc ../win/*.ico
          166  +	$(RC) $(RCFLAGS) $< -Fo"$@"
          167  +
          168  +# ###########################################################################
          169  +# link the application
          170  +$(APPLICATION):	$(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
          171  +	$(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
          172  +
          173  +# ###########################################################################
          174  +# cleanup
          175  +
          176  +.PHONY: clean
          177  +clean:
          178  +	del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
          179  +	del /F $(TRANSLATEDSRC)
          180  +	del /F *.h headers
          181  +	del /F $(RESOURCE)
          182  +
          183  +.PHONY: clobber
          184  +clobber: clean
          185  +	del /F *.exe
          186  +

Added win/Makefile.dmc.

            1  +# DO NOT EDIT
            2  +#
            3  +# This file is automatically generated.  Instead of editing this
            4  +# file, edit "makemake.tcl" then run
            5  +# "tclsh src/makemake.tcl dmc > win/Makefile.dmc"
            6  +# to regenerate this file.
            7  +B      = ..
            8  +SRCDIR = $B\src
            9  +OBJDIR = .
           10  +O      = .obj
           11  +E      = .exe
           12  +
           13  +
           14  +# Maybe DMDIR, SSL or INCL needs adjustment
           15  +DMDIR  = c:\DM
           16  +INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(DMDIR)\extra\include
           17  +
           18  +#SSL   =  -DFOSSIL_ENABLE_SSL=1
           19  +SSL    =
           20  +
           21  +DMCDEF =  -Dstrncasecmp=memicmp -Dstrcasecmp=stricmp
           22  +I18N   =  -DFOSSIL_I18N=0
           23  +
           24  +CFLAGS = -o 
           25  +BCC    = $(DMDIR)\bin\dmc $(CFLAGS)
           26  +TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(I18N) $(SSL) $(INCL)
           27  +LIBS   = $(DMDIR)\extra\lib\ zlib wsock32
           28  +
           29  +SRC   = add_.c allrepo_.c attach_.c bag_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c file_.c finfo_.c graph_.c http_.c http_socket_.c http_ssl_.c http_transport_.c info_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c stat_.c style_.c sync_.c tag_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c 
           30  +
           31  +OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\graph$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\info$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\sqlite3$O $(OBJDIR)\shell$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 
           32  +
           33  +RC=$(DMDIR)\bin\rcc
           34  +RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
           35  +
           36  +APPNAME = $(OBJDIR)\fossil$(E)
           37  +
           38  +all: $(APPNAME)
           39  +
           40  +$(APPNAME) : translate$E mkindex$E headers fossil.res $(OBJ) $(OBJDIR)\link
           41  +	cd $(OBJDIR) 
           42  +	$(DMDIR)\bin\link @link
           43  +
           44  +fossil.res:	$B\win\fossil.rc
           45  +	$(RC) $(RCFLAGS) -o$@ $**
           46  +
           47  +$(OBJDIR)\link: $B\win\Makefile.dmc
           48  +	+echo add allrepo attach bag blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event file finfo graph http http_socket http_ssl http_transport info login main manifest md5 merge merge3 name pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins stat style sync tag th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip sqlite3 shell th th_lang > $@
           49  +	+echo fossil >> $@
           50  +	+echo fossil >> $@
           51  +	+echo $(LIBS) >> $@
           52  +	+echo. >> $@
           53  +	+echo fossil >> $@
           54  +
           55  +
           56  +
           57  +translate$E: $(SRCDIR)\translate.c
           58  +	$(BCC) -o$@ $**
           59  +
           60  +makeheaders$E: $(SRCDIR)\makeheaders.c
           61  +	$(BCC) -o$@ $**
           62  +
           63  +mkindex$E: $(SRCDIR)\mkindex.c
           64  +	$(BCC) -o$@ $**
           65  +
           66  +version$E: $B\win\version.c
           67  +	$(BCC) -o$@ $**
           68  +
           69  +$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
           70  +	$(TCC) -o$@ -c -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 $**
           71  +
           72  +$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
           73  +	$(TCC) -o$@ -c -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 $**
           74  +
           75  +$(OBJDIR)\th$O : $(SRCDIR)\th.c
           76  +	$(TCC) -o$@ -c $**
           77  +
           78  +$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
           79  +	$(TCC) -o$@ -c $**
           80  +
           81  +VERSION.h : version$E $B\manifest.uuid $B\manifest
           82  +	+$** > $@
           83  +
           84  +page_index.h: mkindex$E $(SRC) 
           85  +	+$** > $@
           86  +
           87  +clean:
           88  +	-del $(OBJDIR)\*.obj
           89  +	-del *.obj *_.c *.h *.map
           90  +
           91  +realclean:
           92  +	-del $(APPNAME) translate$E mkindex$E makeheaders$E version$E
           93  +
           94  +
           95  +$(OBJDIR)\add$O : add_.c add.h
           96  +	$(TCC) -o$@ -c add_.c
           97  +
           98  +add_.c : $(SRCDIR)\add.c
           99  +	+translate$E $** > $@
          100  +
          101  +$(OBJDIR)\allrepo$O : allrepo_.c allrepo.h
          102  +	$(TCC) -o$@ -c allrepo_.c
          103  +
          104  +allrepo_.c : $(SRCDIR)\allrepo.c
          105  +	+translate$E $** > $@
          106  +
          107  +$(OBJDIR)\attach$O : attach_.c attach.h
          108  +	$(TCC) -o$@ -c attach_.c
          109  +
          110  +attach_.c : $(SRCDIR)\attach.c
          111  +	+translate$E $** > $@
          112  +
          113  +$(OBJDIR)\bag$O : bag_.c bag.h
          114  +	$(TCC) -o$@ -c bag_.c
          115  +
          116  +bag_.c : $(SRCDIR)\bag.c
          117  +	+translate$E $** > $@
          118  +
          119  +$(OBJDIR)\blob$O : blob_.c blob.h
          120  +	$(TCC) -o$@ -c blob_.c
          121  +
          122  +blob_.c : $(SRCDIR)\blob.c
          123  +	+translate$E $** > $@
          124  +
          125  +$(OBJDIR)\branch$O : branch_.c branch.h
          126  +	$(TCC) -o$@ -c branch_.c
          127  +
          128  +branch_.c : $(SRCDIR)\branch.c
          129  +	+translate$E $** > $@
          130  +
          131  +$(OBJDIR)\browse$O : browse_.c browse.h
          132  +	$(TCC) -o$@ -c browse_.c
          133  +
          134  +browse_.c : $(SRCDIR)\browse.c
          135  +	+translate$E $** > $@
          136  +
          137  +$(OBJDIR)\captcha$O : captcha_.c captcha.h
          138  +	$(TCC) -o$@ -c captcha_.c
          139  +
          140  +captcha_.c : $(SRCDIR)\captcha.c
          141  +	+translate$E $** > $@
          142  +
          143  +$(OBJDIR)\cgi$O : cgi_.c cgi.h
          144  +	$(TCC) -o$@ -c cgi_.c
          145  +
          146  +cgi_.c : $(SRCDIR)\cgi.c
          147  +	+translate$E $** > $@
          148  +
          149  +$(OBJDIR)\checkin$O : checkin_.c checkin.h
          150  +	$(TCC) -o$@ -c checkin_.c
          151  +
          152  +checkin_.c : $(SRCDIR)\checkin.c
          153  +	+translate$E $** > $@
          154  +
          155  +$(OBJDIR)\checkout$O : checkout_.c checkout.h
          156  +	$(TCC) -o$@ -c checkout_.c
          157  +
          158  +checkout_.c : $(SRCDIR)\checkout.c
          159  +	+translate$E $** > $@
          160  +
          161  +$(OBJDIR)\clearsign$O : clearsign_.c clearsign.h
          162  +	$(TCC) -o$@ -c clearsign_.c
          163  +
          164  +clearsign_.c : $(SRCDIR)\clearsign.c
          165  +	+translate$E $** > $@
          166  +
          167  +$(OBJDIR)\clone$O : clone_.c clone.h
          168  +	$(TCC) -o$@ -c clone_.c
          169  +
          170  +clone_.c : $(SRCDIR)\clone.c
          171  +	+translate$E $** > $@
          172  +
          173  +$(OBJDIR)\comformat$O : comformat_.c comformat.h
          174  +	$(TCC) -o$@ -c comformat_.c
          175  +
          176  +comformat_.c : $(SRCDIR)\comformat.c
          177  +	+translate$E $** > $@
          178  +
          179  +$(OBJDIR)\configure$O : configure_.c configure.h
          180  +	$(TCC) -o$@ -c configure_.c
          181  +
          182  +configure_.c : $(SRCDIR)\configure.c
          183  +	+translate$E $** > $@
          184  +
          185  +$(OBJDIR)\content$O : content_.c content.h
          186  +	$(TCC) -o$@ -c content_.c
          187  +
          188  +content_.c : $(SRCDIR)\content.c
          189  +	+translate$E $** > $@
          190  +
          191  +$(OBJDIR)\db$O : db_.c db.h
          192  +	$(TCC) -o$@ -c db_.c
          193  +
          194  +db_.c : $(SRCDIR)\db.c
          195  +	+translate$E $** > $@
          196  +
          197  +$(OBJDIR)\delta$O : delta_.c delta.h
          198  +	$(TCC) -o$@ -c delta_.c
          199  +
          200  +delta_.c : $(SRCDIR)\delta.c
          201  +	+translate$E $** > $@
          202  +
          203  +$(OBJDIR)\deltacmd$O : deltacmd_.c deltacmd.h
          204  +	$(TCC) -o$@ -c deltacmd_.c
          205  +
          206  +deltacmd_.c : $(SRCDIR)\deltacmd.c
          207  +	+translate$E $** > $@
          208  +
          209  +$(OBJDIR)\descendants$O : descendants_.c descendants.h
          210  +	$(TCC) -o$@ -c descendants_.c
          211  +
          212  +descendants_.c : $(SRCDIR)\descendants.c
          213  +	+translate$E $** > $@
          214  +
          215  +$(OBJDIR)\diff$O : diff_.c diff.h
          216  +	$(TCC) -o$@ -c diff_.c
          217  +
          218  +diff_.c : $(SRCDIR)\diff.c
          219  +	+translate$E $** > $@
          220  +
          221  +$(OBJDIR)\diffcmd$O : diffcmd_.c diffcmd.h
          222  +	$(TCC) -o$@ -c diffcmd_.c
          223  +
          224  +diffcmd_.c : $(SRCDIR)\diffcmd.c
          225  +	+translate$E $** > $@
          226  +
          227  +$(OBJDIR)\doc$O : doc_.c doc.h
          228  +	$(TCC) -o$@ -c doc_.c
          229  +
          230  +doc_.c : $(SRCDIR)\doc.c
          231  +	+translate$E $** > $@
          232  +
          233  +$(OBJDIR)\event$O : event_.c event.h
          234  +	$(TCC) -o$@ -c event_.c
          235  +
          236  +event_.c : $(SRCDIR)\event.c
          237  +	+translate$E $** > $@
          238  +
          239  +$(OBJDIR)\encode$O : encode_.c encode.h
          240  +	$(TCC) -o$@ -c encode_.c
          241  +
          242  +encode_.c : $(SRCDIR)\encode.c
          243  +	+translate$E $** > $@
          244  +
          245  +$(OBJDIR)\event$O : event_.c event.h
          246  +	$(TCC) -o$@ -c event_.c
          247  +
          248  +event_.c : $(SRCDIR)\event.c
          249  +	+translate$E $** > $@
          250  +
          251  +$(OBJDIR)\file$O : file_.c file.h
          252  +	$(TCC) -o$@ -c file_.c
          253  +
          254  +file_.c : $(SRCDIR)\file.c
          255  +	+translate$E $** > $@
          256  +
          257  +$(OBJDIR)\finfo$O : finfo_.c finfo.h
          258  +	$(TCC) -o$@ -c finfo_.c
          259  +
          260  +finfo_.c : $(SRCDIR)\finfo.c
          261  +	+translate$E $** > $@
          262  +
          263  +$(OBJDIR)\graph$O : graph_.c graph.h
          264  +	$(TCC) -o$@ -c graph_.c
          265  +
          266  +graph_.c : $(SRCDIR)\graph.c
          267  +	+translate$E $** > $@
          268  +
          269  +$(OBJDIR)\http$O : http_.c http.h
          270  +	$(TCC) -o$@ -c http_.c
          271  +
          272  +http_.c : $(SRCDIR)\http.c
          273  +	+translate$E $** > $@
          274  +
          275  +$(OBJDIR)\http_socket$O : http_socket_.c http_socket.h
          276  +	$(TCC) -o$@ -c http_socket_.c
          277  +
          278  +http_socket_.c : $(SRCDIR)\http_socket.c
          279  +	+translate$E $** > $@
          280  +
          281  +$(OBJDIR)\http_ssl$O : http_ssl_.c http_ssl.h
          282  +	$(TCC) -o$@ -c http_ssl_.c
          283  +
          284  +http_ssl_.c : $(SRCDIR)\http_ssl.c
          285  +	+translate$E $** > $@
          286  +
          287  +$(OBJDIR)\http_transport$O : http_transport_.c http_transport.h
          288  +	$(TCC) -o$@ -c http_transport_.c
          289  +
          290  +http_transport_.c : $(SRCDIR)\http_transport.c
          291  +	+translate$E $** > $@
          292  +
          293  +$(OBJDIR)\info$O : info_.c info.h
          294  +	$(TCC) -o$@ -c info_.c
          295  +
          296  +info_.c : $(SRCDIR)\info.c
          297  +	+translate$E $** > $@
          298  +
          299  +$(OBJDIR)\login$O : login_.c login.h
          300  +	$(TCC) -o$@ -c login_.c
          301  +
          302  +login_.c : $(SRCDIR)\login.c
          303  +	+translate$E $** > $@
          304  +
          305  +$(OBJDIR)\main$O : main_.c main.h
          306  +	$(TCC) -o$@ -c main_.c
          307  +
          308  +main_.c : $(SRCDIR)\main.c
          309  +	+translate$E $** > $@
          310  +
          311  +$(OBJDIR)\manifest$O : manifest_.c manifest.h
          312  +	$(TCC) -o$@ -c manifest_.c
          313  +
          314  +manifest_.c : $(SRCDIR)\manifest.c
          315  +	+translate$E $** > $@
          316  +
          317  +$(OBJDIR)\md5$O : md5_.c md5.h
          318  +	$(TCC) -o$@ -c md5_.c
          319  +
          320  +md5_.c : $(SRCDIR)\md5.c
          321  +	+translate$E $** > $@
          322  +
          323  +$(OBJDIR)\merge$O : merge_.c merge.h
          324  +	$(TCC) -o$@ -c merge_.c
          325  +
          326  +merge_.c : $(SRCDIR)\merge.c
          327  +	+translate$E $** > $@
          328  +
          329  +$(OBJDIR)\merge3$O : merge3_.c merge3.h
          330  +	$(TCC) -o$@ -c merge3_.c
          331  +
          332  +merge3_.c : $(SRCDIR)\merge3.c
          333  +	+translate$E $** > $@
          334  +
          335  +$(OBJDIR)\name$O : name_.c name.h
          336  +	$(TCC) -o$@ -c name_.c
          337  +
          338  +name_.c : $(SRCDIR)\name.c
          339  +	+translate$E $** > $@
          340  +
          341  +$(OBJDIR)\pivot$O : pivot_.c pivot.h
          342  +	$(TCC) -o$@ -c pivot_.c
          343  +
          344  +pivot_.c : $(SRCDIR)\pivot.c
          345  +	+translate$E $** > $@
          346  +
          347  +$(OBJDIR)\popen$O : popen_.c popen.h
          348  +	$(TCC) -o$@ -c popen_.c
          349  +
          350  +popen_.c : $(SRCDIR)\popen.c
          351  +	+translate$E $** > $@
          352  +
          353  +$(OBJDIR)\pqueue$O : pqueue_.c pqueue.h
          354  +	$(TCC) -o$@ -c pqueue_.c
          355  +
          356  +pqueue_.c : $(SRCDIR)\pqueue.c
          357  +	+translate$E $** > $@
          358  +
          359  +$(OBJDIR)\printf$O : printf_.c printf.h
          360  +	$(TCC) -o$@ -c printf_.c
          361  +
          362  +printf_.c : $(SRCDIR)\printf.c
          363  +	+translate$E $** > $@
          364  +
          365  +$(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
          366  +	$(TCC) -o$@ -c rebuild_.c
          367  +
          368  +rebuild_.c : $(SRCDIR)\rebuild.c
          369  +	+translate$E $** > $@
          370  +
          371  +$(OBJDIR)\report$O : report_.c report.h
          372  +	$(TCC) -o$@ -c report_.c
          373  +
          374  +report_.c : $(SRCDIR)\report.c
          375  +	+translate$E $** > $@
          376  +
          377  +$(OBJDIR)\rss$O : rss_.c rss.h
          378  +	$(TCC) -o$@ -c rss_.c
          379  +
          380  +rss_.c : $(SRCDIR)\rss.c
          381  +	+translate$E $** > $@
          382  +
          383  +$(OBJDIR)\schema$O : schema_.c schema.h
          384  +	$(TCC) -o$@ -c schema_.c
          385  +
          386  +schema_.c : $(SRCDIR)\schema.c
          387  +	+translate$E $** > $@
          388  +
          389  +$(OBJDIR)\search$O : search_.c search.h
          390  +	$(TCC) -o$@ -c search_.c
          391  +
          392  +search_.c : $(SRCDIR)\search.c
          393  +	+translate$E $** > $@
          394  +
          395  +$(OBJDIR)\setup$O : setup_.c setup.h
          396  +	$(TCC) -o$@ -c setup_.c
          397  +
          398  +setup_.c : $(SRCDIR)\setup.c
          399  +	+translate$E $** > $@
          400  +
          401  +$(OBJDIR)\sha1$O : sha1_.c sha1.h
          402  +	$(TCC) -o$@ -c sha1_.c
          403  +
          404  +sha1_.c : $(SRCDIR)\sha1.c
          405  +	+translate$E $** > $@
          406  +
          407  +$(OBJDIR)\shun$O : shun_.c shun.h
          408  +	$(TCC) -o$@ -c shun_.c
          409  +
          410  +shun_.c : $(SRCDIR)\shun.c
          411  +	+translate$E $** > $@
          412  +
          413  +$(OBJDIR)\skins$O : skins_.c skins.h
          414  +	$(TCC) -o$@ -c skins_.c
          415  +
          416  +skins_.c : $(SRCDIR)\skins.c
          417  +	+translate$E $** > $@
          418  +
          419  +$(OBJDIR)\stat$O : stat_.c stat.h
          420  +	$(TCC) -o$@ -c stat_.c
          421  +
          422  +stat_.c : $(SRCDIR)\stat.c
          423  +	+translate$E $** > $@
          424  +
          425  +$(OBJDIR)\style$O : style_.c style.h
          426  +	$(TCC) -o$@ -c style_.c
          427  +
          428  +style_.c : $(SRCDIR)\style.c
          429  +	+translate$E $** > $@
          430  +
          431  +$(OBJDIR)\sync$O : sync_.c sync.h
          432  +	$(TCC) -o$@ -c sync_.c
          433  +
          434  +sync_.c : $(SRCDIR)\sync.c
          435  +	+translate$E $** > $@
          436  +
          437  +$(OBJDIR)\tag$O : tag_.c tag.h
          438  +	$(TCC) -o$@ -c tag_.c
          439  +
          440  +tag_.c : $(SRCDIR)\tag.c
          441  +	+translate$E $** > $@
          442  +
          443  +$(OBJDIR)\th_main$O : th_main_.c th_main.h
          444  +	$(TCC) -o$@ -c th_main_.c
          445  +
          446  +th_main_.c : $(SRCDIR)\th_main.c
          447  +	+translate$E $** > $@
          448  +
          449  +$(OBJDIR)\timeline$O : timeline_.c timeline.h
          450  +	$(TCC) -o$@ -c timeline_.c
          451  +
          452  +timeline_.c : $(SRCDIR)\timeline.c
          453  +	+translate$E $** > $@
          454  +
          455  +$(OBJDIR)\tkt$O : tkt_.c tkt.h
          456  +	$(TCC) -o$@ -c tkt_.c
          457  +
          458  +tkt_.c : $(SRCDIR)\tkt.c
          459  +	+translate$E $** > $@
          460  +
          461  +$(OBJDIR)\tktsetup$O : tktsetup_.c tktsetup.h
          462  +	$(TCC) -o$@ -c tktsetup_.c
          463  +
          464  +tktsetup_.c : $(SRCDIR)\tktsetup.c
          465  +	+translate$E $** > $@
          466  +
          467  +$(OBJDIR)\undo$O : undo_.c undo.h
          468  +	$(TCC) -o$@ -c undo_.c
          469  +
          470  +undo_.c : $(SRCDIR)\undo.c
          471  +	+translate$E $** > $@
          472  +
          473  +$(OBJDIR)\update$O : update_.c update.h
          474  +	$(TCC) -o$@ -c update_.c
          475  +
          476  +update_.c : $(SRCDIR)\update.c
          477  +	+translate$E $** > $@
          478  +
          479  +$(OBJDIR)\url$O : url_.c url.h
          480  +	$(TCC) -o$@ -c url_.c
          481  +
          482  +url_.c : $(SRCDIR)\url.c
          483  +	+translate$E $** > $@
          484  +
          485  +$(OBJDIR)\user$O : user_.c user.h
          486  +	$(TCC) -o$@ -c user_.c
          487  +
          488  +user_.c : $(SRCDIR)\user.c
          489  +	+translate$E $** > $@
          490  +
          491  +$(OBJDIR)\verify$O : verify_.c verify.h
          492  +	$(TCC) -o$@ -c verify_.c
          493  +
          494  +verify_.c : $(SRCDIR)\verify.c
          495  +	+translate$E $** > $@
          496  +
          497  +$(OBJDIR)\vfile$O : vfile_.c vfile.h
          498  +	$(TCC) -o$@ -c vfile_.c
          499  +
          500  +vfile_.c : $(SRCDIR)\vfile.c
          501  +	+translate$E $** > $@
          502  +
          503  +$(OBJDIR)\wiki$O : wiki_.c wiki.h
          504  +	$(TCC) -o$@ -c wiki_.c
          505  +
          506  +wiki_.c : $(SRCDIR)\wiki.c
          507  +	+translate$E $** > $@
          508  +
          509  +$(OBJDIR)\wikiformat$O : wikiformat_.c wikiformat.h
          510  +	$(TCC) -o$@ -c wikiformat_.c
          511  +
          512  +wikiformat_.c : $(SRCDIR)\wikiformat.c
          513  +	+translate$E $** > $@
          514  +
          515  +$(OBJDIR)\winhttp$O : winhttp_.c winhttp.h
          516  +	$(TCC) -o$@ -c winhttp_.c
          517  +
          518  +winhttp_.c : $(SRCDIR)\winhttp.c
          519  +	+translate$E $** > $@
          520  +
          521  +$(OBJDIR)\xfer$O : xfer_.c xfer.h
          522  +	$(TCC) -o$@ -c xfer_.c
          523  +
          524  +xfer_.c : $(SRCDIR)\xfer.c
          525  +	+translate$E $** > $@
          526  +
          527  +$(OBJDIR)\zip$O : zip_.c zip.h
          528  +	$(TCC) -o$@ -c zip_.c
          529  +
          530  +zip_.c : $(SRCDIR)\zip.c
          531  +	+translate$E $** > $@
          532  +
          533  +headers: makeheaders$E page_index.h VERSION.h
          534  +	+makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h
          535  +	@copy /Y nul: headers

Added win/Makefile.msc.

            1  +# DO NOT EDIT
            2  +#
            3  +# This file is automatically generated.  Instead of editing this
            4  +# file, edit "makemake.tcl" then run
            5  +# "tclsh src/makemake.tcl msc > win/Makefile.msc"
            6  +# to regenerate this file.
            7  +B      = ..
            8  +SRCDIR = $B\src
            9  +OBJDIR = .
           10  +O      = .obj
           11  +E      = .exe
           12  +
           13  +# Maybe MSCDIR, SSL, ZLIB, or INCL needs adjustment
           14  +MSCDIR = c:\msc
           15  +
           16  +# Uncomment below for SSL support
           17  +SSL =
           18  +SSLLIB =
           19  +#SSL = -DFOSSIL_ENABLE_SSL=1
           20  +#SSLLIB  = ssleay32.lib libeay32.lib user32.lib gdi32.lib advapi32.lib
           21  +
           22  +# zlib options
           23  +# When using precompiled from http://zlib.net/zlib125-dll.zip
           24  +#ZINCDIR = C:\zlib125-dll\include
           25  +#ZLIBDIR = C:\zlib125-dll\lib
           26  +#ZLIB    = zdll.lib
           27  +ZINCDIR = $(MSCDIR)\extra\include
           28  +ZLIBDIR = $(MSCDIR)\extra\lib
           29  +ZLIB    = zlib.lib
           30  +
           31  +INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)
           32  +
           33  +MSCDEF =  -Dstrncasecmp=memicmp -Dstrcasecmp=stricmp
           34  +I18N   =  -DFOSSIL_I18N=0
           35  +
           36  +CFLAGS = -nologo -MT -O2
           37  +BCC    = $(CC) $(CFLAGS)
           38  +TCC    = $(CC) -c $(CFLAGS) $(MSCDEF) $(I18N) $(SSL) $(INCL)
           39  +LIBS   = $(ZLIB) ws2_32.lib $(SSLLIB)
           40  +LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
           41  +
           42  +SRC   = add_.c allrepo_.c attach_.c bag_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c file_.c finfo_.c graph_.c http_.c http_socket_.c http_ssl_.c http_transport_.c info_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c stat_.c style_.c sync_.c tag_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c 
           43  +
           44  +OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\graph$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\info$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 
           45  +
           46  +
           47  +APPNAME = $(OBJDIR)\fossil$(E)
           48  +
           49  +all: $(OBJDIR) $(APPNAME)
           50  +
           51  +$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\linkopts
           52  +	cd $(OBJDIR) 
           53  +	link -LINK -OUT:$@ $(LIBDIR) @linkopts
           54  +
           55  +$(OBJDIR)\linkopts: $B\win\Makefile.msc
           56  +	echo add allrepo attach bag blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode file finfo graph http http_socket http_ssl http_transport info login main manifest md5 merge merge3 name pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins stat style sync tag th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip sqlite3 th th_lang > $@
           57  +	echo $(LIBS) >> $@
           58  +
           59  +
           60  +
           61  +
           62  +$(OBJDIR):
           63  +	@-mkdir $@
           64  +
           65  +translate$E: $(SRCDIR)\translate.c
           66  +	$(BCC) $**
           67  +
           68  +makeheaders$E: $(SRCDIR)\makeheaders.c
           69  +	$(BCC) $**
           70  +
           71  +mkindex$E: $(SRCDIR)\mkindex.c
           72  +	$(BCC) $**
           73  +
           74  +version$E: $B\win\version.c
           75  +	$(BCC) $**
           76  +
           77  +$(OBJDIR)\sqlite3$O : $(SRCDIR)\sqlite3.c
           78  +	$(TCC) /Fo$@ -c -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 $**
           79  +
           80  +$(OBJDIR)\th$O : $(SRCDIR)\th.c
           81  +	$(TCC) /Fo$@ -c $**
           82  +
           83  +$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
           84  +	$(TCC) /Fo$@ -c $**
           85  +
           86  +VERSION.h : version$E $B\manifest.uuid $B\manifest
           87  +	$** > $@
           88  +
           89  +page_index.h: mkindex$E $(SRC) 
           90  +	$** > $@
           91  +
           92  +clean:
           93  +	-del $(OBJDIR)\*.obj
           94  +	-del *.obj *_.c *.h *.map
           95  +	-del headers linkopts
           96  +
           97  +realclean:
           98  +	-del $(APPNAME) translate$E mkindex$E makeheaders$E version$E
           99  +
          100  +
          101  +$(OBJDIR)\add$O : add_.c add.h
          102  +	$(TCC) /Fo$@ -c add_.c
          103  +
          104  +add_.c : $(SRCDIR)\add.c
          105  +	translate$E $** > $@
          106  +
          107  +$(OBJDIR)\allrepo$O : allrepo_.c allrepo.h
          108  +	$(TCC) /Fo$@ -c allrepo_.c
          109  +
          110  +allrepo_.c : $(SRCDIR)\allrepo.c
          111  +	translate$E $** > $@
          112  +
          113  +$(OBJDIR)\attach$O : attach_.c attach.h
          114  +	$(TCC) /Fo$@ -c attach_.c
          115  +
          116  +attach_.c : $(SRCDIR)\attach.c
          117  +	translate$E $** > $@
          118  +
          119  +$(OBJDIR)\bag$O : bag_.c bag.h
          120  +	$(TCC) /Fo$@ -c bag_.c
          121  +
          122  +bag_.c : $(SRCDIR)\bag.c
          123  +	translate$E $** > $@
          124  +
          125  +$(OBJDIR)\blob$O : blob_.c blob.h
          126  +	$(TCC) /Fo$@ -c blob_.c
          127  +
          128  +blob_.c : $(SRCDIR)\blob.c
          129  +	translate$E $** > $@
          130  +
          131  +$(OBJDIR)\branch$O : branch_.c branch.h
          132  +	$(TCC) /Fo$@ -c branch_.c
          133  +
          134  +branch_.c : $(SRCDIR)\branch.c
          135  +	translate$E $** > $@
          136  +
          137  +$(OBJDIR)\browse$O : browse_.c browse.h
          138  +	$(TCC) /Fo$@ -c browse_.c
          139  +
          140  +browse_.c : $(SRCDIR)\browse.c
          141  +	translate$E $** > $@
          142  +
          143  +$(OBJDIR)\captcha$O : captcha_.c captcha.h
          144  +	$(TCC) /Fo$@ -c captcha_.c
          145  +
          146  +captcha_.c : $(SRCDIR)\captcha.c
          147  +	translate$E $** > $@
          148  +
          149  +$(OBJDIR)\cgi$O : cgi_.c cgi.h
          150  +	$(TCC) /Fo$@ -c cgi_.c
          151  +
          152  +cgi_.c : $(SRCDIR)\cgi.c
          153  +	translate$E $** > $@
          154  +
          155  +$(OBJDIR)\checkin$O : checkin_.c checkin.h
          156  +	$(TCC) /Fo$@ -c checkin_.c
          157  +
          158  +checkin_.c : $(SRCDIR)\checkin.c
          159  +	translate$E $** > $@
          160  +
          161  +$(OBJDIR)\checkout$O : checkout_.c checkout.h
          162  +	$(TCC) /Fo$@ -c checkout_.c
          163  +
          164  +checkout_.c : $(SRCDIR)\checkout.c
          165  +	translate$E $** > $@
          166  +
          167  +$(OBJDIR)\clearsign$O : clearsign_.c clearsign.h
          168  +	$(TCC) /Fo$@ -c clearsign_.c
          169  +
          170  +clearsign_.c : $(SRCDIR)\clearsign.c
          171  +	translate$E $** > $@
          172  +
          173  +$(OBJDIR)\clone$O : clone_.c clone.h
          174  +	$(TCC) /Fo$@ -c clone_.c
          175  +
          176  +clone_.c : $(SRCDIR)\clone.c
          177  +	translate$E $** > $@
          178  +
          179  +$(OBJDIR)\comformat$O : comformat_.c comformat.h
          180  +	$(TCC) /Fo$@ -c comformat_.c
          181  +
          182  +comformat_.c : $(SRCDIR)\comformat.c
          183  +	translate$E $** > $@
          184  +
          185  +$(OBJDIR)\configure$O : configure_.c configure.h
          186  +	$(TCC) /Fo$@ -c configure_.c
          187  +
          188  +configure_.c : $(SRCDIR)\configure.c
          189  +	translate$E $** > $@
          190  +
          191  +$(OBJDIR)\content$O : content_.c content.h
          192  +	$(TCC) /Fo$@ -c content_.c
          193  +
          194  +content_.c : $(SRCDIR)\content.c
          195  +	translate$E $** > $@
          196  +
          197  +$(OBJDIR)\db$O : db_.c db.h
          198  +	$(TCC) /Fo$@ -c db_.c
          199  +
          200  +db_.c : $(SRCDIR)\db.c
          201  +	translate$E $** > $@
          202  +
          203  +$(OBJDIR)\delta$O : delta_.c delta.h
          204  +	$(TCC) /Fo$@ -c delta_.c
          205  +
          206  +delta_.c : $(SRCDIR)\delta.c
          207  +	translate$E $** > $@
          208  +
          209  +$(OBJDIR)\deltacmd$O : deltacmd_.c deltacmd.h
          210  +	$(TCC) /Fo$@ -c deltacmd_.c
          211  +
          212  +deltacmd_.c : $(SRCDIR)\deltacmd.c
          213  +	translate$E $** > $@
          214  +
          215  +$(OBJDIR)\descendants$O : descendants_.c descendants.h
          216  +	$(TCC) /Fo$@ -c descendants_.c
          217  +
          218  +descendants_.c : $(SRCDIR)\descendants.c
          219  +	translate$E $** > $@
          220  +
          221  +$(OBJDIR)\diff$O : diff_.c diff.h
          222  +	$(TCC) /Fo$@ -c diff_.c
          223  +
          224  +diff_.c : $(SRCDIR)\diff.c
          225  +	translate$E $** > $@
          226  +
          227  +$(OBJDIR)\diffcmd$O : diffcmd_.c diffcmd.h
          228  +	$(TCC) /Fo$@ -c diffcmd_.c
          229  +
          230  +diffcmd_.c : $(SRCDIR)\diffcmd.c
          231  +	translate$E $** > $@
          232  +
          233  +$(OBJDIR)\doc$O : doc_.c doc.h
          234  +	$(TCC) /Fo$@ -c doc_.c
          235  +
          236  +doc_.c : $(SRCDIR)\doc.c
          237  +	translate$E $** > $@
          238  +
          239  +$(OBJDIR)\encode$O : encode_.c encode.h
          240  +	$(TCC) /Fo$@ -c encode_.c
          241  +
          242  +encode_.c : $(SRCDIR)\encode.c
          243  +	translate$E $** > $@
          244  +
          245  +$(OBJDIR)\file$O : file_.c file.h
          246  +	$(TCC) /Fo$@ -c file_.c
          247  +
          248  +file_.c : $(SRCDIR)\file.c
          249  +	translate$E $** > $@
          250  +
          251  +$(OBJDIR)\finfo$O : finfo_.c finfo.h
          252  +	$(TCC) /Fo$@ -c finfo_.c
          253  +
          254  +finfo_.c : $(SRCDIR)\finfo.c
          255  +	translate$E $** > $@
          256  +
          257  +$(OBJDIR)\graph$O : graph_.c graph.h
          258  +	$(TCC) /Fo$@ -c graph_.c
          259  +
          260  +graph_.c : $(SRCDIR)\graph.c
          261  +	translate$E $** > $@
          262  +
          263  +$(OBJDIR)\http$O : http_.c http.h
          264  +	$(TCC) /Fo$@ -c http_.c
          265  +
          266  +http_.c : $(SRCDIR)\http.c
          267  +	translate$E $** > $@
          268  +
          269  +$(OBJDIR)\http_socket$O : http_socket_.c http_socket.h
          270  +	$(TCC) /Fo$@ -c http_socket_.c
          271  +
          272  +http_socket_.c : $(SRCDIR)\http_socket.c
          273  +	translate$E $** > $@
          274  +
          275  +$(OBJDIR)\http_ssl$O : http_ssl_.c http_ssl.h
          276  +	$(TCC) /Fo$@ -c http_ssl_.c
          277  +
          278  +http_ssl_.c : $(SRCDIR)\http_ssl.c
          279  +	translate$E $** > $@
          280  +
          281  +$(OBJDIR)\http_transport$O : http_transport_.c http_transport.h
          282  +	$(TCC) /Fo$@ -c http_transport_.c
          283  +
          284  +http_transport_.c : $(SRCDIR)\http_transport.c
          285  +	translate$E $** > $@
          286  +
          287  +$(OBJDIR)\info$O : info_.c info.h
          288  +	$(TCC) /Fo$@ -c info_.c
          289  +
          290  +info_.c : $(SRCDIR)\info.c
          291  +	translate$E $** > $@
          292  +
          293  +$(OBJDIR)\login$O : login_.c login.h
          294  +	$(TCC) /Fo$@ -c login_.c
          295  +
          296  +login_.c : $(SRCDIR)\login.c
          297  +	translate$E $** > $@
          298  +
          299  +$(OBJDIR)\main$O : main_.c main.h
          300  +	$(TCC) /Fo$@ -c main_.c
          301  +
          302  +main_.c : $(SRCDIR)\main.c
          303  +	translate$E $** > $@
          304  +
          305  +$(OBJDIR)\manifest$O : manifest_.c manifest.h
          306  +	$(TCC) /Fo$@ -c manifest_.c
          307  +
          308  +manifest_.c : $(SRCDIR)\manifest.c
          309  +	translate$E $** > $@
          310  +
          311  +$(OBJDIR)\md5$O : md5_.c md5.h
          312  +	$(TCC) /Fo$@ -c md5_.c
          313  +
          314  +md5_.c : $(SRCDIR)\md5.c
          315  +	translate$E $** > $@
          316  +
          317  +$(OBJDIR)\merge$O : merge_.c merge.h
          318  +	$(TCC) /Fo$@ -c merge_.c
          319  +
          320  +merge_.c : $(SRCDIR)\merge.c
          321  +	translate$E $** > $@
          322  +
          323  +$(OBJDIR)\merge3$O : merge3_.c merge3.h
          324  +	$(TCC) /Fo$@ -c merge3_.c
          325  +
          326  +merge3_.c : $(SRCDIR)\merge3.c
          327  +	translate$E $** > $@
          328  +
          329  +$(OBJDIR)\name$O : name_.c name.h
          330  +	$(TCC) /Fo$@ -c name_.c
          331  +
          332  +name_.c : $(SRCDIR)\name.c
          333  +	translate$E $** > $@
          334  +
          335  +$(OBJDIR)\pivot$O : pivot_.c pivot.h
          336  +	$(TCC) /Fo$@ -c pivot_.c
          337  +
          338  +pivot_.c : $(SRCDIR)\pivot.c
          339  +	translate$E $** > $@
          340  +
          341  +$(OBJDIR)\popen$O : popen_.c popen.h
          342  +	$(TCC) /Fo$@ -c popen_.c
          343  +
          344  +popen_.c : $(SRCDIR)\popen.c
          345  +	translate$E $** > $@
          346  +
          347  +$(OBJDIR)\pqueue$O : pqueue_.c pqueue.h
          348  +	$(TCC) /Fo$@ -c pqueue_.c
          349  +
          350  +pqueue_.c : $(SRCDIR)\pqueue.c
          351  +	translate$E $** > $@
          352  +
          353  +$(OBJDIR)\printf$O : printf_.c printf.h
          354  +	$(TCC) /Fo$@ -c printf_.c
          355  +
          356  +printf_.c : $(SRCDIR)\printf.c
          357  +	translate$E $** > $@
          358  +
          359  +$(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
          360  +	$(TCC) /Fo$@ -c rebuild_.c
          361  +
          362  +rebuild_.c : $(SRCDIR)\rebuild.c
          363  +	translate$E $** > $@
          364  +
          365  +$(OBJDIR)\report$O : report_.c report.h
          366  +	$(TCC) /Fo$@ -c report_.c
          367  +
          368  +report_.c : $(SRCDIR)\report.c
          369  +	translate$E $** > $@
          370  +
          371  +$(OBJDIR)\rss$O : rss_.c rss.h
          372  +	$(TCC) /Fo$@ -c rss_.c
          373  +
          374  +rss_.c : $(SRCDIR)\rss.c
          375  +	translate$E $** > $@
          376  +
          377  +$(OBJDIR)\schema$O : schema_.c schema.h
          378  +	$(TCC) /Fo$@ -c schema_.c
          379  +
          380  +schema_.c : $(SRCDIR)\schema.c
          381  +	translate$E $** > $@
          382  +
          383  +$(OBJDIR)\search$O : search_.c search.h
          384  +	$(TCC) /Fo$@ -c search_.c
          385  +
          386  +search_.c : $(SRCDIR)\search.c
          387  +	translate$E $** > $@
          388  +
          389  +$(OBJDIR)\setup$O : setup_.c setup.h
          390  +	$(TCC) /Fo$@ -c setup_.c
          391  +
          392  +setup_.c : $(SRCDIR)\setup.c
          393  +	translate$E $** > $@
          394  +
          395  +$(OBJDIR)\sha1$O : sha1_.c sha1.h
          396  +	$(TCC) /Fo$@ -c sha1_.c
          397  +
          398  +sha1_.c : $(SRCDIR)\sha1.c
          399  +	translate$E $** > $@
          400  +
          401  +$(OBJDIR)\shun$O : shun_.c shun.h
          402  +	$(TCC) /Fo$@ -c shun_.c
          403  +
          404  +shun_.c : $(SRCDIR)\shun.c
          405  +	translate$E $** > $@
          406  +
          407  +$(OBJDIR)\skins$O : skins_.c skins.h
          408  +	$(TCC) /Fo$@ -c skins_.c
          409  +
          410  +skins_.c : $(SRCDIR)\skins.c
          411  +	translate$E $** > $@
          412  +
          413  +$(OBJDIR)\stat$O : stat_.c stat.h
          414  +	$(TCC) /Fo$@ -c stat_.c
          415  +
          416  +stat_.c : $(SRCDIR)\stat.c
          417  +	translate$E $** > $@
          418  +
          419  +$(OBJDIR)\style$O : style_.c style.h
          420  +	$(TCC) /Fo$@ -c style_.c
          421  +
          422  +style_.c : $(SRCDIR)\style.c
          423  +	translate$E $** > $@
          424  +
          425  +$(OBJDIR)\sync$O : sync_.c sync.h
          426  +	$(TCC) /Fo$@ -c sync_.c
          427  +
          428  +sync_.c : $(SRCDIR)\sync.c
          429  +	translate$E $** > $@
          430  +
          431  +$(OBJDIR)\tag$O : tag_.c tag.h
          432  +	$(TCC) /Fo$@ -c tag_.c
          433  +
          434  +tag_.c : $(SRCDIR)\tag.c
          435  +	translate$E $** > $@
          436  +
          437  +$(OBJDIR)\th_main$O : th_main_.c th_main.h
          438  +	$(TCC) /Fo$@ -c th_main_.c
          439  +
          440  +th_main_.c : $(SRCDIR)\th_main.c
          441  +	translate$E $** > $@
          442  +
          443  +$(OBJDIR)\timeline$O : timeline_.c timeline.h
          444  +	$(TCC) /Fo$@ -c timeline_.c
          445  +
          446  +timeline_.c : $(SRCDIR)\timeline.c
          447  +	translate$E $** > $@
          448  +
          449  +$(OBJDIR)\tkt$O : tkt_.c tkt.h
          450  +	$(TCC) /Fo$@ -c tkt_.c
          451  +
          452  +tkt_.c : $(SRCDIR)\tkt.c
          453  +	translate$E $** > $@
          454  +
          455  +$(OBJDIR)\tktsetup$O : tktsetup_.c tktsetup.h
          456  +	$(TCC) /Fo$@ -c tktsetup_.c
          457  +
          458  +tktsetup_.c : $(SRCDIR)\tktsetup.c
          459  +	translate$E $** > $@
          460  +
          461  +$(OBJDIR)\undo$O : undo_.c undo.h
          462  +	$(TCC) /Fo$@ -c undo_.c
          463  +
          464  +undo_.c : $(SRCDIR)\undo.c
          465  +	translate$E $** > $@
          466  +
          467  +$(OBJDIR)\update$O : update_.c update.h
          468  +	$(TCC) /Fo$@ -c update_.c
          469  +
          470  +update_.c : $(SRCDIR)\update.c
          471  +	translate$E $** > $@
          472  +
          473  +$(OBJDIR)\url$O : url_.c url.h
          474  +	$(TCC) /Fo$@ -c url_.c
          475  +
          476  +url_.c : $(SRCDIR)\url.c
          477  +	translate$E $** > $@
          478  +
          479  +$(OBJDIR)\user$O : user_.c user.h
          480  +	$(TCC) /Fo$@ -c user_.c
          481  +
          482  +user_.c : $(SRCDIR)\user.c
          483  +	translate$E $** > $@
          484  +
          485  +$(OBJDIR)\verify$O : verify_.c verify.h
          486  +	$(TCC) /Fo$@ -c verify_.c
          487  +
          488  +verify_.c : $(SRCDIR)\verify.c
          489  +	translate$E $** > $@
          490  +
          491  +$(OBJDIR)\vfile$O : vfile_.c vfile.h
          492  +	$(TCC) /Fo$@ -c vfile_.c
          493  +
          494  +vfile_.c : $(SRCDIR)\vfile.c
          495  +	translate$E $** > $@
          496  +
          497  +$(OBJDIR)\wiki$O : wiki_.c wiki.h
          498  +	$(TCC) /Fo$@ -c wiki_.c
          499  +
          500  +wiki_.c : $(SRCDIR)\wiki.c
          501  +	translate$E $** > $@
          502  +
          503  +$(OBJDIR)\wikiformat$O : wikiformat_.c wikiformat.h
          504  +	$(TCC) /Fo$@ -c wikiformat_.c
          505  +
          506  +wikiformat_.c : $(SRCDIR)\wikiformat.c
          507  +	translate$E $** > $@
          508  +
          509  +$(OBJDIR)\winhttp$O : winhttp_.c winhttp.h
          510  +	$(TCC) /Fo$@ -c winhttp_.c
          511  +
          512  +winhttp_.c : $(SRCDIR)\winhttp.c
          513  +	translate$E $** > $@
          514  +
          515  +$(OBJDIR)\xfer$O : xfer_.c xfer.h
          516  +	$(TCC) /Fo$@ -c xfer_.c
          517  +
          518  +xfer_.c : $(SRCDIR)\xfer.c
          519  +	translate$E $** > $@
          520  +
          521  +$(OBJDIR)\zip$O : zip_.c zip.h
          522  +	$(TCC) /Fo$@ -c zip_.c
          523  +
          524  +zip_.c : $(SRCDIR)\zip.c
          525  +	translate$E $** > $@
          526  +
          527  +headers: makeheaders$E page_index.h VERSION.h
          528  +	makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h
          529  +	@copy /Y nul: headers

Added win/fossil.ico.

cannot compute difference between binary files

Added win/fossil.rc.

            1  +#include <windows.h>
            2  +#include "VERSION.h"
            3  +#define _RC_COMPILE_
            4  +#include "config.h"
            5  +
            6  +LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US
            7  +
            8  +VS_VERSION_INFO VERSIONINFO
            9  +FILEVERSION 1,0,0,0
           10  +PRODUCTVERSION 1,0,0,0
           11  +FILEFLAGSMASK 0x3F
           12  +FILEFLAGS 0x0
           13  +FILEOS VOS__WINDOWS32
           14  +FILETYPE VFT_APP
           15  +FILESUBTYPE VFT2_UNKNOWN
           16  +BEGIN
           17  +  BLOCK "StringFileInfo"
           18  +  BEGIN
           19  +    BLOCK "040904B0"
           20  +    BEGIN
           21  +      VALUE "FileDescription", "distributed source code control system with integrated wiki and ticket-system\0"
           22  +      VALUE "Comments", "compiler: "COMPILER_NAME"\0"
           23  +      VALUE "FileVersion", MANIFEST_UUID"("COMPILER_NAME"\0"
           24  +      VALUE "InternalName", "fossil\0"
           25  +      VALUE "LegalCopyright", "Copyright (c) "MANIFEST_YEAR" D. Richard Hipp\0"
           26  +      VALUE "OriginalFilename", "fossil.exe\0"
           27  +      VALUE "ProductName", "fossil\0"
           28  +      VALUE "ProductVersion", MANIFEST_VERSION" "MANIFEST_DATE" UTC\0"
           29  +    END
           30  +  END
           31  +  BLOCK "VarFileInfo"
           32  +  BEGIN
           33  +    VALUE "Translation", 0x409, 0x4B0
           34  +  END
           35  +END
           36  +
           37  +8001 ICON "fossil.ico"
           38  +

Added win/include/dirent.h.

            1  +/*****************************************************************************
            2  + * dirent.h - dirent API for Microsoft Visual Studio
            3  + *
            4  + * Copyright (C) 2006 Toni Ronkko
            5  + *
            6  + * Permission is hereby granted, free of charge, to any person obtaining
            7  + * a copy of this software and associated documentation files (the
            8  + * ``Software''), to deal in the Software without restriction, including
            9  + * without limitation the rights to use, copy, modify, merge, publish,
           10  + * distribute, sublicense, and/or sell copies of the Software, and to
           11  + * permit persons to whom the Software is furnished to do so, subject to
           12  + * the following conditions:
           13  + *
           14  + * The above copyright notice and this permission notice shall be included
           15  + * in all copies or substantial portions of the Software.
           16  + *
           17  + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
           18  + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
           19  + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
           20  + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
           21  + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
           22  + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
           23  + * OTHER DEALINGS IN THE SOFTWARE.
           24  + *
           25  + * Dec 15, 2009, John Cunningham
           26  + * Added rewinddir member function
           27  + *
           28  + * Jan 18, 2008, Toni Ronkko
           29  + * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
           30  + * between multi-byte and unicode representations.  This makes the
           31  + * code simpler and also allows the code to be compiled under MingW.  Thanks
           32  + * to Azriel Fasten for the suggestion.
           33  + *
           34  + * Mar 4, 2007, Toni Ronkko
           35  + * Bug fix: due to the strncpy_s() function this file only compiled in
           36  + * Visual Studio 2005.  Using the new string functions only when the
           37  + * compiler version allows.
           38  + *
           39  + * Nov  2, 2006, Toni Ronkko
           40  + * Major update: removed support for Watcom C, MS-DOS and Turbo C to
           41  + * simplify the file, updated the code to compile cleanly on Visual
           42  + * Studio 2005 with both unicode and multi-byte character strings,
           43  + * removed rewinddir() as it had a bug.
           44  + *
           45  + * Aug 20, 2006, Toni Ronkko
           46  + * Removed all remarks about MSVC 1.0, which is antiqued now.  Simplified
           47  + * comments by removing SGML tags.
           48  + *
           49  + * May 14 2002, Toni Ronkko
           50  + * Embedded the function definitions directly to the header so that no
           51  + * source modules need to be included in the Visual Studio project.  Removed
           52  + * all the dependencies to other projects so that this very header can be
           53  + * used independently.
           54  + *
           55  + * May 28 1998, Toni Ronkko
           56  + * First version.
           57  + *****************************************************************************/
           58  +#ifndef DIRENT_H
           59  +#define DIRENT_H
           60  +
           61  +#include <windows.h>
           62  +#include <string.h>
           63  +#include <assert.h>
           64  +
           65  +
           66  +typedef struct dirent
           67  +{
           68  +   char d_name[MAX_PATH + 1]; /* current dir entry (multi-byte char string) */
           69  +   WIN32_FIND_DATAA data;     /* file attributes */
           70  +}  dirent;
           71  +
           72  +
           73  +typedef struct DIR
           74  +{
           75  +   dirent current;            /* Current directory entry */
           76  +   int    cached;             /* Indicates un-processed entry in memory */
           77  +   HANDLE search_handle;      /* File search handle */
           78  +   char   patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
           79  +} DIR;
           80  +
           81  +
           82  +/* Forward declarations */
           83  +static DIR *opendir (const char *dirname);
           84  +static struct dirent *readdir (DIR *dirp);
           85  +static int closedir (DIR *dirp);
           86  +static void rewinddir(DIR* dirp);
           87  +
           88  +
           89  +/* Use the new safe string functions introduced in Visual Studio 2005 */
           90  +#if defined(_MSC_VER) && _MSC_VER >= 1400
           91  +# define STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
           92  +#else
           93  +# define STRNCPY(dest,src,size) strncpy((dest),(src),(size))
           94  +#endif
           95  +
           96  +
           97  +/*****************************************************************************
           98  + * Open directory stream DIRNAME for read and return a pointer to the
           99  + * internal working area that is used to retrieve individual directory
          100  + * entries.
          101  + */
          102  +static DIR *opendir(const char *dirname)
          103  +{
          104  +   DIR *dirp;
          105  +   assert (dirname != NULL);
          106  +   assert (strlen (dirname) < MAX_PATH);
          107  +
          108  +   /* construct new DIR structure */
          109  +   dirp = (DIR*) malloc (sizeof (struct DIR));
          110  +   if (dirp != NULL) {
          111  +      char *p;
          112  +
          113  +      /* take directory name... */
          114  +      STRNCPY (dirp->patt, dirname, sizeof(dirp->patt));
          115  +      dirp->patt[MAX_PATH] = '\0';
          116  +
          117  +      /* ... and append search pattern to it */
          118  +      p = strchr (dirp->patt, '\0');
          119  +      if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
          120  +         *p++ = '\\';
          121  +      }
          122  +      *p++ = '*';
          123  +      *p = '\0';
          124  +
          125  +      /* open stream and retrieve first file */
          126  +      dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
          127  +      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
          128  +         /* invalid search pattern? */
          129  +         free (dirp);
          130  +         return NULL;
          131  +      }
          132  +
          133  +      /* there is an un-processed directory entry in memory now */
          134  +      dirp->cached = 1;
          135  +   }
          136  +
          137  +   return dirp;
          138  +}
          139  +
          140  +
          141  +/*****************************************************************************
          142  + * Read a directory entry, and return a pointer to a dirent structure
          143  + * containing the name of the entry in d_name field.  Individual directory
          144  + * entries returned by this very function include regular files,
          145  + * sub-directories, pseudo-directories "." and "..", but also volume labels,
          146  + * hidden files and system files may be returned.
          147  + */
          148  +static struct dirent *readdir(DIR *dirp)
          149  +{
          150  +   assert (dirp != NULL);
          151  +
          152  +   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
          153  +      /* directory stream was opened/rewound incorrectly or ended normally */
          154  +      return NULL;
          155  +   }
          156  +
          157  +   /* get next directory entry */
          158  +   if (dirp->cached != 0) {
          159  +      /* a valid directory entry already in memory */
          160  +      dirp->cached = 0;
          161  +   } else {
          162  +      /* read next directory entry from disk */
          163  +      if (FindNextFileA (dirp->search_handle, &dirp->current.data) == FALSE) {
          164  +         /* the very last file has been processed or an error occured */
          165  +         FindClose (dirp->search_handle);
          166  +         dirp->search_handle = INVALID_HANDLE_VALUE;
          167  +         return NULL;
          168  +      }
          169  +   }
          170  +
          171  +   /* copy as a multibyte character string */
          172  +   STRNCPY ( dirp->current.d_name,
          173  +             dirp->current.data.cFileName,
          174  +             sizeof(dirp->current.d_name) );
          175  +   dirp->current.d_name[MAX_PATH] = '\0';
          176  +
          177  +   return &dirp->current;
          178  +}
          179  +
          180  +
          181  +/*****************************************************************************
          182  + * Close directory stream opened by opendir() function.  Close of the
          183  + * directory stream invalidates the DIR structure as well as any previously
          184  + * read directory entry.
          185  + */
          186  +static int closedir(DIR *dirp)
          187  +{
          188  +   assert (dirp != NULL);
          189  +
          190  +   /* release search handle */
          191  +   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
          192  +      FindClose (dirp->search_handle);
          193  +      dirp->search_handle = INVALID_HANDLE_VALUE;
          194  +   }
          195  +
          196  +   /* release directory handle */
          197  +   free (dirp);
          198  +   return 0;
          199  +}
          200  +
          201  +
          202  +/*****************************************************************************
          203  + * Resets the position of the directory stream to which dirp refers to the
          204  + * beginning of the directory. It also causes the directory stream to refer
          205  + * to the current state of the corresponding directory, as a call to opendir()
          206  + * would have done. If dirp does not refer to a directory stream, the effect
          207  + * is undefined.
          208  + */
          209  +static void rewinddir(DIR* dirp)
          210  +{
          211  +   /* release search handle */
          212  +   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
          213  +      FindClose (dirp->search_handle);
          214  +      dirp->search_handle = INVALID_HANDLE_VALUE;
          215  +   }
          216  +
          217  +   /* open new search handle and retrieve first file */
          218  +   dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
          219  +   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
          220  +      /* invalid search pattern? */
          221  +      free (dirp);
          222  +      return;
          223  +   }
          224  +
          225  +   /* there is an un-processed directory entry in memory now */
          226  +   dirp->cached = 1;
          227  +}
          228  +
          229  +
          230  +#endif /*DIRENT_H*/

Added win/include/unistd.h.

            1  +#ifndef _UNISTD_H
            2  +#define _UNISTD_H	 1
            3  +
            4  +/* This file intended to serve as a drop-in replacement for 
            5  + *  unistd.h on Windows
            6  + *  Please add functionality as neeeded 
            7  + */
            8  +
            9  +#include <stdlib.h>
           10  +#include <io.h>
           11  +#define srandom srand
           12  +#define random rand
           13  +#if defined(__DMC__)
           14  +#endif
           15  +
           16  +#if defined(_WIN32)
           17  +#define _CRT_SECURE_NO_WARNINGS 1
           18  +
           19  +#ifndef F_OK
           20  +#define F_OK 0
           21  +#endif /* not F_OK */
           22  +
           23  +#ifndef X_OK
           24  +#define X_OK 1
           25  +#endif /* not X_OK */
           26  +
           27  +#ifndef R_OK
           28  +#define R_OK 2
           29  +#endif /* not R_OK */
           30  +
           31  +#ifndef W_OK
           32  +#define W_OK 4
           33  +#endif /* not W_OK */
           34  +
           35  +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
           36  +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
           37  +
           38  +
           39  +
           40  +#endif
           41  +
           42  +#define access _access
           43  +#define ftruncate _chsize
           44  +
           45  +#define ssize_t int
           46  +
           47  +#endif /* unistd.h  */

Added win/version.c.

            1  +#include <stdio.h>
            2  +
            3  +int main(int argc, char *argv[]){
            4  +    FILE *m,*u;
            5  +    char b[10240];
            6  +    u = fopen(argv[1],"r");
            7  +    fgets(b, sizeof(b)-1,u);
            8  +    b[strlen(b)-1] =0;
            9  +    printf("#define MANIFEST_UUID \"%s\"\n",b);
           10  +    printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
           11  +    m = fopen(argv[2],"r");
           12  +    while(b ==  fgets(b, sizeof(b)-1,m)){
           13  +        if(0 == strncmp("D ",b,2)){
           14  +            printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13);
           15  +            printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2);
           16  +            return 0;
           17  +        }
           18  +    }
           19  +    return 1;
           20  +}

Changes to www/branching.wiki.

   153    153   concerned, there is no difference.  The distinction is in the intent.
   154    154   In figure 2, the fact that check-in 2 has multiple children is an
   155    155   accident that stems from concurrent development.  In figure 4, giving
   156    156   check-in 2 multiple children is a deliberate act.  So, to a good
   157    157   approximation, we define forking to be by accident and branching to
   158    158   be by intent.  Apart from that, they are the same.
   159    159   
          160  +<a name="tags"></a>
   160    161   <h2>Tags And Properties</h2>
   161    162   
   162    163   Tags and properties are used in fossil to help express the intent, and
   163    164   thus to distinguish between forks and branches.  Figure 5 shows the
   164    165   same scenario as figure 4 but with tags and properties added:
   165    166   
   166    167   <center><table border=1 cellpadding=10 hspace=10 vspace=10>

Added www/event.wiki.

            1  +<title>Events</title>
            2  +
            3  +<h2>What Is An "Event"?</h2>
            4  +
            5  +In Fossil, and "event" is a special kind of [./wikitheory.wiki | wiki page]
            6  +that is associated with a point in time rather than having a page name.
            7  +Each event causes a single entry to appear on the [/timeline | Timeline Page].
            8  +Clicking on the hyperlink of the timeline entry cause a jump to the wiki
            9  +content for the event.  The wiki content, the timeline entry text, the
           10  +time of the event, and the timeline background color can all be edited.
           11  +
           12  +As with check-ins, wiki, and tickets, all events automatically synchronize
           13  +to other repositories.  Hence, events can be viewed, created, and edited
           14  +off-line.  And the complete edit history for events is maintained
           15  +for auditing purposes.
           16  +
           17  +Possible uses for events include:
           18  +
           19  +  *  <b>Milestones</b>.  Project milestones, such as releases or beta-test
           20  +      cycles, can be recorded as events.  The timeline entry for the event
           21  +      can be something simple like "Version 1.2.3" perhaps with a bright
           22  +      color background to draw attention to the entry and the wiki content
           23  +      can contain release notes, for example.
           24  +
           25  +  *  <b>Blog Entries</b>.  Blog entries from developers describing the current
           26  +     state of a project, or rational for various design decisions, or 
           27  +     roadmaps for future development, can be entered as events.
           28  +
           29  +  *  <b>Process Checkpoints</b>.  For projects that have a formal process,
           30  +     events can be used to record the completion or the initiation of
           31  +     various process steps.  For example, an event can be used to record
           32  +     the successful completion of a long-running test, perhaps with
           33  +     performance results and details of where the test was run and who
           34  +     ran it recorded in the wiki content.
           35  +
           36  +  *  <b>News Articles</b>.  Significant occurrences in the lifecycle of
           37  +     a project can be recorded as news articles using events.  Perhaps the
           38  +     domain name of the canonical website for a project changes, or new
           39  +     server hardware is obtained.  Such happenings are appropriate for
           40  +     reporting as news.
           41  +
           42  +  *  <b>Announcements</b>.  Changes to the composition of the development
           43  +     team or acquisition of new project sponsors can be communicated as
           44  +     announcements which can be implemented as events.
           45  +
           46  +No project is required to use events.  But events can help many projects
           47  +stay better organized and provide a better historical record of the
           48  +development progress.
           49  +
           50  +<h2>Viewing Events</h2>
           51  +
           52  +Because events are considered a special kind of wiki, 
           53  +users must have permission to read wiki in order read events.
           54  +Enable the "j" permission under the /Setup/Users menu in order
           55  +to give specific users or user classes the ability to view wiki
           56  +and events.
           57  +
           58  +Events show up on the timeline.  Click on the hyperlink beside the
           59  +event title to see the details of the event.
           60  +
           61  +<h2>Creating And Editing Events</h2>
           62  +
           63  +There is a hyperlink under the /Wiki menu that can be used to create
           64  +new events.  And there is a submenu hyperlink on event displays for
           65  +editing existing events.
           66  +
           67  +Users must have check-in privileges (permission "i") in order to 
           68  +create or edit events.  In addition, users must have create-wiki
           69  +privilege (permission "f") to create new events and edit-wiki
           70  +privilege (permission "k") in order to edit existing events.
           71  +
           72  +If the first non-whitespace text of the event wiki content is
           73  +&lt;title&gt;...&lt;/title&gt; then that markup is omitted from
           74  +the body of the wiki pages and is instead displayed as the page
           75  +title.

Changes to www/fileformat.wiki.

    41     41   <ul>
    42     42   <li> [#manifest | Manifests] </li>
    43     43   <li> [#cluster | Clusters] </li>
    44     44   <li> [#ctrl | Control Artifacts] </li>
    45     45   <li> [#wikichng | Wiki Pages] </li>
    46     46   <li> [#tktchng | Ticket Changes] </li>
    47     47   <li> [#attachment | Attachments] </li>
           48  +<li> [#event | Events] </li>
    48     49   </ul>
    49     50   
    50         -These five artifact types are described in the sequel.
           51  +These seven artifact types are described in the sequel.
    51     52   
    52     53   In the current implementation (as of 2009-01-25) the artifacts that
    53     54   make up a fossil repository are stored in in as delta- and zlib-compressed
    54     55   blobs in an <a href="http://www.sqlite.org/">SQLite</a> database.  This
    55     56   is an implementation detail and might change in a future release.  For
    56     57   the purpose of this article "file format" means the format of the artifacts,
    57     58   not how the artifacts are stored on disk.  It is the artifact format that
    58     59   is intended to be enduring.  The specifics of how artifacts are stored on
    59     60   disk, though stable, is not intended to live as long as the
    60     61   artifact format.
           62  +
           63  +All of the artifacts can be extracted from a Fossil repository using
           64  +the "fossil deconstruct" command.
    61     65   
    62     66   <a name="manifest"></a>
    63     67   <h2>1.0 The Manifest</h2>
    64     68   
    65     69   A manifest defines a check-in or version of the project
    66     70   source tree.  The manifest contains a list of artifacts for
    67     71   each file in the project and the corresponding filenames, as
................................................................................
    89     93   No card may be duplicated.
    90     94   The entire manifest may be PGP clear-signed, but otherwise it
    91     95   may contain no additional text or data beyond what is described here.
    92     96   
    93     97   Allowed cards in the manifest are as follows:
    94     98   
    95     99   <blockquote>
          100  +<b>B</b> <i>baseline-manifest</i><br>
    96    101   <b>C</b> <i>checkin-comment</i><br>
    97    102   <b>D</b> <i>time-and-date-stamp</i><br>
    98    103   <b>F</b> <i>filename</i> <i>SHA1-hash</i> <i>permissions</i> <i>old-name</i><br>
    99    104   <b>P</b> <i>SHA1-hash</i>+<br>
   100    105   <b>R</b> <i>repository-checksum</i><br>
   101    106   <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name  <b>*</b> ?value?</i><br>
   102    107   <b>U</b> <i>user-login</i><br>
   103    108   <b>Z</b> <i>manifest-checksum</i>
   104    109   </blockquote>
          110  +
          111  +A manifest may optionally have a single B-card.  The B-card specifies
          112  +another manifest that serves as the "baseline" for this manifest.  A
          113  +manifest that has a B-card is called a delta-manifest and a manifest
          114  +that omits the B-card is a baseline-manifest.  The other manifest
          115  +identified by the argument of the B-card must be a baseline-manifest.
          116  +A baseline-manifest records the complete contents of a checkin.
          117  +A delta-manifest records only changes from its baseline.  
   105    118   
   106    119   A manifest must have exactly one C-card.  The sole argument to
   107    120   the C-card is a check-in comment that describes the check-in that
   108    121   the manifest defines.  The check-in comment is text.  The following
   109    122   escape sequences are applied to the text:
   110    123   A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73).  A
   111         -newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E).  A backslash 
          124  +newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E).  A backslash 
   112    125   (ASCII 0x5C) is represented as two backslashes "\\".  Apart from
   113    126   space and newline, no other whitespace characters are allowed in
   114    127   the check-in comment.  Nor are any unprintable characters allowed
   115    128   in the comment.
   116    129   
   117    130   A manifest must have exactly one D-card.  The sole argument to
   118    131   the D-card is a date-time stamp in the ISO8601 format.  The
................................................................................
   119    132   date and time should be in coordinated universal time (UTC).
   120    133   The format is:
   121    134   
   122    135   <blockquote>
   123    136   <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i>
   124    137   </blockquote>
   125    138   
   126         -A manifest has zero or more F-cards.  Each F-card defines a file
   127         -(other than the manifest itself) which is part of the check-in that
   128         -the manifest defines.  There are two, three, or four arguments.
          139  +A manifest has zero or more F-cards.  Each F-card identifies a file
          140  +that is part of the check-in.  There are one, two, three, or four arguments.
   129    141   The first argument
   130    142   is the pathname of the file in the check-in relative to the root
   131    143   of the project file hierarchy.  No ".." or "." directories are allowed
   132    144   within the filename.  Space characters are escaped as in C-card
   133    145   comment text.  Backslash characters and newlines are not allowed
   134    146   within filenames.  The directory separator character is a forward
   135    147   slash (ASCII 0x2F).  The second argument to the F-card is the
   136    148   full 40-character lower-case hexadecimal SHA1 hash of the content
   137         -artifact.  The optional 3rd argument defines any special access 
          149  +artifact.  The second argument is required for baseline manifests
          150  +but is optional for delta manifests.  When the second argument to the
          151  +F-card is omitted, it means that the file has been deleted relative
          152  +to the baseline.  The optional 3rd argument defines any special access 
   138    153   permissions associated with the file.  The only special code currently
   139    154   defined is "x" which means that the file is executable.  All files are
   140    155   always readable and writable.  This can be expressed by "w" permission
   141         -if desired but is optional.
          156  +if desired but is optional.  The file format might be extended with
          157  +new permission letters in the future.
   142    158   The optional 4th argument is the name of the same file as it existed in
   143    159   the parent check-in.  If the name of the file is unchanged from its
   144    160   parent, then the 4th argument is omitted.
   145    161   
   146    162   A manifest has zero or one P-cards.  Most manifests have one P-card.
   147    163   The P-card has a varying number of arguments that
   148    164   defines other manifests from which the current manifest
................................................................................
   163    179   the manifest itself) in strict sorted lexicographical order, 
   164    180   take the pathname of the file relative to the root of the
   165    181   repository, append a single space (ASCII 0x20), the
   166    182   size of the file in ASCII decimal, a single newline
   167    183   character (ASCII 0x0A), and the complete text of the file.
   168    184   Compute the MD5 checksum of the result.
   169    185   
   170         -A manifest might contain one or more T-cards used to set tags or
   171         -properties on the check-in.  The format of the T-card is the same as
          186  +A manifest might contain one or more T-cards used to set
          187  +[./branching.wiki#tags | tags or properties]
          188  +on the check-in.  The format of the T-card is the same as
   172    189   described in <i>Control Artifacts</i> section below, except that the
   173    190   second argument is the single characcter "<b>*</b>" instead of an
   174    191   artifact ID.  The <b>*</b> in place of the artifact ID indicates that
   175    192   the tag or property applies to the current artifact.  It is not
   176    193   possible to encode the current artifact ID as part of an artifact,
   177    194   since the act of inserting the artifact ID would change the artifact ID,
   178    195   hence a <b>*</b> is used to represent "self".  T-cards are typically
................................................................................
   180    197   symbolic name when the check-in is intended to start a new branch.
   181    198   
   182    199   Each manifest has a single U-card.  The argument to the U-card is
   183    200   the login of the user who created the manifest.  The login name
   184    201   is encoded using the same character escapes as is used for the
   185    202   check-in comment argument to the C-card.
   186    203   
   187         -A manifest has an option Z-card as its last line.  The argument
          204  +A manifest has an optional Z-card as its last line.  The argument
   188    205   to the Z-card is a 32-character lowercase hexadecimal MD5 hash
   189    206   of all prior lines of the manifest up to and including the newline 
   190    207   character that immediately precedes the "Z".  The Z-card is just
   191    208   a sanity check to prove that the manifest is well-formed and
   192    209   consistent.
   193    210   
   194    211   A sample manifest from Fossil itself can be seen
................................................................................
   260    277   one or more T cards.  No other cards or other text is
   261    278   allowed in a control artifact.  Control artifacts might be PGP
   262    279   clearsigned.
   263    280   
   264    281   The D card and the Z card of a control artifact are the same
   265    282   as in a manifest.
   266    283   
   267         -The T card represents a "tag" or property that is applied to
          284  +The T card represents a [./branching.wiki#tags | tag or property]
          285  +that is applied to
   268    286   some other artifact.  The T card has two or three values.  The
   269    287   second argument is the 40 character lowercase artifact ID of the artifact
   270    288   to which the tag is to be applied. The
   271    289   first value is the tag name.  The first character of the tag
   272    290   is either "+", "-", or "*".  A "+" means the tag should be added
   273    291   to the artifact.  The "-" means the tag should be removed.
   274    292   The "*" character means the tag should be added to the artifact
................................................................................
   322    340   The W card is used to specify the text of the wiki page.  The
   323    341   argument to the W card is an integer which is the number of bytes
   324    342   of text in the wiki page.  That text follows the newline character
   325    343   that terminates the W card.  The wiki text is always followed by one
   326    344   extra newline.
   327    345   
   328    346   An example wiki artifact can be seen
   329         -[/artifact/7b2f5fd0e0 | here].
          347  +[/artifact?name=7b2f5fd0e0&txt=1 | here].
   330    348   
   331    349   <a name="tktchng"></a>
   332    350   <h2>5.0 Ticket Changes</h2>
   333    351   
   334    352   A ticket-change artifact represents a change to a trouble ticket.
   335    353   The following cards are allowed on a ticket change artifact:
   336    354   
................................................................................
   373    391   An example ticket-change artifact can be seen
   374    392   [/artifact/91f1ec6af053 | here].
   375    393   
   376    394   <a name="attachment"></a>
   377    395   <h2>6.0 Attachments</h2>
   378    396   
   379    397   An attachment artifact associates some other artifact that is the
   380         -attachment (the source artifact) with a ticket or wiki page to which
          398  +attachment (the source artifact) with a ticket or wiki page or event to which
   381    399   the attachment is connected (the target artifact).
   382    400   The following cards are allowed on an attachment artifact:
   383    401   
   384    402   <blockquote>
   385         -<b>A</b> <i>filename target</i> ?<i>source</i>?
   386         -<b>C</b> <i>comment</i><br>
          403  +<b>A</b> <i>filename target</i> ?<i>source</i>?<br />
          404  +<b>C</b> <i>comment</i><br />
   387    405   <b>D</b> <i>time-and-date-stamp</i><br />
   388    406   <b>U</b> <i>user-name</i><br />
   389    407   <b>Z</b> <i>checksum</i>
   390    408   </blockquote>
   391    409   
   392    410   The A card specifies a filename for the attachment in its first argument.
   393    411   The second argument to the A card is the name
   394         -of the wiki page or ticket to which the attachment is connected.  The
          412  +of the wiki page or ticket or event to which the attachment is connected.  The
   395    413   third argument is either missing or else it is the 40-character artifact 
   396    414   ID of the attachment itself.  A missing third argument means that the
   397    415   attachment should be deleted.
   398    416   
   399    417   The C card is an optional comment describing what the attachment is about.
   400    418   The C card is optional, but there can only be one.
   401    419   
................................................................................
   403    421   was applied.
   404    422   
   405    423   A single U card gives the name of the user to added the attachment.
   406    424   If an attachment is added anonymously, then the U card may be omitted.
   407    425   
   408    426   The Z card is the usual checksum over the rest of the attachment artifact.
   409    427   
          428  +
          429  +<a name="event"></a>
          430  +<h2>7.0 Events</h2>
          431  +
          432  +An event artifact associates a timeline comment and a page of text
          433  +(similar to a wiki page) with a point in time.  Events can be used
          434  +to record project milestones, release notes, blog entries, process
          435  +checkpoints, or news articles.
          436  +The following cards are allowed on an event artifact:
          437  +
          438  +<blockquote>
          439  +<b>C</b> <i>comment</i><br>
          440  +<b>D</b> <i>time-and-date-stamp</i><br />
          441  +<b>E</b> <i>event-time</i> <i>event-id</i><br />
          442  +<b>P</b> <i>parent-artifact-id</i>+<br />
          443  +<b>T</b> <b>+</b><i>tag-name</i> <b>*</b> <i>value</i><br />
          444  +<b>U</b> <i>user-name</i><br />
          445  +<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
          446  +<b>Z</b> <i>checksum</i>
          447  +</blockquote>
          448  +
          449  +The C card contains text that is displayed on the timeline for the
          450  +event.  Exactly one C card is required on an event artifact.
          451  +
          452  +A single D card is required to give the date and time when the 
          453  +event artifact was created.  This is different from the time at which
          454  +the event occurs.
          455  +
          456  +A single E card gives the time of the event (the point on the timeline
          457  +where the event is displayed) and a unique identifier for the event.
          458  +When there are multiple artifacts with the same event-id, the one with
          459  +the most recent D card is the only one used.  The event-id must be a
          460  +40-character lower-case hexadecimal string.
          461  +
          462  +The option P card specifies a prior event with the same event-id from
          463  +which the current event is an edit.  The P card is a hint to the system
          464  +that it might be space efficient to store one event as a delta of the
          465  +other.
          466  +
          467  +An event might contain one or more T-cards used to set
          468  +[./branching.wiki#tags | tags or properties]
          469  +on the event.  The format of the T-card is the same as
          470  +described in [#ctrl | Control Artifacts] section above, except that the
          471  +second argument is the single characcter "<b>*</b>" instead of an
          472  +artifact ID and the name is always prefaced by "<b>+</b>".
          473  +The <b>*</b> in place of the artifact ID indicates that
          474  +the tag or property applies to the current artifact.  It is not
          475  +possible to encode the current artifact ID as part of an artifact,
          476  +since the act of inserting the artifact ID would change the artifact ID,
          477  +hence a <b>*</b> is used to represent "self".  The "<b>+</b>" on the
          478  +name means that tags can only be add and they can only be non-propagating
          479  +tags.  A an event, T cards are normally used to set the background
          480  +display color for timelines.
          481  +
          482  +The optional U card gives name of the user who entered the event.
          483  +
          484  +A single W card provides wiki text for the document associated with the
          485  +event.  The format of the W card is exactly the same as for a 
          486  +[#wikichng | wiki artifact].
          487  +
          488  +The Z card is the usual checksum over the rest of the attachment artifact.
          489  +
   410    490   
   411    491   <a name="summary"></a>
   412         -<h2>7.0 Card Summary</h2>
          492  +<h2>8.0 Card Summary</h2>
   413    493   
   414    494   The following table summaries the various kinds of cards that
   415    495   appear on Fossil artifacts:
   416    496   
   417    497   <table border=1 width="100%">
   418    498   <tr>
   419    499   <th rowspan=2 valign=bottom>Card Format</th>
   420         -<th colspan=6>Used By</th>
          500  +<th colspan=7>Used By</th>
   421    501   </tr>
   422    502   <tr>
   423    503   <th>Manifest</th>
   424    504   <th>Cluster</th>
   425    505   <th>Control</th>
   426    506   <th>Wiki</th>
   427    507   <th>Ticket</th>
   428    508   <th>Attachment</th>
          509  +<th>Event</th>
   429    510   </tr>
   430    511   <tr>
   431    512   <td><b>A</b> <i>filename target source</i></td>
   432    513   <td>&nbsp;</td>
   433    514   <td>&nbsp;</td>
   434    515   <td>&nbsp;</td>
   435    516   <td>&nbsp;</td>
   436    517   <td>&nbsp;</td>
   437    518   <td align=center><b>X</b></td>
          519  +<td>&nbsp;</td>
   438    520   </tr>
   439    521   <tr>
   440         -<td><b>C</b> <i>coment-text</i></td>
          522  +<td><b>B</b> <i>baseline</i></td>
          523  +<td align=center><b>X</b></td>
          524  +<td>&nbsp;</td>
          525  +<td>&nbsp;</td>
          526  +<td>&nbsp;</td>
          527  +<td>&nbsp;</td>
          528  +<td>&nbsp;</td>
          529  +<td>&nbsp;</td>
          530  +</tr>
          531  +<tr>
          532  +<td><b>C</b> <i>comment-text</i></td>
   441    533   <td align=center><b>X</b></td>
   442    534   <td>&nbsp;</td>
   443    535   <td>&nbsp;</td>
   444    536   <td>&nbsp;</td>
   445    537   <td>&nbsp;</td>
          538  +<td align=center><b>X</b></td>
   446    539   <td align=center><b>X</b></td>
   447    540   </tr>
   448    541   <tr>
   449    542   <td><b>D</b> <i>date-time-stamp</i></td>
   450    543   <td align=center><b>X</b></td>
   451    544   <td align=center>&nbsp;</td>
   452    545   <td align=center><b>X</b></td>
   453    546   <td align=center><b>X</b></td>
   454    547   <td align=center><b>X</b></td>
   455    548   <td align=center><b>X</b></td>
          549  +<td align=center><b>X</b></td>
          550  +</tr>
          551  +<tr>
          552  +<td><b>E</b> <i>event-time event-id</i></td>
          553  +<td align=center>&nbsp;</td>
          554  +<td align=center>&nbsp;</td>
          555  +<td align=center>&nbsp;</td>
          556  +<td align=center>&nbsp;</td>
          557  +<td align=center>&nbsp;</td>
          558  +<td align=center>&nbsp;</td>
          559  +<td align=center><b>X</b></td>
   456    560   </tr>
   457    561   <tr>
   458    562   <td><b>F</b> <i>filename uuid permissions oldname</i></td>
   459    563   <td align=center><b>X</b></td>
          564  +<td align=center>&nbsp;</td>
   460    565   <td align=center>&nbsp;</td>
   461    566   <td align=center>&nbsp;</td>
   462    567   <td align=center>&nbsp;</td>
   463    568   <td align=center>&nbsp;</td>
   464    569   <td align=center>&nbsp;</td>
   465    570   </tr>
   466    571   <tr>
................................................................................
   467    572   <td><b>J</b> <i>name value</i></td>
   468    573   <td align=center>&nbsp;</td>
   469    574   <td align=center>&nbsp;</td>
   470    575   <td align=center>&nbsp;</td>
   471    576   <td align=center>&nbsp;</td>
   472    577   <td align=center><b>X</b></td>
   473    578   <td align=center>&nbsp;</td>
          579  +<td align=center>&nbsp;</td>
   474    580   </tr>
   475    581   <tr>
   476    582   <td><b>K</b> <i>ticket-uuid</i></td>
   477    583   <td align=center>&nbsp;</td>
   478    584   <td align=center>&nbsp;</td>
   479    585   <td align=center>&nbsp;</td>
   480    586   <td align=center>&nbsp;</td>
   481    587   <td align=center><b>X</b></td>
          588  +<td align=center>&nbsp;</td>
   482    589   <td align=center>&nbsp;</td>
   483    590   </tr>
   484    591   <tr>
   485    592   <td><b>L</b> <i>wiki-title</i></td>
   486    593   <td align=center>&nbsp;</td>
   487    594   <td align=center>&nbsp;</td>
   488    595   <td align=center>&nbsp;</td>
   489    596   <td align=center><b>X</b></td>
   490    597   <td align=center>&nbsp;</td>
   491    598   <td align=center>&nbsp;</td>
          599  +<td align=center>&nbsp;</td>
   492    600   </tr>
   493    601   <tr>
   494    602   <td><b>M</b> <i>uuid</i></td>
   495    603   <td align=center>&nbsp;</td>
   496    604   <td align=center><b>X</b></td>
          605  +<td align=center>&nbsp;</td>
   497    606   <td align=center>&nbsp;</td>
   498    607   <td align=center>&nbsp;</td>
   499    608   <td align=center>&nbsp;</td>
   500    609   <td align=center>&nbsp;</td>
   501    610   </tr>
   502    611   <tr>
   503    612   <td><b>P</b> <i>uuid ...</i></td>
   504    613   <td align=center><b>X</b></td>
   505    614   <td align=center>&nbsp;</td>
   506    615   <td align=center>&nbsp;</td>
   507    616   <td align=center><b>X</b></td>
   508    617   <td align=center>&nbsp;</td>
   509    618   <td align=center>&nbsp;</td>
          619  +<td align=center>&nbsp;</td>
   510    620   </tr>
   511    621   <tr>
   512    622   <td><b>R</b> <i>md5sum</i></td>
   513    623   <td align=center><b>X</b></td>
          624  +<td align=center>&nbsp;</td>
   514    625   <td align=center>&nbsp;</td>
   515    626   <td align=center>&nbsp;</td>
   516    627   <td align=center>&nbsp;</td>
   517    628   <td align=center>&nbsp;</td>
   518    629   <td align=center>&nbsp;</td>
   519    630   <tr>
   520    631   <td><b>T</b> (<b>+</b>|<b>*</b>|<b>-</b>)<i>tagname uuid value</i></td>
   521    632   <td align=center><b>X</b></td>
   522    633   <td align=center>&nbsp;</td>
   523    634   <td align=center><b>X</b></td>
   524    635   <td align=center>&nbsp;</td>
   525    636   <td align=center>&nbsp;</td>
   526    637   <td align=center>&nbsp;</td>
          638  +<td align=center><b>X</b></td>
   527    639   </tr>
   528    640   <tr>
   529    641   <td><b>U</b> <i>username</i></td>
   530    642   <td align=center><b>X</b></td>
   531    643   <td align=center>&nbsp;</td>
          644  +<td align=center><b>X</b></td>
   532    645   <td align=center><b>X</b></td>
   533    646   <td align=center><b>X</b></td>
   534    647   <td align=center><b>X</b></td>
   535    648   <td align=center><b>X</b></td>
   536    649   </tr>
   537    650   <tr>
   538    651   <td><b>W</b> <i>size</i></td>
   539    652   <td align=center>&nbsp;</td>
   540    653   <td align=center>&nbsp;</td>
   541    654   <td align=center>&nbsp;</td>
   542    655   <td align=center><b>X</b></td>
   543    656   <td align=center>&nbsp;</td>
   544    657   <td align=center>&nbsp;</td>
          658  +<td align=center><b>X</b></td>
   545    659   </tr>
   546    660   <tr>
   547    661   <td><b>Z</b> <i>md5sum</i></td>
          662  +<td align=center><b>X</b></td>
   548    663   <td align=center><b>X</b></td>
   549    664   <td align=center><b>X</b></td>
   550    665   <td align=center><b>X</b></td>
   551    666   <td align=center><b>X</b></td>
   552    667   <td align=center><b>X</b></td>
   553    668   <td align=center><b>X</b></td>
   554    669   </tr>
   555    670   </table>

Changes to www/index.wiki.

    38     38   
    39     39   There are plenty of open-source version control systems available on the
    40     40   internet these days. What makes Fossil worthy of attention?
    41     41   
    42     42     1.  <b>Bug Tracking And Wiki</b> -
    43     43         In addition to doing [./concepts.wiki | distributed version control]
    44     44         like Git and Mercurial,
    45         -      Fossil also supports [./bugtheory.wiki | distributed bug tracking] and
    46         -      [./wikitheory.wiki | distributed wiki] all in a single
           45  +      Fossil also supports [./bugtheory.wiki | distributed bug tracking],
           46  +      [./wikitheory.wiki | distributed wiki], and a
           47  +      [./event.wiki | distributed blog] mechanism all in a single
    47     48         integrated package.
    48     49   
    49     50     2.  <b>Web Interface</b> - 
    50     51         Fossil has a built-in and easy-to-use [./webui.wiki | web interface]
    51     52         that simplifies project tracking and promotes situational awareness.
    52     53         Simply type "fossil&nbsp;ui" from within any check-out and Fossil
    53     54         automatically opens your web browser in a page that gives detailed
................................................................................
    86     87         used by the [./selfhost.wiki | self-hosting fossil repositories].
    87     88   
    88     89     7.  <b>Robust &amp; Reliable</b> -
    89     90         Fossil stores content using an [./fileformat.wiki | enduring file format]
    90     91         in an SQLite database so that transactions are
    91     92         atomic even if interrupted by a power loss or system crash.  Furthermore,
    92     93         automatic [./selfcheck.wiki | self-checks] verify that all aspects of
    93         -      the repository are consistent prior to each commit.  In nearly three years
           94  +      the repository are consistent prior to each commit.  In over three years
    94     95         of operation, no work has ever been lost after having been committed to
    95     96         a Fossil repository.
    96     97   
    97     98   <hr>
    98     99   <h3>Links For Fossil Users:</h3>
    99    100   
   100    101     *  [./reviews.wiki | Testimonials] from satisfied fossil users.
................................................................................
   109    110        designed to be readable, searchable, and extensible by people
   110    111        not yet born.
   111    112     *  A tutorial on [./branching.wiki | branching], what it means and how
   112    113        to do it using fossil.
   113    114     *  The [./selfcheck.wiki | automatic self-check] mechanism
   114    115        helps insure project integrity.
   115    116     *  Fossil contains a [./wikitheory.wiki | built-in wiki].
          117  +  *  An [./event.wiki | Event] is a special kind of wiki page associated
          118  +     with a point in time rather than a name.
   116    119     *  There is a
   117    120       [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | mailing list] (with publicly readable
   118    121        [http://www.mail-archive.com/fossil-users@lists.fossil-scm.org | archives]
   119    122        available for discussing fossil issues.
   120    123     *  [./stats.wiki | Performance statistics] taken from real-world projects
   121    124        hosted on fossil.
   122    125     *  How to [./shunning.wiki | delete content] from a fossil repository.

Changes to www/password.wiki.

    58     58   all login for that user.   Thus, to lock a user out of the system,
    59     59   one has only to set their password to an empty string, using either
    60     60   the web interface or direct SQL manipulation of the USER table.
    61     61   Note also that the password field is
    62     62   essentially ignored for the special users named "anonymous", "developer",
    63     63   "reader", and "nobody".  It is not possible to authenticate as users
    64     64   "developer", "reader", or "nobody" and the authentication protocol
    65         -for "anonymous" use one-time captchas not persistent passwords.
           65  +for "anonymous" uses one-time captchas not persistent passwords.
    66     66   
    67     67   <h2>Web Interface Authentication</h2>
    68     68   
    69     69   When a user logs into Fossil using the web interface, the login name
    70     70   and password are sent in the clear to the server.  The server then
    71     71   hashes the password and compares it against the value stored in USER.PW.
    72     72   If they match, the server sets a cookie on the client to record the
    73     73   login.  This cookie contains a large amount of high-quality randomness
    74         -and is thus impossible to guess.  The value of the cookie and the IP
           74  +and is thus intractable to guess.  The value of the cookie and the IP
    75     75   address of the client is stored in the USER.COOKIE and USER.IPADDR fields
    76     76   of the USER table on the server.  
    77     77   The USER.CEXPIRE field holds an expiration date
    78     78   for the cookie, encoded as a julian day number.  On all subsequent
    79     79   HTTP requests, the cookie value is matched against the USER table to 
    80     80   enable access to the repository.
    81     81   

Changes to www/qandc.wiki.

    61     61   fossil repository <a href="http://www.sqlite.org/docsrc/">here</a>,
    62     62   for example.
    63     63   Other projects are also adopting fossil.  But fossil does not yet have
    64     64   the massive user base of git or mercurial.
    65     65   </blockquote>
    66     66   
    67     67   <b>Fossil looks like the bug tracker that would be in your 
    68         -Linksys Router's administration screen.</p>
           68  +Linksys Router's administration screen.</b>
    69     69   
    70     70   <blockquote>
    71     71   <p>I take a pragmatic approach to software: form follows function.
    72     72   To me, it is more important to have a reliable, fast, efficient,
    73     73   enduring, and simple DVCS than one that looks pretty.</p>
    74     74   
    75     75   <p>On the other hand, if you have patches that improve the appearance

Changes to www/quickstart.wiki.

   230    230   
   231    231       <p>Or</b>
   232    232   
   233    233       <blockquote>
   234    234       <b>fossil ui</b> <i>repository-filename</i>
   235    235       </blockquote>
   236    236   
   237         -    <p>The difference between these two command is that <b>ui</b>
   238         -    attempts to automatically start your web browser pointing at the
   239         -    server whereas <b>server</b> does not.
          237  +    <p>The <b>ui</b> command is intended for accessing the web interface
          238  +    from a local desktop.  The <b>ui</b> command binds to the loopback IP
          239  +    address only (and is thus makes the web interface visible only on the
          240  +    local machine) and it automatically start your web browser pointing at the
          241  +    server.  For cross-machine collaboration, use the <b>server</b> command,
          242  +    which binds on all IP addresses and does not try to start a web browser.
   240    243       You can omit the <i>repository-filename</i> if you are within
   241         -    a checked-out local tree.  This server uses port 8080 by default
   242         -    but you can specify a different port using the <b>-port</b> command.</p>
          244  +    a checked-out local tree.  The <b>server</b> uses port 8080 by default
          245  +    but you can specify a different port using the <b>-port</b> option.</p>
   243    246   
   244    247       <p>Command-line servers like this are useful when two people want
   245    248       to share a repository on temporary or ad-hoc basis.  For a more
   246    249       permanent installation, you should use either the CGI server or the
   247    250       inetd server.
   248    251       <a name="cgiserver"></a>
   249    252       To use the CGI server, create a CGI script that

Changes to www/server.wiki.

    92     92   If you are using "inetd" to serve your repository, then you simply need to add "/usr/bin/stunnel" (perhaps on a different path, depending on your setup) before the command line to launch Fossil.
    93     93   </p>
    94     94   <p>
    95     95   At this stage, the standalone server (e.g. "fossil server") does not support SSL.
    96     96   </p>
    97     97   </blockquote>
    98     98   
    99         -<h2>Various security concerns with hosted repositories</h2><blockquote>
           99  +<h2>Various security concerns with hosted repositories</h2>
          100  +
          101  +<blockquote>
          102  +
   100    103   <p>
   101    104   There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):
   102    105   <ul>
   103    106   <li>Interception of the Fossil synchronization stream, thereby capturing data, and
   104         -</ul>Direct access to the Fossil repository on the server
          107  +<li>Direct access to the Fossil repository on the server
          108  +</ul>
   105    109   </p>
   106    110   <p>
   107    111   Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access.  The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure.  The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).
   108    112   </p>
   109    113   <p>
   110    114   As far as direct access to the repository, the same steps must be taken as for any other internet-facing data-store.  Access passwords to any disk-accessing accounts should be strong (and preferably changed from time to time).  However, the data in the repository itself are <i>not</i> encrypted (unless you save encrypted data yourself), and so the system administrators of your server will be able to access your data (as with any hosting service setup).  The only workaround in this case is to host the server yourself, in which case you will need to allocate resources to deal with administration issues.
   111    115   </p>
   112    116   
   113    117   </blockquote>
   114    118   
   115    119   </nowiki>

Changes to www/wikitheory.wiki.

     3      3   Fossil uses [/wiki_rules | wiki markup] for many things:
     4      4   
     5      5      *  Stand-alone wiki pages.
     6      6      *  Description and comments in [./bugtheory.wiki | bug reports].
     7      7      *  Check-in comments.
     8      8      *  [./embeddeddoc.wiki | Embedded documentation] files whose
     9      9         name ends in "wiki".
           10  +   *  [./event.wiki | Event descriptions].
    10     11   
    11     12   The [/wiki_rules | formatting rules] for fossil wiki
    12     13   are designed to be simple and intuitive.  The idea is that wiki provides
    13     14   paragraph breaks, numbered and bulleted lists, and hyperlinking for
    14     15   simple documents together with a safe subset of HTML for more complex
    15     16   formatting tasks.
    16     17