Fossil SCM
merge trunk
Commit
b68f65bb69a098a119f290e0857beb25a3c04f72
Parent
acbe8c41b1c7784…
63 files changed
+240
-331
+154
-103
+20
+19
-2
+8
-8
+1
-1
+55
+1
-1
+1
-1
+61
-22
+9
-1
+4
+403
-57
+5
+14
-8
+15
-2
+9
-5
+20
-6
+8
-2
+40
-7
+2
-1
+2
+31
-31
+2
-2
+4
+2
-1
+10
-6
+14
-6
+12
-1
+10
-2
+132
-27
+1063
-476
+1063
-476
+54
-16
+1
-1
+4
+16
+9
-3
+2
+63
-63
+22
-33
+3
-3
+166
-154
+41
-29
+11
-6
+2
-1
+21
-7
+229
-33
+36
-3
+5
-1
+2
-2
+2
-2
+3
-1
+3
-1
+3
-1
+29
-30
+8
+3
-3
+1
-1
+11
-1
+1
-1
+58
-12
~
autosetup/config.guess
~
autosetup/config.sub
~
src/add.c
~
src/allrepo.c
~
src/attach.c
~
src/bisect.c
~
src/blob.c
~
src/branch.c
~
src/browse.c
~
src/checkin.c
~
src/checkout.c
~
src/clone.c
~
src/comformat.c
~
src/config.h
~
src/db.c
~
src/descendants.c
~
src/diff.c
~
src/finfo.c
~
src/info.c
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/manifest.c
~
src/merge.c
~
src/merge3.c
~
src/mkindex.c
~
src/name.c
~
src/printf.c
~
src/rebuild.c
~
src/regexp.c
~
src/rss.c
~
src/shell.c
~
src/sqlite3.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/stash.c
~
src/stat.c
~
src/sync.c
~
src/tar.c
~
src/th.c
~
src/th_main.c
~
src/timeline.c
~
src/tkt.c
~
src/unicode.c
~
src/update.c
~
src/winhttp.c
~
src/xfer.c
~
src/zip.c
~
test/comment.test
~
test/merge_renames.test
~
test/release-checklist.wiki
~
win/Makefile.PellesCGMake
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
~
www/branching.wiki
~
www/changes.wiki
~
www/fileformat.wiki
~
www/pop.wiki
~
www/quotes.wiki
~
www/shunning.wiki
~
www/sync.wiki
+240
-331
| --- autosetup/config.guess | ||
| +++ autosetup/config.guess | ||
| @@ -1,44 +1,38 @@ | ||
| 1 | 1 | #! /bin/sh |
| 2 | 2 | # Attempt to guess a canonical system name. |
| 3 | -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
| 4 | -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
| 5 | -# Free Software Foundation, Inc. | |
| 3 | +# Copyright 1992-2014 Free Software Foundation, Inc. | |
| 6 | 4 | |
| 7 | -timestamp='2010-09-24' | |
| 5 | +timestamp='2014-03-23' | |
| 8 | 6 | |
| 9 | 7 | # This file is free software; you can redistribute it and/or modify it |
| 10 | 8 | # under the terms of the GNU General Public License as published by |
| 11 | -# the Free Software Foundation; either version 2 of the License, or | |
| 9 | +# the Free Software Foundation; either version 3 of the License, or | |
| 12 | 10 | # (at your option) any later version. |
| 13 | 11 | # |
| 14 | 12 | # This program is distributed in the hope that it will be useful, but |
| 15 | 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | 15 | # General Public License for more details. |
| 18 | 16 | # |
| 19 | 17 | # You should have received a copy of the GNU General Public License |
| 20 | -# along with this program; if not, write to the Free Software | |
| 21 | -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA | |
| 22 | -# 02110-1301, USA. | |
| 18 | +# along with this program; if not, see <http://www.gnu.org/licenses/>. | |
| 23 | 19 | # |
| 24 | 20 | # As a special exception to the GNU General Public License, if you |
| 25 | 21 | # distribute this file as part of a program that contains a |
| 26 | 22 | # configuration script generated by Autoconf, you may include it under |
| 27 | -# the same distribution terms that you use for the rest of that program. | |
| 28 | - | |
| 29 | - | |
| 30 | -# Originally written by Per Bothner. Please send patches (context | |
| 31 | -# diff format) to <[email protected]> and include a ChangeLog | |
| 32 | -# entry. | |
| 33 | -# | |
| 34 | -# This script attempts to guess a canonical system name similar to | |
| 35 | -# config.sub. If it succeeds, it prints the system name on stdout, and | |
| 36 | -# exits with 0. Otherwise, it exits with 1. | |
| 23 | +# the same distribution terms that you use for the rest of that | |
| 24 | +# program. This Exception is an additional permission under section 7 | |
| 25 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 26 | +# | |
| 27 | +# Originally written by Per Bothner. | |
| 37 | 28 | # |
| 38 | 29 | # You can get the latest version of this script from: |
| 39 | 30 | # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD |
| 31 | +# | |
| 32 | +# Please send patches with a ChangeLog entry to [email protected]. | |
| 33 | + | |
| 40 | 34 | |
| 41 | 35 | me=`echo "$0" | sed -e 's,.*/,,'` |
| 42 | 36 | |
| 43 | 37 | usage="\ |
| 44 | 38 | Usage: $0 [OPTION] |
| @@ -54,13 +48,11 @@ | ||
| 54 | 48 | |
| 55 | 49 | version="\ |
| 56 | 50 | GNU config.guess ($timestamp) |
| 57 | 51 | |
| 58 | 52 | Originally written by Per Bothner. |
| 59 | -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |
| 60 | -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free | |
| 61 | -Software Foundation, Inc. | |
| 53 | +Copyright 1992-2014 Free Software Foundation, Inc. | |
| 62 | 54 | |
| 63 | 55 | This is free software; see the source for copying conditions. There is NO |
| 64 | 56 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 65 | 57 | |
| 66 | 58 | help=" |
| @@ -90,11 +82,11 @@ | ||
| 90 | 82 | if test $# != 0; then |
| 91 | 83 | echo "$me: too many arguments$help" >&2 |
| 92 | 84 | exit 1 |
| 93 | 85 | fi |
| 94 | 86 | |
| 95 | -trap 'exit 1' HUP INT TERM | |
| 87 | +trap 'exit 1' 1 2 15 | |
| 96 | 88 | |
| 97 | 89 | # CC_FOR_BUILD -- compiler used by this script. Note that the use of a |
| 98 | 90 | # compiler to aid in system detection is discouraged as it requires |
| 99 | 91 | # temporary files to be created and, as you can see below, it is a |
| 100 | 92 | # headache to deal with in a portable fashion. |
| @@ -104,11 +96,11 @@ | ||
| 104 | 96 | |
| 105 | 97 | # Portable tmp directory creation inspired by the Autoconf team. |
| 106 | 98 | |
| 107 | 99 | set_cc_for_build=' |
| 108 | 100 | trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; |
| 109 | -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ; | |
| 101 | +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; | |
| 110 | 102 | : ${TMPDIR=/tmp} ; |
| 111 | 103 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || |
| 112 | 104 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || |
| 113 | 105 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || |
| 114 | 106 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; |
| @@ -137,17 +129,38 @@ | ||
| 137 | 129 | |
| 138 | 130 | UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown |
| 139 | 131 | UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown |
| 140 | 132 | UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown |
| 141 | 133 | UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown |
| 134 | + | |
| 135 | +case "${UNAME_SYSTEM}" in | |
| 136 | +Linux|GNU|GNU/*) | |
| 137 | + # If the system lacks a compiler, then just pick glibc. | |
| 138 | + # We could probably try harder. | |
| 139 | + LIBC=gnu | |
| 140 | + | |
| 141 | + eval $set_cc_for_build | |
| 142 | + cat <<-EOF > $dummy.c | |
| 143 | + #include <features.h> | |
| 144 | + #if defined(__UCLIBC__) | |
| 145 | + LIBC=uclibc | |
| 146 | + #elif defined(__dietlibc__) | |
| 147 | + LIBC=dietlibc | |
| 148 | + #else | |
| 149 | + LIBC=gnu | |
| 150 | + #endif | |
| 151 | + EOF | |
| 152 | + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` | |
| 153 | + ;; | |
| 154 | +esac | |
| 142 | 155 | |
| 143 | 156 | # Note: order is significant - the case branches are not exclusive. |
| 144 | 157 | |
| 145 | 158 | case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in |
| 146 | 159 | *:NetBSD:*:*) |
| 147 | 160 | # NetBSD (nbsd) targets should (where applicable) match one or |
| 148 | - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, | |
| 161 | + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, | |
| 149 | 162 | # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently |
| 150 | 163 | # switched to ELF, *-*-netbsd* would select the old |
| 151 | 164 | # object file format. This provides both forward |
| 152 | 165 | # compatibility and a consistent mechanism for selecting the |
| 153 | 166 | # object file format. |
| @@ -179,11 +192,11 @@ | ||
| 179 | 192 | else |
| 180 | 193 | os=netbsdelf |
| 181 | 194 | fi |
| 182 | 195 | ;; |
| 183 | 196 | *) |
| 184 | - os=netbsd | |
| 197 | + os=netbsd | |
| 185 | 198 | ;; |
| 186 | 199 | esac |
| 187 | 200 | # The OS release |
| 188 | 201 | # Debian GNU/NetBSD machines have a different userland, and |
| 189 | 202 | # thus, need a distinct triplet. However, they do not need |
| @@ -200,10 +213,14 @@ | ||
| 200 | 213 | # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: |
| 201 | 214 | # contains redundant information, the shorter form: |
| 202 | 215 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. |
| 203 | 216 | echo "${machine}-${os}${release}" |
| 204 | 217 | exit ;; |
| 218 | + *:Bitrig:*:*) | |
| 219 | + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` | |
| 220 | + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} | |
| 221 | + exit ;; | |
| 205 | 222 | *:OpenBSD:*:*) |
| 206 | 223 | UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` |
| 207 | 224 | echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} |
| 208 | 225 | exit ;; |
| 209 | 226 | *:ekkoBSD:*:*) |
| @@ -222,11 +239,11 @@ | ||
| 222 | 239 | case $UNAME_RELEASE in |
| 223 | 240 | *4.0) |
| 224 | 241 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` |
| 225 | 242 | ;; |
| 226 | 243 | *5.*) |
| 227 | - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` | |
| 244 | + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` | |
| 228 | 245 | ;; |
| 229 | 246 | esac |
| 230 | 247 | # According to Compaq, /usr/sbin/psrinfo has been available on |
| 231 | 248 | # OSF/1 and Tru64 systems produced since 1995. I hope that |
| 232 | 249 | # covers most systems running today. This code pipes the CPU |
| @@ -268,11 +285,14 @@ | ||
| 268 | 285 | # A Vn.n version is a released version. |
| 269 | 286 | # A Tn.n version is a released field test version. |
| 270 | 287 | # A Xn.n version is an unreleased experimental baselevel. |
| 271 | 288 | # 1.2 uses "1.2" for uname -r. |
| 272 | 289 | echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 273 | - exit ;; | |
| 290 | + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. | |
| 291 | + exitcode=$? | |
| 292 | + trap '' 0 | |
| 293 | + exit $exitcode ;; | |
| 274 | 294 | Alpha\ *:Windows_NT*:*) |
| 275 | 295 | # How do we know it's Interix rather than the generic POSIX subsystem? |
| 276 | 296 | # Should we change UNAME_MACHINE based on the output of uname instead |
| 277 | 297 | # of the specific Alpha model? |
| 278 | 298 | echo alpha-pc-interix |
| @@ -294,16 +314,16 @@ | ||
| 294 | 314 | exit ;; |
| 295 | 315 | *:z/VM:*:*) |
| 296 | 316 | echo s390-ibm-zvmoe |
| 297 | 317 | exit ;; |
| 298 | 318 | *:OS400:*:*) |
| 299 | - echo powerpc-ibm-os400 | |
| 319 | + echo powerpc-ibm-os400 | |
| 300 | 320 | exit ;; |
| 301 | 321 | arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) |
| 302 | 322 | echo arm-acorn-riscix${UNAME_RELEASE} |
| 303 | 323 | exit ;; |
| 304 | - arm:riscos:*:*|arm:RISCOS:*:*) | |
| 324 | + arm*:riscos:*:*|arm*:RISCOS:*:*) | |
| 305 | 325 | echo arm-unknown-riscos |
| 306 | 326 | exit ;; |
| 307 | 327 | SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) |
| 308 | 328 | echo hppa1.1-hitachi-hiuxmpp |
| 309 | 329 | exit ;; |
| @@ -393,27 +413,27 @@ | ||
| 393 | 413 | # to the lowercase version "mint" (or "freemint"). Finally |
| 394 | 414 | # the system name "TOS" denotes a system which is actually not |
| 395 | 415 | # MiNT. But MiNT is downward compatible to TOS, so this should |
| 396 | 416 | # be no problem. |
| 397 | 417 | atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) |
| 398 | - echo m68k-atari-mint${UNAME_RELEASE} | |
| 418 | + echo m68k-atari-mint${UNAME_RELEASE} | |
| 399 | 419 | exit ;; |
| 400 | 420 | atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) |
| 401 | 421 | echo m68k-atari-mint${UNAME_RELEASE} |
| 402 | - exit ;; | |
| 422 | + exit ;; | |
| 403 | 423 | *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) |
| 404 | - echo m68k-atari-mint${UNAME_RELEASE} | |
| 424 | + echo m68k-atari-mint${UNAME_RELEASE} | |
| 405 | 425 | exit ;; |
| 406 | 426 | milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) |
| 407 | - echo m68k-milan-mint${UNAME_RELEASE} | |
| 408 | - exit ;; | |
| 427 | + echo m68k-milan-mint${UNAME_RELEASE} | |
| 428 | + exit ;; | |
| 409 | 429 | hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) |
| 410 | - echo m68k-hades-mint${UNAME_RELEASE} | |
| 411 | - exit ;; | |
| 430 | + echo m68k-hades-mint${UNAME_RELEASE} | |
| 431 | + exit ;; | |
| 412 | 432 | *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) |
| 413 | - echo m68k-unknown-mint${UNAME_RELEASE} | |
| 414 | - exit ;; | |
| 433 | + echo m68k-unknown-mint${UNAME_RELEASE} | |
| 434 | + exit ;; | |
| 415 | 435 | m68k:machten:*:*) |
| 416 | 436 | echo m68k-apple-machten${UNAME_RELEASE} |
| 417 | 437 | exit ;; |
| 418 | 438 | powerpc:machten:*:*) |
| 419 | 439 | echo powerpc-apple-machten${UNAME_RELEASE} |
| @@ -479,12 +499,12 @@ | ||
| 479 | 499 | exit ;; |
| 480 | 500 | m88k:*:3*:R3*) |
| 481 | 501 | echo m88k-motorola-sysv3 |
| 482 | 502 | exit ;; |
| 483 | 503 | AViiON:dgux:*:*) |
| 484 | - # DG/UX returns AViiON for all architectures | |
| 485 | - UNAME_PROCESSOR=`/usr/bin/uname -p` | |
| 504 | + # DG/UX returns AViiON for all architectures | |
| 505 | + UNAME_PROCESSOR=`/usr/bin/uname -p` | |
| 486 | 506 | if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] |
| 487 | 507 | then |
| 488 | 508 | if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ |
| 489 | 509 | [ ${TARGET_BINARY_INTERFACE}x = x ] |
| 490 | 510 | then |
| @@ -493,11 +513,11 @@ | ||
| 493 | 513 | echo m88k-dg-dguxbcs${UNAME_RELEASE} |
| 494 | 514 | fi |
| 495 | 515 | else |
| 496 | 516 | echo i586-dg-dgux${UNAME_RELEASE} |
| 497 | 517 | fi |
| 498 | - exit ;; | |
| 518 | + exit ;; | |
| 499 | 519 | M88*:DolphinOS:*:*) # DolphinOS (SVR3) |
| 500 | 520 | echo m88k-dolphin-sysv3 |
| 501 | 521 | exit ;; |
| 502 | 522 | M88*:*:R3*:*) |
| 503 | 523 | # Delta 88k system running SVR3 |
| @@ -593,56 +613,56 @@ | ||
| 593 | 613 | 9000/31? ) HP_ARCH=m68000 ;; |
| 594 | 614 | 9000/[34]?? ) HP_ARCH=m68k ;; |
| 595 | 615 | 9000/[678][0-9][0-9]) |
| 596 | 616 | if [ -x /usr/bin/getconf ]; then |
| 597 | 617 | sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` |
| 598 | - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` | |
| 599 | - case "${sc_cpu_version}" in | |
| 600 | - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 | |
| 601 | - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 | |
| 602 | - 532) # CPU_PA_RISC2_0 | |
| 603 | - case "${sc_kernel_bits}" in | |
| 604 | - 32) HP_ARCH="hppa2.0n" ;; | |
| 605 | - 64) HP_ARCH="hppa2.0w" ;; | |
| 618 | + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` | |
| 619 | + case "${sc_cpu_version}" in | |
| 620 | + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 | |
| 621 | + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 | |
| 622 | + 532) # CPU_PA_RISC2_0 | |
| 623 | + case "${sc_kernel_bits}" in | |
| 624 | + 32) HP_ARCH="hppa2.0n" ;; | |
| 625 | + 64) HP_ARCH="hppa2.0w" ;; | |
| 606 | 626 | '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 |
| 607 | - esac ;; | |
| 608 | - esac | |
| 627 | + esac ;; | |
| 628 | + esac | |
| 609 | 629 | fi |
| 610 | 630 | if [ "${HP_ARCH}" = "" ]; then |
| 611 | 631 | eval $set_cc_for_build |
| 612 | - sed 's/^ //' << EOF >$dummy.c | |
| 613 | - | |
| 614 | - #define _HPUX_SOURCE | |
| 615 | - #include <stdlib.h> | |
| 616 | - #include <unistd.h> | |
| 617 | - | |
| 618 | - int main () | |
| 619 | - { | |
| 620 | - #if defined(_SC_KERNEL_BITS) | |
| 621 | - long bits = sysconf(_SC_KERNEL_BITS); | |
| 622 | - #endif | |
| 623 | - long cpu = sysconf (_SC_CPU_VERSION); | |
| 624 | - | |
| 625 | - switch (cpu) | |
| 626 | - { | |
| 627 | - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; | |
| 628 | - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; | |
| 629 | - case CPU_PA_RISC2_0: | |
| 630 | - #if defined(_SC_KERNEL_BITS) | |
| 631 | - switch (bits) | |
| 632 | - { | |
| 633 | - case 64: puts ("hppa2.0w"); break; | |
| 634 | - case 32: puts ("hppa2.0n"); break; | |
| 635 | - default: puts ("hppa2.0"); break; | |
| 636 | - } break; | |
| 637 | - #else /* !defined(_SC_KERNEL_BITS) */ | |
| 638 | - puts ("hppa2.0"); break; | |
| 639 | - #endif | |
| 640 | - default: puts ("hppa1.0"); break; | |
| 641 | - } | |
| 642 | - exit (0); | |
| 643 | - } | |
| 632 | + sed 's/^ //' << EOF >$dummy.c | |
| 633 | + | |
| 634 | + #define _HPUX_SOURCE | |
| 635 | + #include <stdlib.h> | |
| 636 | + #include <unistd.h> | |
| 637 | + | |
| 638 | + int main () | |
| 639 | + { | |
| 640 | + #if defined(_SC_KERNEL_BITS) | |
| 641 | + long bits = sysconf(_SC_KERNEL_BITS); | |
| 642 | + #endif | |
| 643 | + long cpu = sysconf (_SC_CPU_VERSION); | |
| 644 | + | |
| 645 | + switch (cpu) | |
| 646 | + { | |
| 647 | + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; | |
| 648 | + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; | |
| 649 | + case CPU_PA_RISC2_0: | |
| 650 | + #if defined(_SC_KERNEL_BITS) | |
| 651 | + switch (bits) | |
| 652 | + { | |
| 653 | + case 64: puts ("hppa2.0w"); break; | |
| 654 | + case 32: puts ("hppa2.0n"); break; | |
| 655 | + default: puts ("hppa2.0"); break; | |
| 656 | + } break; | |
| 657 | + #else /* !defined(_SC_KERNEL_BITS) */ | |
| 658 | + puts ("hppa2.0"); break; | |
| 659 | + #endif | |
| 660 | + default: puts ("hppa1.0"); break; | |
| 661 | + } | |
| 662 | + exit (0); | |
| 663 | + } | |
| 644 | 664 | EOF |
| 645 | 665 | (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` |
| 646 | 666 | test -z "$HP_ARCH" && HP_ARCH=hppa |
| 647 | 667 | fi ;; |
| 648 | 668 | esac |
| @@ -729,26 +749,26 @@ | ||
| 729 | 749 | parisc*:Lites*:*:*) |
| 730 | 750 | echo hppa1.1-hp-lites |
| 731 | 751 | exit ;; |
| 732 | 752 | C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) |
| 733 | 753 | echo c1-convex-bsd |
| 734 | - exit ;; | |
| 754 | + exit ;; | |
| 735 | 755 | C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) |
| 736 | 756 | if getsysinfo -f scalar_acc |
| 737 | 757 | then echo c32-convex-bsd |
| 738 | 758 | else echo c2-convex-bsd |
| 739 | 759 | fi |
| 740 | - exit ;; | |
| 760 | + exit ;; | |
| 741 | 761 | C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) |
| 742 | 762 | echo c34-convex-bsd |
| 743 | - exit ;; | |
| 763 | + exit ;; | |
| 744 | 764 | C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) |
| 745 | 765 | echo c38-convex-bsd |
| 746 | - exit ;; | |
| 766 | + exit ;; | |
| 747 | 767 | C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) |
| 748 | 768 | echo c4-convex-bsd |
| 749 | - exit ;; | |
| 769 | + exit ;; | |
| 750 | 770 | CRAY*Y-MP:*:*:*) |
| 751 | 771 | echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 752 | 772 | exit ;; |
| 753 | 773 | CRAY*[A-Z]90:*:*:*) |
| 754 | 774 | echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ |
| @@ -768,18 +788,18 @@ | ||
| 768 | 788 | *:UNICOS/mp:*:*) |
| 769 | 789 | echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 770 | 790 | exit ;; |
| 771 | 791 | F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) |
| 772 | 792 | FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 773 | - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` | |
| 774 | - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` | |
| 775 | - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" | |
| 776 | - exit ;; | |
| 793 | + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` | |
| 794 | + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` | |
| 795 | + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" | |
| 796 | + exit ;; | |
| 777 | 797 | 5000:UNIX_System_V:4.*:*) |
| 778 | - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` | |
| 779 | - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` | |
| 780 | - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" | |
| 798 | + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` | |
| 799 | + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` | |
| 800 | + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" | |
| 781 | 801 | exit ;; |
| 782 | 802 | i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) |
| 783 | 803 | echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} |
| 784 | 804 | exit ;; |
| 785 | 805 | sparc*:BSD/OS:*:*) |
| @@ -787,37 +807,39 @@ | ||
| 787 | 807 | exit ;; |
| 788 | 808 | *:BSD/OS:*:*) |
| 789 | 809 | echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} |
| 790 | 810 | exit ;; |
| 791 | 811 | *:FreeBSD:*:*) |
| 792 | - case ${UNAME_MACHINE} in | |
| 793 | - pc98) | |
| 794 | - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; | |
| 812 | + UNAME_PROCESSOR=`/usr/bin/uname -p` | |
| 813 | + case ${UNAME_PROCESSOR} in | |
| 795 | 814 | amd64) |
| 796 | 815 | echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 797 | 816 | *) |
| 798 | - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; | |
| 817 | + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; | |
| 799 | 818 | esac |
| 800 | 819 | exit ;; |
| 801 | 820 | i*:CYGWIN*:*) |
| 802 | 821 | echo ${UNAME_MACHINE}-pc-cygwin |
| 803 | 822 | exit ;; |
| 823 | + *:MINGW64*:*) | |
| 824 | + echo ${UNAME_MACHINE}-pc-mingw64 | |
| 825 | + exit ;; | |
| 804 | 826 | *:MINGW*:*) |
| 805 | 827 | echo ${UNAME_MACHINE}-pc-mingw32 |
| 806 | 828 | exit ;; |
| 807 | - i*:MSYS*:*) | |
| 808 | - echo ${UNAME_MACHINE}-pc-msys | |
| 809 | - exit ;; | |
| 829 | + *:MSYS*:*) | |
| 830 | + echo ${UNAME_MACHINE}-pc-msys | |
| 831 | + exit ;; | |
| 810 | 832 | i*:windows32*:*) |
| 811 | - # uname -m includes "-pc" on this system. | |
| 812 | - echo ${UNAME_MACHINE}-mingw32 | |
| 833 | + # uname -m includes "-pc" on this system. | |
| 834 | + echo ${UNAME_MACHINE}-mingw32 | |
| 813 | 835 | exit ;; |
| 814 | 836 | i*:PW*:*) |
| 815 | 837 | echo ${UNAME_MACHINE}-pc-pw32 |
| 816 | 838 | exit ;; |
| 817 | 839 | *:Interix*:*) |
| 818 | - case ${UNAME_MACHINE} in | |
| 840 | + case ${UNAME_MACHINE} in | |
| 819 | 841 | x86) |
| 820 | 842 | echo i586-pc-interix${UNAME_RELEASE} |
| 821 | 843 | exit ;; |
| 822 | 844 | authenticamd | genuineintel | EM64T) |
| 823 | 845 | echo x86_64-unknown-interix${UNAME_RELEASE} |
| @@ -850,74 +872,85 @@ | ||
| 850 | 872 | prep*:SunOS:5.*:*) |
| 851 | 873 | echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` |
| 852 | 874 | exit ;; |
| 853 | 875 | *:GNU:*:*) |
| 854 | 876 | # the GNU system |
| 855 | - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` | |
| 877 | + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` | |
| 856 | 878 | exit ;; |
| 857 | 879 | *:GNU/*:*:*) |
| 858 | 880 | # other systems with GNU libc and userland |
| 859 | - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu | |
| 881 | + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} | |
| 860 | 882 | exit ;; |
| 861 | 883 | i*86:Minix:*:*) |
| 862 | 884 | echo ${UNAME_MACHINE}-pc-minix |
| 863 | 885 | exit ;; |
| 886 | + aarch64:Linux:*:*) | |
| 887 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 888 | + exit ;; | |
| 889 | + aarch64_be:Linux:*:*) | |
| 890 | + UNAME_MACHINE=aarch64_be | |
| 891 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 892 | + exit ;; | |
| 864 | 893 | alpha:Linux:*:*) |
| 865 | 894 | case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in |
| 866 | 895 | EV5) UNAME_MACHINE=alphaev5 ;; |
| 867 | 896 | EV56) UNAME_MACHINE=alphaev56 ;; |
| 868 | 897 | PCA56) UNAME_MACHINE=alphapca56 ;; |
| 869 | 898 | PCA57) UNAME_MACHINE=alphapca56 ;; |
| 870 | 899 | EV6) UNAME_MACHINE=alphaev6 ;; |
| 871 | 900 | EV67) UNAME_MACHINE=alphaev67 ;; |
| 872 | 901 | EV68*) UNAME_MACHINE=alphaev68 ;; |
| 873 | - esac | |
| 902 | + esac | |
| 874 | 903 | objdump --private-headers /bin/sh | grep -q ld.so.1 |
| 875 | - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi | |
| 876 | - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} | |
| 904 | + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi | |
| 905 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 906 | + exit ;; | |
| 907 | + arc:Linux:*:* | arceb:Linux:*:*) | |
| 908 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 877 | 909 | exit ;; |
| 878 | 910 | arm*:Linux:*:*) |
| 879 | 911 | eval $set_cc_for_build |
| 880 | 912 | if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
| 881 | 913 | | grep -q __ARM_EABI__ |
| 882 | 914 | then |
| 883 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 915 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 884 | 916 | else |
| 885 | - echo ${UNAME_MACHINE}-unknown-linux-gnueabi | |
| 917 | + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | |
| 918 | + | grep -q __ARM_PCS_VFP | |
| 919 | + then | |
| 920 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi | |
| 921 | + else | |
| 922 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf | |
| 923 | + fi | |
| 886 | 924 | fi |
| 887 | 925 | exit ;; |
| 888 | 926 | avr32*:Linux:*:*) |
| 889 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 927 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 890 | 928 | exit ;; |
| 891 | 929 | cris:Linux:*:*) |
| 892 | - echo cris-axis-linux-gnu | |
| 930 | + echo ${UNAME_MACHINE}-axis-linux-${LIBC} | |
| 893 | 931 | exit ;; |
| 894 | 932 | crisv32:Linux:*:*) |
| 895 | - echo crisv32-axis-linux-gnu | |
| 933 | + echo ${UNAME_MACHINE}-axis-linux-${LIBC} | |
| 896 | 934 | exit ;; |
| 897 | 935 | frv:Linux:*:*) |
| 898 | - echo frv-unknown-linux-gnu | |
| 936 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 937 | + exit ;; | |
| 938 | + hexagon:Linux:*:*) | |
| 939 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 899 | 940 | exit ;; |
| 900 | 941 | i*86:Linux:*:*) |
| 901 | - LIBC=gnu | |
| 902 | - eval $set_cc_for_build | |
| 903 | - sed 's/^ //' << EOF >$dummy.c | |
| 904 | - #ifdef __dietlibc__ | |
| 905 | - LIBC=dietlibc | |
| 906 | - #endif | |
| 907 | -EOF | |
| 908 | - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` | |
| 909 | - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" | |
| 942 | + echo ${UNAME_MACHINE}-pc-linux-${LIBC} | |
| 910 | 943 | exit ;; |
| 911 | 944 | ia64:Linux:*:*) |
| 912 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 945 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 913 | 946 | exit ;; |
| 914 | 947 | m32r*:Linux:*:*) |
| 915 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 948 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 916 | 949 | exit ;; |
| 917 | 950 | m68*:Linux:*:*) |
| 918 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 951 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 919 | 952 | exit ;; |
| 920 | 953 | mips:Linux:*:* | mips64:Linux:*:*) |
| 921 | 954 | eval $set_cc_for_build |
| 922 | 955 | sed 's/^ //' << EOF >$dummy.c |
| 923 | 956 | #undef CPU |
| @@ -932,71 +965,80 @@ | ||
| 932 | 965 | CPU= |
| 933 | 966 | #endif |
| 934 | 967 | #endif |
| 935 | 968 | EOF |
| 936 | 969 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` |
| 937 | - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } | |
| 970 | + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } | |
| 938 | 971 | ;; |
| 939 | - or32:Linux:*:*) | |
| 940 | - echo or32-unknown-linux-gnu | |
| 972 | + openrisc*:Linux:*:*) | |
| 973 | + echo or1k-unknown-linux-${LIBC} | |
| 974 | + exit ;; | |
| 975 | + or32:Linux:*:* | or1k*:Linux:*:*) | |
| 976 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 941 | 977 | exit ;; |
| 942 | 978 | padre:Linux:*:*) |
| 943 | - echo sparc-unknown-linux-gnu | |
| 979 | + echo sparc-unknown-linux-${LIBC} | |
| 944 | 980 | exit ;; |
| 945 | 981 | parisc64:Linux:*:* | hppa64:Linux:*:*) |
| 946 | - echo hppa64-unknown-linux-gnu | |
| 982 | + echo hppa64-unknown-linux-${LIBC} | |
| 947 | 983 | exit ;; |
| 948 | 984 | parisc:Linux:*:* | hppa:Linux:*:*) |
| 949 | 985 | # Look for CPU level |
| 950 | 986 | case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in |
| 951 | - PA7*) echo hppa1.1-unknown-linux-gnu ;; | |
| 952 | - PA8*) echo hppa2.0-unknown-linux-gnu ;; | |
| 953 | - *) echo hppa-unknown-linux-gnu ;; | |
| 987 | + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; | |
| 988 | + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; | |
| 989 | + *) echo hppa-unknown-linux-${LIBC} ;; | |
| 954 | 990 | esac |
| 955 | 991 | exit ;; |
| 956 | 992 | ppc64:Linux:*:*) |
| 957 | - echo powerpc64-unknown-linux-gnu | |
| 993 | + echo powerpc64-unknown-linux-${LIBC} | |
| 958 | 994 | exit ;; |
| 959 | 995 | ppc:Linux:*:*) |
| 960 | - echo powerpc-unknown-linux-gnu | |
| 996 | + echo powerpc-unknown-linux-${LIBC} | |
| 997 | + exit ;; | |
| 998 | + ppc64le:Linux:*:*) | |
| 999 | + echo powerpc64le-unknown-linux-${LIBC} | |
| 1000 | + exit ;; | |
| 1001 | + ppcle:Linux:*:*) | |
| 1002 | + echo powerpcle-unknown-linux-${LIBC} | |
| 961 | 1003 | exit ;; |
| 962 | 1004 | s390:Linux:*:* | s390x:Linux:*:*) |
| 963 | - echo ${UNAME_MACHINE}-ibm-linux | |
| 1005 | + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} | |
| 964 | 1006 | exit ;; |
| 965 | 1007 | sh64*:Linux:*:*) |
| 966 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 1008 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 967 | 1009 | exit ;; |
| 968 | 1010 | sh*:Linux:*:*) |
| 969 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 1011 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 970 | 1012 | exit ;; |
| 971 | 1013 | sparc:Linux:*:* | sparc64:Linux:*:*) |
| 972 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 1014 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 973 | 1015 | exit ;; |
| 974 | 1016 | tile*:Linux:*:*) |
| 975 | - echo ${UNAME_MACHINE}-tilera-linux-gnu | |
| 1017 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 976 | 1018 | exit ;; |
| 977 | 1019 | vax:Linux:*:*) |
| 978 | - echo ${UNAME_MACHINE}-dec-linux-gnu | |
| 1020 | + echo ${UNAME_MACHINE}-dec-linux-${LIBC} | |
| 979 | 1021 | exit ;; |
| 980 | 1022 | x86_64:Linux:*:*) |
| 981 | - echo x86_64-unknown-linux-gnu | |
| 1023 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 982 | 1024 | exit ;; |
| 983 | 1025 | xtensa*:Linux:*:*) |
| 984 | - echo ${UNAME_MACHINE}-unknown-linux-gnu | |
| 1026 | + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} | |
| 985 | 1027 | exit ;; |
| 986 | 1028 | i*86:DYNIX/ptx:4*:*) |
| 987 | 1029 | # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. |
| 988 | 1030 | # earlier versions are messed up and put the nodename in both |
| 989 | 1031 | # sysname and nodename. |
| 990 | 1032 | echo i386-sequent-sysv4 |
| 991 | 1033 | exit ;; |
| 992 | 1034 | i*86:UNIX_SV:4.2MP:2.*) |
| 993 | - # Unixware is an offshoot of SVR4, but it has its own version | |
| 994 | - # number series starting with 2... | |
| 995 | - # I am not positive that other SVR4 systems won't match this, | |
| 1035 | + # Unixware is an offshoot of SVR4, but it has its own version | |
| 1036 | + # number series starting with 2... | |
| 1037 | + # I am not positive that other SVR4 systems won't match this, | |
| 996 | 1038 | # I just have to hope. -- rms. |
| 997 | - # Use sysv4.2uw... so that sysv4* matches it. | |
| 1039 | + # Use sysv4.2uw... so that sysv4* matches it. | |
| 998 | 1040 | echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} |
| 999 | 1041 | exit ;; |
| 1000 | 1042 | i*86:OS/2:*:*) |
| 1001 | 1043 | # If we were able to find `uname', then EMX Unix compatibility |
| 1002 | 1044 | # is probably installed. |
| @@ -1024,11 +1066,11 @@ | ||
| 1024 | 1066 | else |
| 1025 | 1067 | echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} |
| 1026 | 1068 | fi |
| 1027 | 1069 | exit ;; |
| 1028 | 1070 | i*86:*:5:[678]*) |
| 1029 | - # UnixWare 7.x, OpenUNIX and OpenServer 6. | |
| 1071 | + # UnixWare 7.x, OpenUNIX and OpenServer 6. | |
| 1030 | 1072 | case `/bin/uname -X | grep "^Machine"` in |
| 1031 | 1073 | *486*) UNAME_MACHINE=i486 ;; |
| 1032 | 1074 | *Pentium) UNAME_MACHINE=i586 ;; |
| 1033 | 1075 | *Pent*|*Celeron) UNAME_MACHINE=i686 ;; |
| 1034 | 1076 | esac |
| @@ -1052,17 +1094,17 @@ | ||
| 1052 | 1094 | echo ${UNAME_MACHINE}-pc-sysv32 |
| 1053 | 1095 | fi |
| 1054 | 1096 | exit ;; |
| 1055 | 1097 | pc:*:*:*) |
| 1056 | 1098 | # Left here for compatibility: |
| 1057 | - # uname -m prints for DJGPP always 'pc', but it prints nothing about | |
| 1058 | - # the processor, so we play safe by assuming i586. | |
| 1099 | + # uname -m prints for DJGPP always 'pc', but it prints nothing about | |
| 1100 | + # the processor, so we play safe by assuming i586. | |
| 1059 | 1101 | # Note: whatever this is, it MUST be the same as what config.sub |
| 1060 | 1102 | # prints for the "djgpp" host, or else GDB configury will decide that |
| 1061 | 1103 | # this is a cross-build. |
| 1062 | 1104 | echo i586-pc-msdosdjgpp |
| 1063 | - exit ;; | |
| 1105 | + exit ;; | |
| 1064 | 1106 | Intel:Mach:3*:*) |
| 1065 | 1107 | echo i386-pc-mach3 |
| 1066 | 1108 | exit ;; |
| 1067 | 1109 | paragon:*:*:*) |
| 1068 | 1110 | echo i860-intel-osf1 |
| @@ -1093,12 +1135,12 @@ | ||
| 1093 | 1135 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| 1094 | 1136 | && { echo i486-ncr-sysv4.3${OS_REL}; exit; } |
| 1095 | 1137 | /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ |
| 1096 | 1138 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; |
| 1097 | 1139 | 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) |
| 1098 | - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ | |
| 1099 | - && { echo i486-ncr-sysv4; exit; } ;; | |
| 1140 | + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ | |
| 1141 | + && { echo i486-ncr-sysv4; exit; } ;; | |
| 1100 | 1142 | NCR*:*:4.2:* | MPRAS*:*:4.2:*) |
| 1101 | 1143 | OS_REL='.3' |
| 1102 | 1144 | test -r /etc/.relid \ |
| 1103 | 1145 | && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` |
| 1104 | 1146 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| @@ -1137,14 +1179,14 @@ | ||
| 1137 | 1179 | echo ${UNAME_MACHINE}-sni-sysv4 |
| 1138 | 1180 | else |
| 1139 | 1181 | echo ns32k-sni-sysv |
| 1140 | 1182 | fi |
| 1141 | 1183 | exit ;; |
| 1142 | - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort | |
| 1143 | - # says <[email protected]> | |
| 1144 | - echo i586-unisys-sysv4 | |
| 1145 | - exit ;; | |
| 1184 | + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort | |
| 1185 | + # says <[email protected]> | |
| 1186 | + echo i586-unisys-sysv4 | |
| 1187 | + exit ;; | |
| 1146 | 1188 | *:UNIX_System_V:4*:FTX*) |
| 1147 | 1189 | # From Gerald Hewes <[email protected]>. |
| 1148 | 1190 | # How about differentiating between stratus architectures? -djm |
| 1149 | 1191 | echo hppa1.1-stratus-sysv4 |
| 1150 | 1192 | exit ;; |
| @@ -1166,15 +1208,15 @@ | ||
| 1166 | 1208 | news*:NEWS-OS:6*:*) |
| 1167 | 1209 | echo mips-sony-newsos6 |
| 1168 | 1210 | exit ;; |
| 1169 | 1211 | R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) |
| 1170 | 1212 | if [ -d /usr/nec ]; then |
| 1171 | - echo mips-nec-sysv${UNAME_RELEASE} | |
| 1213 | + echo mips-nec-sysv${UNAME_RELEASE} | |
| 1172 | 1214 | else |
| 1173 | - echo mips-unknown-sysv${UNAME_RELEASE} | |
| 1215 | + echo mips-unknown-sysv${UNAME_RELEASE} | |
| 1174 | 1216 | fi |
| 1175 | - exit ;; | |
| 1217 | + exit ;; | |
| 1176 | 1218 | BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. |
| 1177 | 1219 | echo powerpc-be-beos |
| 1178 | 1220 | exit ;; |
| 1179 | 1221 | BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. |
| 1180 | 1222 | echo powerpc-apple-beos |
| @@ -1183,10 +1225,13 @@ | ||
| 1183 | 1225 | echo i586-pc-beos |
| 1184 | 1226 | exit ;; |
| 1185 | 1227 | BePC:Haiku:*:*) # Haiku running on Intel PC compatible. |
| 1186 | 1228 | echo i586-pc-haiku |
| 1187 | 1229 | exit ;; |
| 1230 | + x86_64:Haiku:*:*) | |
| 1231 | + echo x86_64-unknown-haiku | |
| 1232 | + exit ;; | |
| 1188 | 1233 | SX-4:SUPER-UX:*:*) |
| 1189 | 1234 | echo sx4-nec-superux${UNAME_RELEASE} |
| 1190 | 1235 | exit ;; |
| 1191 | 1236 | SX-5:SUPER-UX:*:*) |
| 1192 | 1237 | echo sx5-nec-superux${UNAME_RELEASE} |
| @@ -1209,23 +1254,35 @@ | ||
| 1209 | 1254 | *:Rhapsody:*:*) |
| 1210 | 1255 | echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} |
| 1211 | 1256 | exit ;; |
| 1212 | 1257 | *:Darwin:*:*) |
| 1213 | 1258 | UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown |
| 1214 | - case $UNAME_PROCESSOR in | |
| 1215 | - i386) | |
| 1216 | - eval $set_cc_for_build | |
| 1217 | - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then | |
| 1218 | - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ | |
| 1219 | - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ | |
| 1220 | - grep IS_64BIT_ARCH >/dev/null | |
| 1221 | - then | |
| 1222 | - UNAME_PROCESSOR="x86_64" | |
| 1223 | - fi | |
| 1224 | - fi ;; | |
| 1225 | - unknown) UNAME_PROCESSOR=powerpc ;; | |
| 1226 | - esac | |
| 1259 | + eval $set_cc_for_build | |
| 1260 | + if test "$UNAME_PROCESSOR" = unknown ; then | |
| 1261 | + UNAME_PROCESSOR=powerpc | |
| 1262 | + fi | |
| 1263 | + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then | |
| 1264 | + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then | |
| 1265 | + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ | |
| 1266 | + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ | |
| 1267 | + grep IS_64BIT_ARCH >/dev/null | |
| 1268 | + then | |
| 1269 | + case $UNAME_PROCESSOR in | |
| 1270 | + i386) UNAME_PROCESSOR=x86_64 ;; | |
| 1271 | + powerpc) UNAME_PROCESSOR=powerpc64 ;; | |
| 1272 | + esac | |
| 1273 | + fi | |
| 1274 | + fi | |
| 1275 | + elif test "$UNAME_PROCESSOR" = i386 ; then | |
| 1276 | + # Avoid executing cc on OS X 10.9, as it ships with a stub | |
| 1277 | + # that puts up a graphical alert prompting to install | |
| 1278 | + # developer tools. Any system running Mac OS X 10.7 or | |
| 1279 | + # later (Darwin 11 and later) is required to have a 64-bit | |
| 1280 | + # processor. This is not true of the ARM version of Darwin | |
| 1281 | + # that Apple uses in portable devices. | |
| 1282 | + UNAME_PROCESSOR=x86_64 | |
| 1283 | + fi | |
| 1227 | 1284 | echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} |
| 1228 | 1285 | exit ;; |
| 1229 | 1286 | *:procnto*:*:* | *:QNX:[0123456789]*:*) |
| 1230 | 1287 | UNAME_PROCESSOR=`uname -p` |
| 1231 | 1288 | if test "$UNAME_PROCESSOR" = "x86"; then |
| @@ -1238,11 +1295,11 @@ | ||
| 1238 | 1295 | echo i386-pc-qnx |
| 1239 | 1296 | exit ;; |
| 1240 | 1297 | NEO-?:NONSTOP_KERNEL:*:*) |
| 1241 | 1298 | echo neo-tandem-nsk${UNAME_RELEASE} |
| 1242 | 1299 | exit ;; |
| 1243 | - NSE-?:NONSTOP_KERNEL:*:*) | |
| 1300 | + NSE-*:NONSTOP_KERNEL:*:*) | |
| 1244 | 1301 | echo nse-tandem-nsk${UNAME_RELEASE} |
| 1245 | 1302 | exit ;; |
| 1246 | 1303 | NSR-?:NONSTOP_KERNEL:*:*) |
| 1247 | 1304 | echo nsr-tandem-nsk${UNAME_RELEASE} |
| 1248 | 1305 | exit ;; |
| @@ -1283,17 +1340,17 @@ | ||
| 1283 | 1340 | exit ;; |
| 1284 | 1341 | *:ITS:*:*) |
| 1285 | 1342 | echo pdp10-unknown-its |
| 1286 | 1343 | exit ;; |
| 1287 | 1344 | SEI:*:*:SEIUX) |
| 1288 | - echo mips-sei-seiux${UNAME_RELEASE} | |
| 1345 | + echo mips-sei-seiux${UNAME_RELEASE} | |
| 1289 | 1346 | exit ;; |
| 1290 | 1347 | *:DragonFly:*:*) |
| 1291 | 1348 | echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` |
| 1292 | 1349 | exit ;; |
| 1293 | 1350 | *:*VMS:*:*) |
| 1294 | - UNAME_MACHINE=`(uname -p) 2>/dev/null` | |
| 1351 | + UNAME_MACHINE=`(uname -p) 2>/dev/null` | |
| 1295 | 1352 | case "${UNAME_MACHINE}" in |
| 1296 | 1353 | A*) echo alpha-dec-vms ; exit ;; |
| 1297 | 1354 | I*) echo ia64-dec-vms ; exit ;; |
| 1298 | 1355 | V*) echo vax-dec-vms ; exit ;; |
| 1299 | 1356 | esac ;; |
| @@ -1307,162 +1364,14 @@ | ||
| 1307 | 1364 | echo ${UNAME_MACHINE}-pc-rdos |
| 1308 | 1365 | exit ;; |
| 1309 | 1366 | i*86:AROS:*:*) |
| 1310 | 1367 | echo ${UNAME_MACHINE}-pc-aros |
| 1311 | 1368 | exit ;; |
| 1312 | -esac | |
| 1313 | - | |
| 1314 | -#echo '(No uname command or uname output not recognized.)' 1>&2 | |
| 1315 | -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 | |
| 1316 | - | |
| 1317 | -eval $set_cc_for_build | |
| 1318 | -cat >$dummy.c <<EOF | |
| 1319 | -#ifdef _SEQUENT_ | |
| 1320 | -# include <sys/types.h> | |
| 1321 | -# include <sys/utsname.h> | |
| 1322 | -#endif | |
| 1323 | -main () | |
| 1324 | -{ | |
| 1325 | -#if defined (sony) | |
| 1326 | -#if defined (MIPSEB) | |
| 1327 | - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, | |
| 1328 | - I don't know.... */ | |
| 1329 | - printf ("mips-sony-bsd\n"); exit (0); | |
| 1330 | -#else | |
| 1331 | -#include <sys/param.h> | |
| 1332 | - printf ("m68k-sony-newsos%s\n", | |
| 1333 | -#ifdef NEWSOS4 | |
| 1334 | - "4" | |
| 1335 | -#else | |
| 1336 | - "" | |
| 1337 | -#endif | |
| 1338 | - ); exit (0); | |
| 1339 | -#endif | |
| 1340 | -#endif | |
| 1341 | - | |
| 1342 | -#if defined (__arm) && defined (__acorn) && defined (__unix) | |
| 1343 | - printf ("arm-acorn-riscix\n"); exit (0); | |
| 1344 | -#endif | |
| 1345 | - | |
| 1346 | -#if defined (hp300) && !defined (hpux) | |
| 1347 | - printf ("m68k-hp-bsd\n"); exit (0); | |
| 1348 | -#endif | |
| 1349 | - | |
| 1350 | -#if defined (NeXT) | |
| 1351 | -#if !defined (__ARCHITECTURE__) | |
| 1352 | -#define __ARCHITECTURE__ "m68k" | |
| 1353 | -#endif | |
| 1354 | - int version; | |
| 1355 | - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; | |
| 1356 | - if (version < 4) | |
| 1357 | - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); | |
| 1358 | - else | |
| 1359 | - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); | |
| 1360 | - exit (0); | |
| 1361 | -#endif | |
| 1362 | - | |
| 1363 | -#if defined (MULTIMAX) || defined (n16) | |
| 1364 | -#if defined (UMAXV) | |
| 1365 | - printf ("ns32k-encore-sysv\n"); exit (0); | |
| 1366 | -#else | |
| 1367 | -#if defined (CMU) | |
| 1368 | - printf ("ns32k-encore-mach\n"); exit (0); | |
| 1369 | -#else | |
| 1370 | - printf ("ns32k-encore-bsd\n"); exit (0); | |
| 1371 | -#endif | |
| 1372 | -#endif | |
| 1373 | -#endif | |
| 1374 | - | |
| 1375 | -#if defined (__386BSD__) | |
| 1376 | - printf ("i386-pc-bsd\n"); exit (0); | |
| 1377 | -#endif | |
| 1378 | - | |
| 1379 | -#if defined (sequent) | |
| 1380 | -#if defined (i386) | |
| 1381 | - printf ("i386-sequent-dynix\n"); exit (0); | |
| 1382 | -#endif | |
| 1383 | -#if defined (ns32000) | |
| 1384 | - printf ("ns32k-sequent-dynix\n"); exit (0); | |
| 1385 | -#endif | |
| 1386 | -#endif | |
| 1387 | - | |
| 1388 | -#if defined (_SEQUENT_) | |
| 1389 | - struct utsname un; | |
| 1390 | - | |
| 1391 | - uname(&un); | |
| 1392 | - | |
| 1393 | - if (strncmp(un.version, "V2", 2) == 0) { | |
| 1394 | - printf ("i386-sequent-ptx2\n"); exit (0); | |
| 1395 | - } | |
| 1396 | - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ | |
| 1397 | - printf ("i386-sequent-ptx1\n"); exit (0); | |
| 1398 | - } | |
| 1399 | - printf ("i386-sequent-ptx\n"); exit (0); | |
| 1400 | - | |
| 1401 | -#endif | |
| 1402 | - | |
| 1403 | -#if defined (vax) | |
| 1404 | -# if !defined (ultrix) | |
| 1405 | -# include <sys/param.h> | |
| 1406 | -# if defined (BSD) | |
| 1407 | -# if BSD == 43 | |
| 1408 | - printf ("vax-dec-bsd4.3\n"); exit (0); | |
| 1409 | -# else | |
| 1410 | -# if BSD == 199006 | |
| 1411 | - printf ("vax-dec-bsd4.3reno\n"); exit (0); | |
| 1412 | -# else | |
| 1413 | - printf ("vax-dec-bsd\n"); exit (0); | |
| 1414 | -# endif | |
| 1415 | -# endif | |
| 1416 | -# else | |
| 1417 | - printf ("vax-dec-bsd\n"); exit (0); | |
| 1418 | -# endif | |
| 1419 | -# else | |
| 1420 | - printf ("vax-dec-ultrix\n"); exit (0); | |
| 1421 | -# endif | |
| 1422 | -#endif | |
| 1423 | - | |
| 1424 | -#if defined (alliant) && defined (i860) | |
| 1425 | - printf ("i860-alliant-bsd\n"); exit (0); | |
| 1426 | -#endif | |
| 1427 | - | |
| 1428 | - exit (1); | |
| 1429 | -} | |
| 1430 | -EOF | |
| 1431 | - | |
| 1432 | -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && | |
| 1433 | - { echo "$SYSTEM_NAME"; exit; } | |
| 1434 | - | |
| 1435 | -# Apollos put the system type in the environment. | |
| 1436 | - | |
| 1437 | -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } | |
| 1438 | - | |
| 1439 | -# Convex versions that predate uname can use getsysinfo(1) | |
| 1440 | - | |
| 1441 | -if [ -x /usr/convex/getsysinfo ] | |
| 1442 | -then | |
| 1443 | - case `getsysinfo -f cpu_type` in | |
| 1444 | - c1*) | |
| 1445 | - echo c1-convex-bsd | |
| 1446 | - exit ;; | |
| 1447 | - c2*) | |
| 1448 | - if getsysinfo -f scalar_acc | |
| 1449 | - then echo c32-convex-bsd | |
| 1450 | - else echo c2-convex-bsd | |
| 1451 | - fi | |
| 1452 | - exit ;; | |
| 1453 | - c34*) | |
| 1454 | - echo c34-convex-bsd | |
| 1455 | - exit ;; | |
| 1456 | - c38*) | |
| 1457 | - echo c38-convex-bsd | |
| 1458 | - exit ;; | |
| 1459 | - c4*) | |
| 1460 | - echo c4-convex-bsd | |
| 1461 | - exit ;; | |
| 1462 | - esac | |
| 1463 | -fi | |
| 1369 | + x86_64:VMkernel:*:*) | |
| 1370 | + echo ${UNAME_MACHINE}-unknown-esx | |
| 1371 | + exit ;; | |
| 1372 | +esac | |
| 1464 | 1373 | |
| 1465 | 1374 | cat >&2 <<EOF |
| 1466 | 1375 | $0: unable to guess system type |
| 1467 | 1376 | |
| 1468 | 1377 | This script, last modified $timestamp, has failed to recognize |
| 1469 | 1378 |
| --- autosetup/config.guess | |
| +++ autosetup/config.guess | |
| @@ -1,44 +1,38 @@ | |
| 1 | #! /bin/sh |
| 2 | # Attempt to guess a canonical system name. |
| 3 | # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
| 4 | # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
| 5 | # Free Software Foundation, Inc. |
| 6 | |
| 7 | timestamp='2010-09-24' |
| 8 | |
| 9 | # This file is free software; you can redistribute it and/or modify it |
| 10 | # under the terms of the GNU General Public License as published by |
| 11 | # the Free Software Foundation; either version 2 of the License, or |
| 12 | # (at your option) any later version. |
| 13 | # |
| 14 | # This program is distributed in the hope that it will be useful, but |
| 15 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | # General Public License for more details. |
| 18 | # |
| 19 | # You should have received a copy of the GNU General Public License |
| 20 | # along with this program; if not, write to the Free Software |
| 21 | # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA |
| 22 | # 02110-1301, USA. |
| 23 | # |
| 24 | # As a special exception to the GNU General Public License, if you |
| 25 | # distribute this file as part of a program that contains a |
| 26 | # configuration script generated by Autoconf, you may include it under |
| 27 | # the same distribution terms that you use for the rest of that program. |
| 28 | |
| 29 | |
| 30 | # Originally written by Per Bothner. Please send patches (context |
| 31 | # diff format) to <[email protected]> and include a ChangeLog |
| 32 | # entry. |
| 33 | # |
| 34 | # This script attempts to guess a canonical system name similar to |
| 35 | # config.sub. If it succeeds, it prints the system name on stdout, and |
| 36 | # exits with 0. Otherwise, it exits with 1. |
| 37 | # |
| 38 | # You can get the latest version of this script from: |
| 39 | # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD |
| 40 | |
| 41 | me=`echo "$0" | sed -e 's,.*/,,'` |
| 42 | |
| 43 | usage="\ |
| 44 | Usage: $0 [OPTION] |
| @@ -54,13 +48,11 @@ | |
| 54 | |
| 55 | version="\ |
| 56 | GNU config.guess ($timestamp) |
| 57 | |
| 58 | Originally written by Per Bothner. |
| 59 | Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
| 60 | 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free |
| 61 | Software Foundation, Inc. |
| 62 | |
| 63 | This is free software; see the source for copying conditions. There is NO |
| 64 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 65 | |
| 66 | help=" |
| @@ -90,11 +82,11 @@ | |
| 90 | if test $# != 0; then |
| 91 | echo "$me: too many arguments$help" >&2 |
| 92 | exit 1 |
| 93 | fi |
| 94 | |
| 95 | trap 'exit 1' HUP INT TERM |
| 96 | |
| 97 | # CC_FOR_BUILD -- compiler used by this script. Note that the use of a |
| 98 | # compiler to aid in system detection is discouraged as it requires |
| 99 | # temporary files to be created and, as you can see below, it is a |
| 100 | # headache to deal with in a portable fashion. |
| @@ -104,11 +96,11 @@ | |
| 104 | |
| 105 | # Portable tmp directory creation inspired by the Autoconf team. |
| 106 | |
| 107 | set_cc_for_build=' |
| 108 | trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; |
| 109 | trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ; |
| 110 | : ${TMPDIR=/tmp} ; |
| 111 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || |
| 112 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || |
| 113 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || |
| 114 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; |
| @@ -137,17 +129,38 @@ | |
| 137 | |
| 138 | UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown |
| 139 | UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown |
| 140 | UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown |
| 141 | UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown |
| 142 | |
| 143 | # Note: order is significant - the case branches are not exclusive. |
| 144 | |
| 145 | case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in |
| 146 | *:NetBSD:*:*) |
| 147 | # NetBSD (nbsd) targets should (where applicable) match one or |
| 148 | # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, |
| 149 | # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently |
| 150 | # switched to ELF, *-*-netbsd* would select the old |
| 151 | # object file format. This provides both forward |
| 152 | # compatibility and a consistent mechanism for selecting the |
| 153 | # object file format. |
| @@ -179,11 +192,11 @@ | |
| 179 | else |
| 180 | os=netbsdelf |
| 181 | fi |
| 182 | ;; |
| 183 | *) |
| 184 | os=netbsd |
| 185 | ;; |
| 186 | esac |
| 187 | # The OS release |
| 188 | # Debian GNU/NetBSD machines have a different userland, and |
| 189 | # thus, need a distinct triplet. However, they do not need |
| @@ -200,10 +213,14 @@ | |
| 200 | # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: |
| 201 | # contains redundant information, the shorter form: |
| 202 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. |
| 203 | echo "${machine}-${os}${release}" |
| 204 | exit ;; |
| 205 | *:OpenBSD:*:*) |
| 206 | UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` |
| 207 | echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} |
| 208 | exit ;; |
| 209 | *:ekkoBSD:*:*) |
| @@ -222,11 +239,11 @@ | |
| 222 | case $UNAME_RELEASE in |
| 223 | *4.0) |
| 224 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` |
| 225 | ;; |
| 226 | *5.*) |
| 227 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` |
| 228 | ;; |
| 229 | esac |
| 230 | # According to Compaq, /usr/sbin/psrinfo has been available on |
| 231 | # OSF/1 and Tru64 systems produced since 1995. I hope that |
| 232 | # covers most systems running today. This code pipes the CPU |
| @@ -268,11 +285,14 @@ | |
| 268 | # A Vn.n version is a released version. |
| 269 | # A Tn.n version is a released field test version. |
| 270 | # A Xn.n version is an unreleased experimental baselevel. |
| 271 | # 1.2 uses "1.2" for uname -r. |
| 272 | echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 273 | exit ;; |
| 274 | Alpha\ *:Windows_NT*:*) |
| 275 | # How do we know it's Interix rather than the generic POSIX subsystem? |
| 276 | # Should we change UNAME_MACHINE based on the output of uname instead |
| 277 | # of the specific Alpha model? |
| 278 | echo alpha-pc-interix |
| @@ -294,16 +314,16 @@ | |
| 294 | exit ;; |
| 295 | *:z/VM:*:*) |
| 296 | echo s390-ibm-zvmoe |
| 297 | exit ;; |
| 298 | *:OS400:*:*) |
| 299 | echo powerpc-ibm-os400 |
| 300 | exit ;; |
| 301 | arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) |
| 302 | echo arm-acorn-riscix${UNAME_RELEASE} |
| 303 | exit ;; |
| 304 | arm:riscos:*:*|arm:RISCOS:*:*) |
| 305 | echo arm-unknown-riscos |
| 306 | exit ;; |
| 307 | SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) |
| 308 | echo hppa1.1-hitachi-hiuxmpp |
| 309 | exit ;; |
| @@ -393,27 +413,27 @@ | |
| 393 | # to the lowercase version "mint" (or "freemint"). Finally |
| 394 | # the system name "TOS" denotes a system which is actually not |
| 395 | # MiNT. But MiNT is downward compatible to TOS, so this should |
| 396 | # be no problem. |
| 397 | atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) |
| 398 | echo m68k-atari-mint${UNAME_RELEASE} |
| 399 | exit ;; |
| 400 | atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) |
| 401 | echo m68k-atari-mint${UNAME_RELEASE} |
| 402 | exit ;; |
| 403 | *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) |
| 404 | echo m68k-atari-mint${UNAME_RELEASE} |
| 405 | exit ;; |
| 406 | milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) |
| 407 | echo m68k-milan-mint${UNAME_RELEASE} |
| 408 | exit ;; |
| 409 | hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) |
| 410 | echo m68k-hades-mint${UNAME_RELEASE} |
| 411 | exit ;; |
| 412 | *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) |
| 413 | echo m68k-unknown-mint${UNAME_RELEASE} |
| 414 | exit ;; |
| 415 | m68k:machten:*:*) |
| 416 | echo m68k-apple-machten${UNAME_RELEASE} |
| 417 | exit ;; |
| 418 | powerpc:machten:*:*) |
| 419 | echo powerpc-apple-machten${UNAME_RELEASE} |
| @@ -479,12 +499,12 @@ | |
| 479 | exit ;; |
| 480 | m88k:*:3*:R3*) |
| 481 | echo m88k-motorola-sysv3 |
| 482 | exit ;; |
| 483 | AViiON:dgux:*:*) |
| 484 | # DG/UX returns AViiON for all architectures |
| 485 | UNAME_PROCESSOR=`/usr/bin/uname -p` |
| 486 | if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] |
| 487 | then |
| 488 | if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ |
| 489 | [ ${TARGET_BINARY_INTERFACE}x = x ] |
| 490 | then |
| @@ -493,11 +513,11 @@ | |
| 493 | echo m88k-dg-dguxbcs${UNAME_RELEASE} |
| 494 | fi |
| 495 | else |
| 496 | echo i586-dg-dgux${UNAME_RELEASE} |
| 497 | fi |
| 498 | exit ;; |
| 499 | M88*:DolphinOS:*:*) # DolphinOS (SVR3) |
| 500 | echo m88k-dolphin-sysv3 |
| 501 | exit ;; |
| 502 | M88*:*:R3*:*) |
| 503 | # Delta 88k system running SVR3 |
| @@ -593,56 +613,56 @@ | |
| 593 | 9000/31? ) HP_ARCH=m68000 ;; |
| 594 | 9000/[34]?? ) HP_ARCH=m68k ;; |
| 595 | 9000/[678][0-9][0-9]) |
| 596 | if [ -x /usr/bin/getconf ]; then |
| 597 | sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` |
| 598 | sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` |
| 599 | case "${sc_cpu_version}" in |
| 600 | 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 |
| 601 | 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 |
| 602 | 532) # CPU_PA_RISC2_0 |
| 603 | case "${sc_kernel_bits}" in |
| 604 | 32) HP_ARCH="hppa2.0n" ;; |
| 605 | 64) HP_ARCH="hppa2.0w" ;; |
| 606 | '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 |
| 607 | esac ;; |
| 608 | esac |
| 609 | fi |
| 610 | if [ "${HP_ARCH}" = "" ]; then |
| 611 | eval $set_cc_for_build |
| 612 | sed 's/^ //' << EOF >$dummy.c |
| 613 | |
| 614 | #define _HPUX_SOURCE |
| 615 | #include <stdlib.h> |
| 616 | #include <unistd.h> |
| 617 | |
| 618 | int main () |
| 619 | { |
| 620 | #if defined(_SC_KERNEL_BITS) |
| 621 | long bits = sysconf(_SC_KERNEL_BITS); |
| 622 | #endif |
| 623 | long cpu = sysconf (_SC_CPU_VERSION); |
| 624 | |
| 625 | switch (cpu) |
| 626 | { |
| 627 | case CPU_PA_RISC1_0: puts ("hppa1.0"); break; |
| 628 | case CPU_PA_RISC1_1: puts ("hppa1.1"); break; |
| 629 | case CPU_PA_RISC2_0: |
| 630 | #if defined(_SC_KERNEL_BITS) |
| 631 | switch (bits) |
| 632 | { |
| 633 | case 64: puts ("hppa2.0w"); break; |
| 634 | case 32: puts ("hppa2.0n"); break; |
| 635 | default: puts ("hppa2.0"); break; |
| 636 | } break; |
| 637 | #else /* !defined(_SC_KERNEL_BITS) */ |
| 638 | puts ("hppa2.0"); break; |
| 639 | #endif |
| 640 | default: puts ("hppa1.0"); break; |
| 641 | } |
| 642 | exit (0); |
| 643 | } |
| 644 | EOF |
| 645 | (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` |
| 646 | test -z "$HP_ARCH" && HP_ARCH=hppa |
| 647 | fi ;; |
| 648 | esac |
| @@ -729,26 +749,26 @@ | |
| 729 | parisc*:Lites*:*:*) |
| 730 | echo hppa1.1-hp-lites |
| 731 | exit ;; |
| 732 | C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) |
| 733 | echo c1-convex-bsd |
| 734 | exit ;; |
| 735 | C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) |
| 736 | if getsysinfo -f scalar_acc |
| 737 | then echo c32-convex-bsd |
| 738 | else echo c2-convex-bsd |
| 739 | fi |
| 740 | exit ;; |
| 741 | C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) |
| 742 | echo c34-convex-bsd |
| 743 | exit ;; |
| 744 | C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) |
| 745 | echo c38-convex-bsd |
| 746 | exit ;; |
| 747 | C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) |
| 748 | echo c4-convex-bsd |
| 749 | exit ;; |
| 750 | CRAY*Y-MP:*:*:*) |
| 751 | echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 752 | exit ;; |
| 753 | CRAY*[A-Z]90:*:*:*) |
| 754 | echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ |
| @@ -768,18 +788,18 @@ | |
| 768 | *:UNICOS/mp:*:*) |
| 769 | echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 770 | exit ;; |
| 771 | F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) |
| 772 | FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 773 | FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` |
| 774 | FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` |
| 775 | echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" |
| 776 | exit ;; |
| 777 | 5000:UNIX_System_V:4.*:*) |
| 778 | FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` |
| 779 | FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` |
| 780 | echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" |
| 781 | exit ;; |
| 782 | i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) |
| 783 | echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} |
| 784 | exit ;; |
| 785 | sparc*:BSD/OS:*:*) |
| @@ -787,37 +807,39 @@ | |
| 787 | exit ;; |
| 788 | *:BSD/OS:*:*) |
| 789 | echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} |
| 790 | exit ;; |
| 791 | *:FreeBSD:*:*) |
| 792 | case ${UNAME_MACHINE} in |
| 793 | pc98) |
| 794 | echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 795 | amd64) |
| 796 | echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 797 | *) |
| 798 | echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 799 | esac |
| 800 | exit ;; |
| 801 | i*:CYGWIN*:*) |
| 802 | echo ${UNAME_MACHINE}-pc-cygwin |
| 803 | exit ;; |
| 804 | *:MINGW*:*) |
| 805 | echo ${UNAME_MACHINE}-pc-mingw32 |
| 806 | exit ;; |
| 807 | i*:MSYS*:*) |
| 808 | echo ${UNAME_MACHINE}-pc-msys |
| 809 | exit ;; |
| 810 | i*:windows32*:*) |
| 811 | # uname -m includes "-pc" on this system. |
| 812 | echo ${UNAME_MACHINE}-mingw32 |
| 813 | exit ;; |
| 814 | i*:PW*:*) |
| 815 | echo ${UNAME_MACHINE}-pc-pw32 |
| 816 | exit ;; |
| 817 | *:Interix*:*) |
| 818 | case ${UNAME_MACHINE} in |
| 819 | x86) |
| 820 | echo i586-pc-interix${UNAME_RELEASE} |
| 821 | exit ;; |
| 822 | authenticamd | genuineintel | EM64T) |
| 823 | echo x86_64-unknown-interix${UNAME_RELEASE} |
| @@ -850,74 +872,85 @@ | |
| 850 | prep*:SunOS:5.*:*) |
| 851 | echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` |
| 852 | exit ;; |
| 853 | *:GNU:*:*) |
| 854 | # the GNU system |
| 855 | echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` |
| 856 | exit ;; |
| 857 | *:GNU/*:*:*) |
| 858 | # other systems with GNU libc and userland |
| 859 | echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu |
| 860 | exit ;; |
| 861 | i*86:Minix:*:*) |
| 862 | echo ${UNAME_MACHINE}-pc-minix |
| 863 | exit ;; |
| 864 | alpha:Linux:*:*) |
| 865 | case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in |
| 866 | EV5) UNAME_MACHINE=alphaev5 ;; |
| 867 | EV56) UNAME_MACHINE=alphaev56 ;; |
| 868 | PCA56) UNAME_MACHINE=alphapca56 ;; |
| 869 | PCA57) UNAME_MACHINE=alphapca56 ;; |
| 870 | EV6) UNAME_MACHINE=alphaev6 ;; |
| 871 | EV67) UNAME_MACHINE=alphaev67 ;; |
| 872 | EV68*) UNAME_MACHINE=alphaev68 ;; |
| 873 | esac |
| 874 | objdump --private-headers /bin/sh | grep -q ld.so.1 |
| 875 | if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi |
| 876 | echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} |
| 877 | exit ;; |
| 878 | arm*:Linux:*:*) |
| 879 | eval $set_cc_for_build |
| 880 | if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
| 881 | | grep -q __ARM_EABI__ |
| 882 | then |
| 883 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 884 | else |
| 885 | echo ${UNAME_MACHINE}-unknown-linux-gnueabi |
| 886 | fi |
| 887 | exit ;; |
| 888 | avr32*:Linux:*:*) |
| 889 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 890 | exit ;; |
| 891 | cris:Linux:*:*) |
| 892 | echo cris-axis-linux-gnu |
| 893 | exit ;; |
| 894 | crisv32:Linux:*:*) |
| 895 | echo crisv32-axis-linux-gnu |
| 896 | exit ;; |
| 897 | frv:Linux:*:*) |
| 898 | echo frv-unknown-linux-gnu |
| 899 | exit ;; |
| 900 | i*86:Linux:*:*) |
| 901 | LIBC=gnu |
| 902 | eval $set_cc_for_build |
| 903 | sed 's/^ //' << EOF >$dummy.c |
| 904 | #ifdef __dietlibc__ |
| 905 | LIBC=dietlibc |
| 906 | #endif |
| 907 | EOF |
| 908 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` |
| 909 | echo "${UNAME_MACHINE}-pc-linux-${LIBC}" |
| 910 | exit ;; |
| 911 | ia64:Linux:*:*) |
| 912 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 913 | exit ;; |
| 914 | m32r*:Linux:*:*) |
| 915 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 916 | exit ;; |
| 917 | m68*:Linux:*:*) |
| 918 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 919 | exit ;; |
| 920 | mips:Linux:*:* | mips64:Linux:*:*) |
| 921 | eval $set_cc_for_build |
| 922 | sed 's/^ //' << EOF >$dummy.c |
| 923 | #undef CPU |
| @@ -932,71 +965,80 @@ | |
| 932 | CPU= |
| 933 | #endif |
| 934 | #endif |
| 935 | EOF |
| 936 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` |
| 937 | test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } |
| 938 | ;; |
| 939 | or32:Linux:*:*) |
| 940 | echo or32-unknown-linux-gnu |
| 941 | exit ;; |
| 942 | padre:Linux:*:*) |
| 943 | echo sparc-unknown-linux-gnu |
| 944 | exit ;; |
| 945 | parisc64:Linux:*:* | hppa64:Linux:*:*) |
| 946 | echo hppa64-unknown-linux-gnu |
| 947 | exit ;; |
| 948 | parisc:Linux:*:* | hppa:Linux:*:*) |
| 949 | # Look for CPU level |
| 950 | case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in |
| 951 | PA7*) echo hppa1.1-unknown-linux-gnu ;; |
| 952 | PA8*) echo hppa2.0-unknown-linux-gnu ;; |
| 953 | *) echo hppa-unknown-linux-gnu ;; |
| 954 | esac |
| 955 | exit ;; |
| 956 | ppc64:Linux:*:*) |
| 957 | echo powerpc64-unknown-linux-gnu |
| 958 | exit ;; |
| 959 | ppc:Linux:*:*) |
| 960 | echo powerpc-unknown-linux-gnu |
| 961 | exit ;; |
| 962 | s390:Linux:*:* | s390x:Linux:*:*) |
| 963 | echo ${UNAME_MACHINE}-ibm-linux |
| 964 | exit ;; |
| 965 | sh64*:Linux:*:*) |
| 966 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 967 | exit ;; |
| 968 | sh*:Linux:*:*) |
| 969 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 970 | exit ;; |
| 971 | sparc:Linux:*:* | sparc64:Linux:*:*) |
| 972 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 973 | exit ;; |
| 974 | tile*:Linux:*:*) |
| 975 | echo ${UNAME_MACHINE}-tilera-linux-gnu |
| 976 | exit ;; |
| 977 | vax:Linux:*:*) |
| 978 | echo ${UNAME_MACHINE}-dec-linux-gnu |
| 979 | exit ;; |
| 980 | x86_64:Linux:*:*) |
| 981 | echo x86_64-unknown-linux-gnu |
| 982 | exit ;; |
| 983 | xtensa*:Linux:*:*) |
| 984 | echo ${UNAME_MACHINE}-unknown-linux-gnu |
| 985 | exit ;; |
| 986 | i*86:DYNIX/ptx:4*:*) |
| 987 | # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. |
| 988 | # earlier versions are messed up and put the nodename in both |
| 989 | # sysname and nodename. |
| 990 | echo i386-sequent-sysv4 |
| 991 | exit ;; |
| 992 | i*86:UNIX_SV:4.2MP:2.*) |
| 993 | # Unixware is an offshoot of SVR4, but it has its own version |
| 994 | # number series starting with 2... |
| 995 | # I am not positive that other SVR4 systems won't match this, |
| 996 | # I just have to hope. -- rms. |
| 997 | # Use sysv4.2uw... so that sysv4* matches it. |
| 998 | echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} |
| 999 | exit ;; |
| 1000 | i*86:OS/2:*:*) |
| 1001 | # If we were able to find `uname', then EMX Unix compatibility |
| 1002 | # is probably installed. |
| @@ -1024,11 +1066,11 @@ | |
| 1024 | else |
| 1025 | echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} |
| 1026 | fi |
| 1027 | exit ;; |
| 1028 | i*86:*:5:[678]*) |
| 1029 | # UnixWare 7.x, OpenUNIX and OpenServer 6. |
| 1030 | case `/bin/uname -X | grep "^Machine"` in |
| 1031 | *486*) UNAME_MACHINE=i486 ;; |
| 1032 | *Pentium) UNAME_MACHINE=i586 ;; |
| 1033 | *Pent*|*Celeron) UNAME_MACHINE=i686 ;; |
| 1034 | esac |
| @@ -1052,17 +1094,17 @@ | |
| 1052 | echo ${UNAME_MACHINE}-pc-sysv32 |
| 1053 | fi |
| 1054 | exit ;; |
| 1055 | pc:*:*:*) |
| 1056 | # Left here for compatibility: |
| 1057 | # uname -m prints for DJGPP always 'pc', but it prints nothing about |
| 1058 | # the processor, so we play safe by assuming i586. |
| 1059 | # Note: whatever this is, it MUST be the same as what config.sub |
| 1060 | # prints for the "djgpp" host, or else GDB configury will decide that |
| 1061 | # this is a cross-build. |
| 1062 | echo i586-pc-msdosdjgpp |
| 1063 | exit ;; |
| 1064 | Intel:Mach:3*:*) |
| 1065 | echo i386-pc-mach3 |
| 1066 | exit ;; |
| 1067 | paragon:*:*:*) |
| 1068 | echo i860-intel-osf1 |
| @@ -1093,12 +1135,12 @@ | |
| 1093 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| 1094 | && { echo i486-ncr-sysv4.3${OS_REL}; exit; } |
| 1095 | /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ |
| 1096 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; |
| 1097 | 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) |
| 1098 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| 1099 | && { echo i486-ncr-sysv4; exit; } ;; |
| 1100 | NCR*:*:4.2:* | MPRAS*:*:4.2:*) |
| 1101 | OS_REL='.3' |
| 1102 | test -r /etc/.relid \ |
| 1103 | && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` |
| 1104 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| @@ -1137,14 +1179,14 @@ | |
| 1137 | echo ${UNAME_MACHINE}-sni-sysv4 |
| 1138 | else |
| 1139 | echo ns32k-sni-sysv |
| 1140 | fi |
| 1141 | exit ;; |
| 1142 | PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort |
| 1143 | # says <[email protected]> |
| 1144 | echo i586-unisys-sysv4 |
| 1145 | exit ;; |
| 1146 | *:UNIX_System_V:4*:FTX*) |
| 1147 | # From Gerald Hewes <[email protected]>. |
| 1148 | # How about differentiating between stratus architectures? -djm |
| 1149 | echo hppa1.1-stratus-sysv4 |
| 1150 | exit ;; |
| @@ -1166,15 +1208,15 @@ | |
| 1166 | news*:NEWS-OS:6*:*) |
| 1167 | echo mips-sony-newsos6 |
| 1168 | exit ;; |
| 1169 | R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) |
| 1170 | if [ -d /usr/nec ]; then |
| 1171 | echo mips-nec-sysv${UNAME_RELEASE} |
| 1172 | else |
| 1173 | echo mips-unknown-sysv${UNAME_RELEASE} |
| 1174 | fi |
| 1175 | exit ;; |
| 1176 | BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. |
| 1177 | echo powerpc-be-beos |
| 1178 | exit ;; |
| 1179 | BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. |
| 1180 | echo powerpc-apple-beos |
| @@ -1183,10 +1225,13 @@ | |
| 1183 | echo i586-pc-beos |
| 1184 | exit ;; |
| 1185 | BePC:Haiku:*:*) # Haiku running on Intel PC compatible. |
| 1186 | echo i586-pc-haiku |
| 1187 | exit ;; |
| 1188 | SX-4:SUPER-UX:*:*) |
| 1189 | echo sx4-nec-superux${UNAME_RELEASE} |
| 1190 | exit ;; |
| 1191 | SX-5:SUPER-UX:*:*) |
| 1192 | echo sx5-nec-superux${UNAME_RELEASE} |
| @@ -1209,23 +1254,35 @@ | |
| 1209 | *:Rhapsody:*:*) |
| 1210 | echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} |
| 1211 | exit ;; |
| 1212 | *:Darwin:*:*) |
| 1213 | UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown |
| 1214 | case $UNAME_PROCESSOR in |
| 1215 | i386) |
| 1216 | eval $set_cc_for_build |
| 1217 | if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then |
| 1218 | if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ |
| 1219 | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ |
| 1220 | grep IS_64BIT_ARCH >/dev/null |
| 1221 | then |
| 1222 | UNAME_PROCESSOR="x86_64" |
| 1223 | fi |
| 1224 | fi ;; |
| 1225 | unknown) UNAME_PROCESSOR=powerpc ;; |
| 1226 | esac |
| 1227 | echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} |
| 1228 | exit ;; |
| 1229 | *:procnto*:*:* | *:QNX:[0123456789]*:*) |
| 1230 | UNAME_PROCESSOR=`uname -p` |
| 1231 | if test "$UNAME_PROCESSOR" = "x86"; then |
| @@ -1238,11 +1295,11 @@ | |
| 1238 | echo i386-pc-qnx |
| 1239 | exit ;; |
| 1240 | NEO-?:NONSTOP_KERNEL:*:*) |
| 1241 | echo neo-tandem-nsk${UNAME_RELEASE} |
| 1242 | exit ;; |
| 1243 | NSE-?:NONSTOP_KERNEL:*:*) |
| 1244 | echo nse-tandem-nsk${UNAME_RELEASE} |
| 1245 | exit ;; |
| 1246 | NSR-?:NONSTOP_KERNEL:*:*) |
| 1247 | echo nsr-tandem-nsk${UNAME_RELEASE} |
| 1248 | exit ;; |
| @@ -1283,17 +1340,17 @@ | |
| 1283 | exit ;; |
| 1284 | *:ITS:*:*) |
| 1285 | echo pdp10-unknown-its |
| 1286 | exit ;; |
| 1287 | SEI:*:*:SEIUX) |
| 1288 | echo mips-sei-seiux${UNAME_RELEASE} |
| 1289 | exit ;; |
| 1290 | *:DragonFly:*:*) |
| 1291 | echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` |
| 1292 | exit ;; |
| 1293 | *:*VMS:*:*) |
| 1294 | UNAME_MACHINE=`(uname -p) 2>/dev/null` |
| 1295 | case "${UNAME_MACHINE}" in |
| 1296 | A*) echo alpha-dec-vms ; exit ;; |
| 1297 | I*) echo ia64-dec-vms ; exit ;; |
| 1298 | V*) echo vax-dec-vms ; exit ;; |
| 1299 | esac ;; |
| @@ -1307,162 +1364,14 @@ | |
| 1307 | echo ${UNAME_MACHINE}-pc-rdos |
| 1308 | exit ;; |
| 1309 | i*86:AROS:*:*) |
| 1310 | echo ${UNAME_MACHINE}-pc-aros |
| 1311 | exit ;; |
| 1312 | esac |
| 1313 | |
| 1314 | #echo '(No uname command or uname output not recognized.)' 1>&2 |
| 1315 | #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 |
| 1316 | |
| 1317 | eval $set_cc_for_build |
| 1318 | cat >$dummy.c <<EOF |
| 1319 | #ifdef _SEQUENT_ |
| 1320 | # include <sys/types.h> |
| 1321 | # include <sys/utsname.h> |
| 1322 | #endif |
| 1323 | main () |
| 1324 | { |
| 1325 | #if defined (sony) |
| 1326 | #if defined (MIPSEB) |
| 1327 | /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, |
| 1328 | I don't know.... */ |
| 1329 | printf ("mips-sony-bsd\n"); exit (0); |
| 1330 | #else |
| 1331 | #include <sys/param.h> |
| 1332 | printf ("m68k-sony-newsos%s\n", |
| 1333 | #ifdef NEWSOS4 |
| 1334 | "4" |
| 1335 | #else |
| 1336 | "" |
| 1337 | #endif |
| 1338 | ); exit (0); |
| 1339 | #endif |
| 1340 | #endif |
| 1341 | |
| 1342 | #if defined (__arm) && defined (__acorn) && defined (__unix) |
| 1343 | printf ("arm-acorn-riscix\n"); exit (0); |
| 1344 | #endif |
| 1345 | |
| 1346 | #if defined (hp300) && !defined (hpux) |
| 1347 | printf ("m68k-hp-bsd\n"); exit (0); |
| 1348 | #endif |
| 1349 | |
| 1350 | #if defined (NeXT) |
| 1351 | #if !defined (__ARCHITECTURE__) |
| 1352 | #define __ARCHITECTURE__ "m68k" |
| 1353 | #endif |
| 1354 | int version; |
| 1355 | version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; |
| 1356 | if (version < 4) |
| 1357 | printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); |
| 1358 | else |
| 1359 | printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); |
| 1360 | exit (0); |
| 1361 | #endif |
| 1362 | |
| 1363 | #if defined (MULTIMAX) || defined (n16) |
| 1364 | #if defined (UMAXV) |
| 1365 | printf ("ns32k-encore-sysv\n"); exit (0); |
| 1366 | #else |
| 1367 | #if defined (CMU) |
| 1368 | printf ("ns32k-encore-mach\n"); exit (0); |
| 1369 | #else |
| 1370 | printf ("ns32k-encore-bsd\n"); exit (0); |
| 1371 | #endif |
| 1372 | #endif |
| 1373 | #endif |
| 1374 | |
| 1375 | #if defined (__386BSD__) |
| 1376 | printf ("i386-pc-bsd\n"); exit (0); |
| 1377 | #endif |
| 1378 | |
| 1379 | #if defined (sequent) |
| 1380 | #if defined (i386) |
| 1381 | printf ("i386-sequent-dynix\n"); exit (0); |
| 1382 | #endif |
| 1383 | #if defined (ns32000) |
| 1384 | printf ("ns32k-sequent-dynix\n"); exit (0); |
| 1385 | #endif |
| 1386 | #endif |
| 1387 | |
| 1388 | #if defined (_SEQUENT_) |
| 1389 | struct utsname un; |
| 1390 | |
| 1391 | uname(&un); |
| 1392 | |
| 1393 | if (strncmp(un.version, "V2", 2) == 0) { |
| 1394 | printf ("i386-sequent-ptx2\n"); exit (0); |
| 1395 | } |
| 1396 | if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ |
| 1397 | printf ("i386-sequent-ptx1\n"); exit (0); |
| 1398 | } |
| 1399 | printf ("i386-sequent-ptx\n"); exit (0); |
| 1400 | |
| 1401 | #endif |
| 1402 | |
| 1403 | #if defined (vax) |
| 1404 | # if !defined (ultrix) |
| 1405 | # include <sys/param.h> |
| 1406 | # if defined (BSD) |
| 1407 | # if BSD == 43 |
| 1408 | printf ("vax-dec-bsd4.3\n"); exit (0); |
| 1409 | # else |
| 1410 | # if BSD == 199006 |
| 1411 | printf ("vax-dec-bsd4.3reno\n"); exit (0); |
| 1412 | # else |
| 1413 | printf ("vax-dec-bsd\n"); exit (0); |
| 1414 | # endif |
| 1415 | # endif |
| 1416 | # else |
| 1417 | printf ("vax-dec-bsd\n"); exit (0); |
| 1418 | # endif |
| 1419 | # else |
| 1420 | printf ("vax-dec-ultrix\n"); exit (0); |
| 1421 | # endif |
| 1422 | #endif |
| 1423 | |
| 1424 | #if defined (alliant) && defined (i860) |
| 1425 | printf ("i860-alliant-bsd\n"); exit (0); |
| 1426 | #endif |
| 1427 | |
| 1428 | exit (1); |
| 1429 | } |
| 1430 | EOF |
| 1431 | |
| 1432 | $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && |
| 1433 | { echo "$SYSTEM_NAME"; exit; } |
| 1434 | |
| 1435 | # Apollos put the system type in the environment. |
| 1436 | |
| 1437 | test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } |
| 1438 | |
| 1439 | # Convex versions that predate uname can use getsysinfo(1) |
| 1440 | |
| 1441 | if [ -x /usr/convex/getsysinfo ] |
| 1442 | then |
| 1443 | case `getsysinfo -f cpu_type` in |
| 1444 | c1*) |
| 1445 | echo c1-convex-bsd |
| 1446 | exit ;; |
| 1447 | c2*) |
| 1448 | if getsysinfo -f scalar_acc |
| 1449 | then echo c32-convex-bsd |
| 1450 | else echo c2-convex-bsd |
| 1451 | fi |
| 1452 | exit ;; |
| 1453 | c34*) |
| 1454 | echo c34-convex-bsd |
| 1455 | exit ;; |
| 1456 | c38*) |
| 1457 | echo c38-convex-bsd |
| 1458 | exit ;; |
| 1459 | c4*) |
| 1460 | echo c4-convex-bsd |
| 1461 | exit ;; |
| 1462 | esac |
| 1463 | fi |
| 1464 | |
| 1465 | cat >&2 <<EOF |
| 1466 | $0: unable to guess system type |
| 1467 | |
| 1468 | This script, last modified $timestamp, has failed to recognize |
| 1469 |
| --- autosetup/config.guess | |
| +++ autosetup/config.guess | |
| @@ -1,44 +1,38 @@ | |
| 1 | #! /bin/sh |
| 2 | # Attempt to guess a canonical system name. |
| 3 | # Copyright 1992-2014 Free Software Foundation, Inc. |
| 4 | |
| 5 | timestamp='2014-03-23' |
| 6 | |
| 7 | # This file is free software; you can redistribute it and/or modify it |
| 8 | # under the terms of the GNU General Public License as published by |
| 9 | # the Free Software Foundation; either version 3 of the License, or |
| 10 | # (at your option) any later version. |
| 11 | # |
| 12 | # This program is distributed in the hope that it will be useful, but |
| 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | # General Public License for more details. |
| 16 | # |
| 17 | # You should have received a copy of the GNU General Public License |
| 18 | # along with this program; if not, see <http://www.gnu.org/licenses/>. |
| 19 | # |
| 20 | # As a special exception to the GNU General Public License, if you |
| 21 | # distribute this file as part of a program that contains a |
| 22 | # configuration script generated by Autoconf, you may include it under |
| 23 | # the same distribution terms that you use for the rest of that |
| 24 | # program. This Exception is an additional permission under section 7 |
| 25 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 26 | # |
| 27 | # Originally written by Per Bothner. |
| 28 | # |
| 29 | # You can get the latest version of this script from: |
| 30 | # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD |
| 31 | # |
| 32 | # Please send patches with a ChangeLog entry to [email protected]. |
| 33 | |
| 34 | |
| 35 | me=`echo "$0" | sed -e 's,.*/,,'` |
| 36 | |
| 37 | usage="\ |
| 38 | Usage: $0 [OPTION] |
| @@ -54,13 +48,11 @@ | |
| 48 | |
| 49 | version="\ |
| 50 | GNU config.guess ($timestamp) |
| 51 | |
| 52 | Originally written by Per Bothner. |
| 53 | Copyright 1992-2014 Free Software Foundation, Inc. |
| 54 | |
| 55 | This is free software; see the source for copying conditions. There is NO |
| 56 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 57 | |
| 58 | help=" |
| @@ -90,11 +82,11 @@ | |
| 82 | if test $# != 0; then |
| 83 | echo "$me: too many arguments$help" >&2 |
| 84 | exit 1 |
| 85 | fi |
| 86 | |
| 87 | trap 'exit 1' 1 2 15 |
| 88 | |
| 89 | # CC_FOR_BUILD -- compiler used by this script. Note that the use of a |
| 90 | # compiler to aid in system detection is discouraged as it requires |
| 91 | # temporary files to be created and, as you can see below, it is a |
| 92 | # headache to deal with in a portable fashion. |
| @@ -104,11 +96,11 @@ | |
| 96 | |
| 97 | # Portable tmp directory creation inspired by the Autoconf team. |
| 98 | |
| 99 | set_cc_for_build=' |
| 100 | trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; |
| 101 | trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; |
| 102 | : ${TMPDIR=/tmp} ; |
| 103 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || |
| 104 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || |
| 105 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || |
| 106 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; |
| @@ -137,17 +129,38 @@ | |
| 129 | |
| 130 | UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown |
| 131 | UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown |
| 132 | UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown |
| 133 | UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown |
| 134 | |
| 135 | case "${UNAME_SYSTEM}" in |
| 136 | Linux|GNU|GNU/*) |
| 137 | # If the system lacks a compiler, then just pick glibc. |
| 138 | # We could probably try harder. |
| 139 | LIBC=gnu |
| 140 | |
| 141 | eval $set_cc_for_build |
| 142 | cat <<-EOF > $dummy.c |
| 143 | #include <features.h> |
| 144 | #if defined(__UCLIBC__) |
| 145 | LIBC=uclibc |
| 146 | #elif defined(__dietlibc__) |
| 147 | LIBC=dietlibc |
| 148 | #else |
| 149 | LIBC=gnu |
| 150 | #endif |
| 151 | EOF |
| 152 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` |
| 153 | ;; |
| 154 | esac |
| 155 | |
| 156 | # Note: order is significant - the case branches are not exclusive. |
| 157 | |
| 158 | case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in |
| 159 | *:NetBSD:*:*) |
| 160 | # NetBSD (nbsd) targets should (where applicable) match one or |
| 161 | # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, |
| 162 | # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently |
| 163 | # switched to ELF, *-*-netbsd* would select the old |
| 164 | # object file format. This provides both forward |
| 165 | # compatibility and a consistent mechanism for selecting the |
| 166 | # object file format. |
| @@ -179,11 +192,11 @@ | |
| 192 | else |
| 193 | os=netbsdelf |
| 194 | fi |
| 195 | ;; |
| 196 | *) |
| 197 | os=netbsd |
| 198 | ;; |
| 199 | esac |
| 200 | # The OS release |
| 201 | # Debian GNU/NetBSD machines have a different userland, and |
| 202 | # thus, need a distinct triplet. However, they do not need |
| @@ -200,10 +213,14 @@ | |
| 213 | # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: |
| 214 | # contains redundant information, the shorter form: |
| 215 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. |
| 216 | echo "${machine}-${os}${release}" |
| 217 | exit ;; |
| 218 | *:Bitrig:*:*) |
| 219 | UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` |
| 220 | echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} |
| 221 | exit ;; |
| 222 | *:OpenBSD:*:*) |
| 223 | UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` |
| 224 | echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} |
| 225 | exit ;; |
| 226 | *:ekkoBSD:*:*) |
| @@ -222,11 +239,11 @@ | |
| 239 | case $UNAME_RELEASE in |
| 240 | *4.0) |
| 241 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` |
| 242 | ;; |
| 243 | *5.*) |
| 244 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` |
| 245 | ;; |
| 246 | esac |
| 247 | # According to Compaq, /usr/sbin/psrinfo has been available on |
| 248 | # OSF/1 and Tru64 systems produced since 1995. I hope that |
| 249 | # covers most systems running today. This code pipes the CPU |
| @@ -268,11 +285,14 @@ | |
| 285 | # A Vn.n version is a released version. |
| 286 | # A Tn.n version is a released field test version. |
| 287 | # A Xn.n version is an unreleased experimental baselevel. |
| 288 | # 1.2 uses "1.2" for uname -r. |
| 289 | echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 290 | # Reset EXIT trap before exiting to avoid spurious non-zero exit code. |
| 291 | exitcode=$? |
| 292 | trap '' 0 |
| 293 | exit $exitcode ;; |
| 294 | Alpha\ *:Windows_NT*:*) |
| 295 | # How do we know it's Interix rather than the generic POSIX subsystem? |
| 296 | # Should we change UNAME_MACHINE based on the output of uname instead |
| 297 | # of the specific Alpha model? |
| 298 | echo alpha-pc-interix |
| @@ -294,16 +314,16 @@ | |
| 314 | exit ;; |
| 315 | *:z/VM:*:*) |
| 316 | echo s390-ibm-zvmoe |
| 317 | exit ;; |
| 318 | *:OS400:*:*) |
| 319 | echo powerpc-ibm-os400 |
| 320 | exit ;; |
| 321 | arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) |
| 322 | echo arm-acorn-riscix${UNAME_RELEASE} |
| 323 | exit ;; |
| 324 | arm*:riscos:*:*|arm*:RISCOS:*:*) |
| 325 | echo arm-unknown-riscos |
| 326 | exit ;; |
| 327 | SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) |
| 328 | echo hppa1.1-hitachi-hiuxmpp |
| 329 | exit ;; |
| @@ -393,27 +413,27 @@ | |
| 413 | # to the lowercase version "mint" (or "freemint"). Finally |
| 414 | # the system name "TOS" denotes a system which is actually not |
| 415 | # MiNT. But MiNT is downward compatible to TOS, so this should |
| 416 | # be no problem. |
| 417 | atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) |
| 418 | echo m68k-atari-mint${UNAME_RELEASE} |
| 419 | exit ;; |
| 420 | atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) |
| 421 | echo m68k-atari-mint${UNAME_RELEASE} |
| 422 | exit ;; |
| 423 | *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) |
| 424 | echo m68k-atari-mint${UNAME_RELEASE} |
| 425 | exit ;; |
| 426 | milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) |
| 427 | echo m68k-milan-mint${UNAME_RELEASE} |
| 428 | exit ;; |
| 429 | hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) |
| 430 | echo m68k-hades-mint${UNAME_RELEASE} |
| 431 | exit ;; |
| 432 | *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) |
| 433 | echo m68k-unknown-mint${UNAME_RELEASE} |
| 434 | exit ;; |
| 435 | m68k:machten:*:*) |
| 436 | echo m68k-apple-machten${UNAME_RELEASE} |
| 437 | exit ;; |
| 438 | powerpc:machten:*:*) |
| 439 | echo powerpc-apple-machten${UNAME_RELEASE} |
| @@ -479,12 +499,12 @@ | |
| 499 | exit ;; |
| 500 | m88k:*:3*:R3*) |
| 501 | echo m88k-motorola-sysv3 |
| 502 | exit ;; |
| 503 | AViiON:dgux:*:*) |
| 504 | # DG/UX returns AViiON for all architectures |
| 505 | UNAME_PROCESSOR=`/usr/bin/uname -p` |
| 506 | if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] |
| 507 | then |
| 508 | if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ |
| 509 | [ ${TARGET_BINARY_INTERFACE}x = x ] |
| 510 | then |
| @@ -493,11 +513,11 @@ | |
| 513 | echo m88k-dg-dguxbcs${UNAME_RELEASE} |
| 514 | fi |
| 515 | else |
| 516 | echo i586-dg-dgux${UNAME_RELEASE} |
| 517 | fi |
| 518 | exit ;; |
| 519 | M88*:DolphinOS:*:*) # DolphinOS (SVR3) |
| 520 | echo m88k-dolphin-sysv3 |
| 521 | exit ;; |
| 522 | M88*:*:R3*:*) |
| 523 | # Delta 88k system running SVR3 |
| @@ -593,56 +613,56 @@ | |
| 613 | 9000/31? ) HP_ARCH=m68000 ;; |
| 614 | 9000/[34]?? ) HP_ARCH=m68k ;; |
| 615 | 9000/[678][0-9][0-9]) |
| 616 | if [ -x /usr/bin/getconf ]; then |
| 617 | sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` |
| 618 | sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` |
| 619 | case "${sc_cpu_version}" in |
| 620 | 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 |
| 621 | 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 |
| 622 | 532) # CPU_PA_RISC2_0 |
| 623 | case "${sc_kernel_bits}" in |
| 624 | 32) HP_ARCH="hppa2.0n" ;; |
| 625 | 64) HP_ARCH="hppa2.0w" ;; |
| 626 | '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 |
| 627 | esac ;; |
| 628 | esac |
| 629 | fi |
| 630 | if [ "${HP_ARCH}" = "" ]; then |
| 631 | eval $set_cc_for_build |
| 632 | sed 's/^ //' << EOF >$dummy.c |
| 633 | |
| 634 | #define _HPUX_SOURCE |
| 635 | #include <stdlib.h> |
| 636 | #include <unistd.h> |
| 637 | |
| 638 | int main () |
| 639 | { |
| 640 | #if defined(_SC_KERNEL_BITS) |
| 641 | long bits = sysconf(_SC_KERNEL_BITS); |
| 642 | #endif |
| 643 | long cpu = sysconf (_SC_CPU_VERSION); |
| 644 | |
| 645 | switch (cpu) |
| 646 | { |
| 647 | case CPU_PA_RISC1_0: puts ("hppa1.0"); break; |
| 648 | case CPU_PA_RISC1_1: puts ("hppa1.1"); break; |
| 649 | case CPU_PA_RISC2_0: |
| 650 | #if defined(_SC_KERNEL_BITS) |
| 651 | switch (bits) |
| 652 | { |
| 653 | case 64: puts ("hppa2.0w"); break; |
| 654 | case 32: puts ("hppa2.0n"); break; |
| 655 | default: puts ("hppa2.0"); break; |
| 656 | } break; |
| 657 | #else /* !defined(_SC_KERNEL_BITS) */ |
| 658 | puts ("hppa2.0"); break; |
| 659 | #endif |
| 660 | default: puts ("hppa1.0"); break; |
| 661 | } |
| 662 | exit (0); |
| 663 | } |
| 664 | EOF |
| 665 | (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` |
| 666 | test -z "$HP_ARCH" && HP_ARCH=hppa |
| 667 | fi ;; |
| 668 | esac |
| @@ -729,26 +749,26 @@ | |
| 749 | parisc*:Lites*:*:*) |
| 750 | echo hppa1.1-hp-lites |
| 751 | exit ;; |
| 752 | C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) |
| 753 | echo c1-convex-bsd |
| 754 | exit ;; |
| 755 | C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) |
| 756 | if getsysinfo -f scalar_acc |
| 757 | then echo c32-convex-bsd |
| 758 | else echo c2-convex-bsd |
| 759 | fi |
| 760 | exit ;; |
| 761 | C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) |
| 762 | echo c34-convex-bsd |
| 763 | exit ;; |
| 764 | C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) |
| 765 | echo c38-convex-bsd |
| 766 | exit ;; |
| 767 | C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) |
| 768 | echo c4-convex-bsd |
| 769 | exit ;; |
| 770 | CRAY*Y-MP:*:*:*) |
| 771 | echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 772 | exit ;; |
| 773 | CRAY*[A-Z]90:*:*:*) |
| 774 | echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ |
| @@ -768,18 +788,18 @@ | |
| 788 | *:UNICOS/mp:*:*) |
| 789 | echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' |
| 790 | exit ;; |
| 791 | F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) |
| 792 | FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` |
| 793 | FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` |
| 794 | FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` |
| 795 | echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" |
| 796 | exit ;; |
| 797 | 5000:UNIX_System_V:4.*:*) |
| 798 | FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` |
| 799 | FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` |
| 800 | echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" |
| 801 | exit ;; |
| 802 | i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) |
| 803 | echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} |
| 804 | exit ;; |
| 805 | sparc*:BSD/OS:*:*) |
| @@ -787,37 +807,39 @@ | |
| 807 | exit ;; |
| 808 | *:BSD/OS:*:*) |
| 809 | echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} |
| 810 | exit ;; |
| 811 | *:FreeBSD:*:*) |
| 812 | UNAME_PROCESSOR=`/usr/bin/uname -p` |
| 813 | case ${UNAME_PROCESSOR} in |
| 814 | amd64) |
| 815 | echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 816 | *) |
| 817 | echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; |
| 818 | esac |
| 819 | exit ;; |
| 820 | i*:CYGWIN*:*) |
| 821 | echo ${UNAME_MACHINE}-pc-cygwin |
| 822 | exit ;; |
| 823 | *:MINGW64*:*) |
| 824 | echo ${UNAME_MACHINE}-pc-mingw64 |
| 825 | exit ;; |
| 826 | *:MINGW*:*) |
| 827 | echo ${UNAME_MACHINE}-pc-mingw32 |
| 828 | exit ;; |
| 829 | *:MSYS*:*) |
| 830 | echo ${UNAME_MACHINE}-pc-msys |
| 831 | exit ;; |
| 832 | i*:windows32*:*) |
| 833 | # uname -m includes "-pc" on this system. |
| 834 | echo ${UNAME_MACHINE}-mingw32 |
| 835 | exit ;; |
| 836 | i*:PW*:*) |
| 837 | echo ${UNAME_MACHINE}-pc-pw32 |
| 838 | exit ;; |
| 839 | *:Interix*:*) |
| 840 | case ${UNAME_MACHINE} in |
| 841 | x86) |
| 842 | echo i586-pc-interix${UNAME_RELEASE} |
| 843 | exit ;; |
| 844 | authenticamd | genuineintel | EM64T) |
| 845 | echo x86_64-unknown-interix${UNAME_RELEASE} |
| @@ -850,74 +872,85 @@ | |
| 872 | prep*:SunOS:5.*:*) |
| 873 | echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` |
| 874 | exit ;; |
| 875 | *:GNU:*:*) |
| 876 | # the GNU system |
| 877 | echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` |
| 878 | exit ;; |
| 879 | *:GNU/*:*:*) |
| 880 | # other systems with GNU libc and userland |
| 881 | echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} |
| 882 | exit ;; |
| 883 | i*86:Minix:*:*) |
| 884 | echo ${UNAME_MACHINE}-pc-minix |
| 885 | exit ;; |
| 886 | aarch64:Linux:*:*) |
| 887 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 888 | exit ;; |
| 889 | aarch64_be:Linux:*:*) |
| 890 | UNAME_MACHINE=aarch64_be |
| 891 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 892 | exit ;; |
| 893 | alpha:Linux:*:*) |
| 894 | case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in |
| 895 | EV5) UNAME_MACHINE=alphaev5 ;; |
| 896 | EV56) UNAME_MACHINE=alphaev56 ;; |
| 897 | PCA56) UNAME_MACHINE=alphapca56 ;; |
| 898 | PCA57) UNAME_MACHINE=alphapca56 ;; |
| 899 | EV6) UNAME_MACHINE=alphaev6 ;; |
| 900 | EV67) UNAME_MACHINE=alphaev67 ;; |
| 901 | EV68*) UNAME_MACHINE=alphaev68 ;; |
| 902 | esac |
| 903 | objdump --private-headers /bin/sh | grep -q ld.so.1 |
| 904 | if test "$?" = 0 ; then LIBC="gnulibc1" ; fi |
| 905 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 906 | exit ;; |
| 907 | arc:Linux:*:* | arceb:Linux:*:*) |
| 908 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 909 | exit ;; |
| 910 | arm*:Linux:*:*) |
| 911 | eval $set_cc_for_build |
| 912 | if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
| 913 | | grep -q __ARM_EABI__ |
| 914 | then |
| 915 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 916 | else |
| 917 | if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ |
| 918 | | grep -q __ARM_PCS_VFP |
| 919 | then |
| 920 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi |
| 921 | else |
| 922 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf |
| 923 | fi |
| 924 | fi |
| 925 | exit ;; |
| 926 | avr32*:Linux:*:*) |
| 927 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 928 | exit ;; |
| 929 | cris:Linux:*:*) |
| 930 | echo ${UNAME_MACHINE}-axis-linux-${LIBC} |
| 931 | exit ;; |
| 932 | crisv32:Linux:*:*) |
| 933 | echo ${UNAME_MACHINE}-axis-linux-${LIBC} |
| 934 | exit ;; |
| 935 | frv:Linux:*:*) |
| 936 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 937 | exit ;; |
| 938 | hexagon:Linux:*:*) |
| 939 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 940 | exit ;; |
| 941 | i*86:Linux:*:*) |
| 942 | echo ${UNAME_MACHINE}-pc-linux-${LIBC} |
| 943 | exit ;; |
| 944 | ia64:Linux:*:*) |
| 945 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 946 | exit ;; |
| 947 | m32r*:Linux:*:*) |
| 948 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 949 | exit ;; |
| 950 | m68*:Linux:*:*) |
| 951 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 952 | exit ;; |
| 953 | mips:Linux:*:* | mips64:Linux:*:*) |
| 954 | eval $set_cc_for_build |
| 955 | sed 's/^ //' << EOF >$dummy.c |
| 956 | #undef CPU |
| @@ -932,71 +965,80 @@ | |
| 965 | CPU= |
| 966 | #endif |
| 967 | #endif |
| 968 | EOF |
| 969 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` |
| 970 | test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } |
| 971 | ;; |
| 972 | openrisc*:Linux:*:*) |
| 973 | echo or1k-unknown-linux-${LIBC} |
| 974 | exit ;; |
| 975 | or32:Linux:*:* | or1k*:Linux:*:*) |
| 976 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 977 | exit ;; |
| 978 | padre:Linux:*:*) |
| 979 | echo sparc-unknown-linux-${LIBC} |
| 980 | exit ;; |
| 981 | parisc64:Linux:*:* | hppa64:Linux:*:*) |
| 982 | echo hppa64-unknown-linux-${LIBC} |
| 983 | exit ;; |
| 984 | parisc:Linux:*:* | hppa:Linux:*:*) |
| 985 | # Look for CPU level |
| 986 | case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in |
| 987 | PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; |
| 988 | PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; |
| 989 | *) echo hppa-unknown-linux-${LIBC} ;; |
| 990 | esac |
| 991 | exit ;; |
| 992 | ppc64:Linux:*:*) |
| 993 | echo powerpc64-unknown-linux-${LIBC} |
| 994 | exit ;; |
| 995 | ppc:Linux:*:*) |
| 996 | echo powerpc-unknown-linux-${LIBC} |
| 997 | exit ;; |
| 998 | ppc64le:Linux:*:*) |
| 999 | echo powerpc64le-unknown-linux-${LIBC} |
| 1000 | exit ;; |
| 1001 | ppcle:Linux:*:*) |
| 1002 | echo powerpcle-unknown-linux-${LIBC} |
| 1003 | exit ;; |
| 1004 | s390:Linux:*:* | s390x:Linux:*:*) |
| 1005 | echo ${UNAME_MACHINE}-ibm-linux-${LIBC} |
| 1006 | exit ;; |
| 1007 | sh64*:Linux:*:*) |
| 1008 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1009 | exit ;; |
| 1010 | sh*:Linux:*:*) |
| 1011 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1012 | exit ;; |
| 1013 | sparc:Linux:*:* | sparc64:Linux:*:*) |
| 1014 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1015 | exit ;; |
| 1016 | tile*:Linux:*:*) |
| 1017 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1018 | exit ;; |
| 1019 | vax:Linux:*:*) |
| 1020 | echo ${UNAME_MACHINE}-dec-linux-${LIBC} |
| 1021 | exit ;; |
| 1022 | x86_64:Linux:*:*) |
| 1023 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1024 | exit ;; |
| 1025 | xtensa*:Linux:*:*) |
| 1026 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} |
| 1027 | exit ;; |
| 1028 | i*86:DYNIX/ptx:4*:*) |
| 1029 | # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. |
| 1030 | # earlier versions are messed up and put the nodename in both |
| 1031 | # sysname and nodename. |
| 1032 | echo i386-sequent-sysv4 |
| 1033 | exit ;; |
| 1034 | i*86:UNIX_SV:4.2MP:2.*) |
| 1035 | # Unixware is an offshoot of SVR4, but it has its own version |
| 1036 | # number series starting with 2... |
| 1037 | # I am not positive that other SVR4 systems won't match this, |
| 1038 | # I just have to hope. -- rms. |
| 1039 | # Use sysv4.2uw... so that sysv4* matches it. |
| 1040 | echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} |
| 1041 | exit ;; |
| 1042 | i*86:OS/2:*:*) |
| 1043 | # If we were able to find `uname', then EMX Unix compatibility |
| 1044 | # is probably installed. |
| @@ -1024,11 +1066,11 @@ | |
| 1066 | else |
| 1067 | echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} |
| 1068 | fi |
| 1069 | exit ;; |
| 1070 | i*86:*:5:[678]*) |
| 1071 | # UnixWare 7.x, OpenUNIX and OpenServer 6. |
| 1072 | case `/bin/uname -X | grep "^Machine"` in |
| 1073 | *486*) UNAME_MACHINE=i486 ;; |
| 1074 | *Pentium) UNAME_MACHINE=i586 ;; |
| 1075 | *Pent*|*Celeron) UNAME_MACHINE=i686 ;; |
| 1076 | esac |
| @@ -1052,17 +1094,17 @@ | |
| 1094 | echo ${UNAME_MACHINE}-pc-sysv32 |
| 1095 | fi |
| 1096 | exit ;; |
| 1097 | pc:*:*:*) |
| 1098 | # Left here for compatibility: |
| 1099 | # uname -m prints for DJGPP always 'pc', but it prints nothing about |
| 1100 | # the processor, so we play safe by assuming i586. |
| 1101 | # Note: whatever this is, it MUST be the same as what config.sub |
| 1102 | # prints for the "djgpp" host, or else GDB configury will decide that |
| 1103 | # this is a cross-build. |
| 1104 | echo i586-pc-msdosdjgpp |
| 1105 | exit ;; |
| 1106 | Intel:Mach:3*:*) |
| 1107 | echo i386-pc-mach3 |
| 1108 | exit ;; |
| 1109 | paragon:*:*:*) |
| 1110 | echo i860-intel-osf1 |
| @@ -1093,12 +1135,12 @@ | |
| 1135 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| 1136 | && { echo i486-ncr-sysv4.3${OS_REL}; exit; } |
| 1137 | /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ |
| 1138 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; |
| 1139 | 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) |
| 1140 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| 1141 | && { echo i486-ncr-sysv4; exit; } ;; |
| 1142 | NCR*:*:4.2:* | MPRAS*:*:4.2:*) |
| 1143 | OS_REL='.3' |
| 1144 | test -r /etc/.relid \ |
| 1145 | && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` |
| 1146 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ |
| @@ -1137,14 +1179,14 @@ | |
| 1179 | echo ${UNAME_MACHINE}-sni-sysv4 |
| 1180 | else |
| 1181 | echo ns32k-sni-sysv |
| 1182 | fi |
| 1183 | exit ;; |
| 1184 | PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort |
| 1185 | # says <[email protected]> |
| 1186 | echo i586-unisys-sysv4 |
| 1187 | exit ;; |
| 1188 | *:UNIX_System_V:4*:FTX*) |
| 1189 | # From Gerald Hewes <[email protected]>. |
| 1190 | # How about differentiating between stratus architectures? -djm |
| 1191 | echo hppa1.1-stratus-sysv4 |
| 1192 | exit ;; |
| @@ -1166,15 +1208,15 @@ | |
| 1208 | news*:NEWS-OS:6*:*) |
| 1209 | echo mips-sony-newsos6 |
| 1210 | exit ;; |
| 1211 | R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) |
| 1212 | if [ -d /usr/nec ]; then |
| 1213 | echo mips-nec-sysv${UNAME_RELEASE} |
| 1214 | else |
| 1215 | echo mips-unknown-sysv${UNAME_RELEASE} |
| 1216 | fi |
| 1217 | exit ;; |
| 1218 | BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. |
| 1219 | echo powerpc-be-beos |
| 1220 | exit ;; |
| 1221 | BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. |
| 1222 | echo powerpc-apple-beos |
| @@ -1183,10 +1225,13 @@ | |
| 1225 | echo i586-pc-beos |
| 1226 | exit ;; |
| 1227 | BePC:Haiku:*:*) # Haiku running on Intel PC compatible. |
| 1228 | echo i586-pc-haiku |
| 1229 | exit ;; |
| 1230 | x86_64:Haiku:*:*) |
| 1231 | echo x86_64-unknown-haiku |
| 1232 | exit ;; |
| 1233 | SX-4:SUPER-UX:*:*) |
| 1234 | echo sx4-nec-superux${UNAME_RELEASE} |
| 1235 | exit ;; |
| 1236 | SX-5:SUPER-UX:*:*) |
| 1237 | echo sx5-nec-superux${UNAME_RELEASE} |
| @@ -1209,23 +1254,35 @@ | |
| 1254 | *:Rhapsody:*:*) |
| 1255 | echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} |
| 1256 | exit ;; |
| 1257 | *:Darwin:*:*) |
| 1258 | UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown |
| 1259 | eval $set_cc_for_build |
| 1260 | if test "$UNAME_PROCESSOR" = unknown ; then |
| 1261 | UNAME_PROCESSOR=powerpc |
| 1262 | fi |
| 1263 | if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then |
| 1264 | if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then |
| 1265 | if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ |
| 1266 | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ |
| 1267 | grep IS_64BIT_ARCH >/dev/null |
| 1268 | then |
| 1269 | case $UNAME_PROCESSOR in |
| 1270 | i386) UNAME_PROCESSOR=x86_64 ;; |
| 1271 | powerpc) UNAME_PROCESSOR=powerpc64 ;; |
| 1272 | esac |
| 1273 | fi |
| 1274 | fi |
| 1275 | elif test "$UNAME_PROCESSOR" = i386 ; then |
| 1276 | # Avoid executing cc on OS X 10.9, as it ships with a stub |
| 1277 | # that puts up a graphical alert prompting to install |
| 1278 | # developer tools. Any system running Mac OS X 10.7 or |
| 1279 | # later (Darwin 11 and later) is required to have a 64-bit |
| 1280 | # processor. This is not true of the ARM version of Darwin |
| 1281 | # that Apple uses in portable devices. |
| 1282 | UNAME_PROCESSOR=x86_64 |
| 1283 | fi |
| 1284 | echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} |
| 1285 | exit ;; |
| 1286 | *:procnto*:*:* | *:QNX:[0123456789]*:*) |
| 1287 | UNAME_PROCESSOR=`uname -p` |
| 1288 | if test "$UNAME_PROCESSOR" = "x86"; then |
| @@ -1238,11 +1295,11 @@ | |
| 1295 | echo i386-pc-qnx |
| 1296 | exit ;; |
| 1297 | NEO-?:NONSTOP_KERNEL:*:*) |
| 1298 | echo neo-tandem-nsk${UNAME_RELEASE} |
| 1299 | exit ;; |
| 1300 | NSE-*:NONSTOP_KERNEL:*:*) |
| 1301 | echo nse-tandem-nsk${UNAME_RELEASE} |
| 1302 | exit ;; |
| 1303 | NSR-?:NONSTOP_KERNEL:*:*) |
| 1304 | echo nsr-tandem-nsk${UNAME_RELEASE} |
| 1305 | exit ;; |
| @@ -1283,17 +1340,17 @@ | |
| 1340 | exit ;; |
| 1341 | *:ITS:*:*) |
| 1342 | echo pdp10-unknown-its |
| 1343 | exit ;; |
| 1344 | SEI:*:*:SEIUX) |
| 1345 | echo mips-sei-seiux${UNAME_RELEASE} |
| 1346 | exit ;; |
| 1347 | *:DragonFly:*:*) |
| 1348 | echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` |
| 1349 | exit ;; |
| 1350 | *:*VMS:*:*) |
| 1351 | UNAME_MACHINE=`(uname -p) 2>/dev/null` |
| 1352 | case "${UNAME_MACHINE}" in |
| 1353 | A*) echo alpha-dec-vms ; exit ;; |
| 1354 | I*) echo ia64-dec-vms ; exit ;; |
| 1355 | V*) echo vax-dec-vms ; exit ;; |
| 1356 | esac ;; |
| @@ -1307,162 +1364,14 @@ | |
| 1364 | echo ${UNAME_MACHINE}-pc-rdos |
| 1365 | exit ;; |
| 1366 | i*86:AROS:*:*) |
| 1367 | echo ${UNAME_MACHINE}-pc-aros |
| 1368 | exit ;; |
| 1369 | x86_64:VMkernel:*:*) |
| 1370 | echo ${UNAME_MACHINE}-unknown-esx |
| 1371 | exit ;; |
| 1372 | esac |
| 1373 | |
| 1374 | cat >&2 <<EOF |
| 1375 | $0: unable to guess system type |
| 1376 | |
| 1377 | This script, last modified $timestamp, has failed to recognize |
| 1378 |
+154
-103
| --- autosetup/config.sub | ||
| +++ autosetup/config.sub | ||
| @@ -1,40 +1,33 @@ | ||
| 1 | 1 | #! /bin/sh |
| 2 | 2 | # Configuration validation subroutine script. |
| 3 | -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
| 4 | -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
| 5 | -# Free Software Foundation, Inc. | |
| 6 | - | |
| 7 | -timestamp='2010-09-11' | |
| 8 | - | |
| 9 | -# This file is (in principle) common to ALL GNU software. | |
| 10 | -# The presence of a machine in this file suggests that SOME GNU software | |
| 11 | -# can handle that machine. It does not imply ALL GNU software can. | |
| 12 | -# | |
| 13 | -# This file is free software; you can redistribute it and/or modify | |
| 14 | -# it under the terms of the GNU General Public License as published by | |
| 15 | -# the Free Software Foundation; either version 2 of the License, or | |
| 3 | +# Copyright 1992-2014 Free Software Foundation, Inc. | |
| 4 | + | |
| 5 | +timestamp='2014-05-01' | |
| 6 | + | |
| 7 | +# This file is free software; you can redistribute it and/or modify it | |
| 8 | +# under the terms of the GNU General Public License as published by | |
| 9 | +# the Free Software Foundation; either version 3 of the License, or | |
| 16 | 10 | # (at your option) any later version. |
| 17 | 11 | # |
| 18 | -# This program is distributed in the hope that it will be useful, | |
| 19 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 20 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 21 | -# GNU General Public License for more details. | |
| 12 | +# This program is distributed in the hope that it will be useful, but | |
| 13 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | +# General Public License for more details. | |
| 22 | 16 | # |
| 23 | 17 | # You should have received a copy of the GNU General Public License |
| 24 | -# along with this program; if not, write to the Free Software | |
| 25 | -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA | |
| 26 | -# 02110-1301, USA. | |
| 18 | +# along with this program; if not, see <http://www.gnu.org/licenses/>. | |
| 27 | 19 | # |
| 28 | 20 | # As a special exception to the GNU General Public License, if you |
| 29 | 21 | # distribute this file as part of a program that contains a |
| 30 | 22 | # configuration script generated by Autoconf, you may include it under |
| 31 | -# the same distribution terms that you use for the rest of that program. | |
| 23 | +# the same distribution terms that you use for the rest of that | |
| 24 | +# program. This Exception is an additional permission under section 7 | |
| 25 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 32 | 26 | |
| 33 | 27 | |
| 34 | -# Please send patches to <[email protected]>. Submit a context | |
| 35 | -# diff and a properly formatted GNU ChangeLog entry. | |
| 28 | +# Please send patches with a ChangeLog entry to [email protected]. | |
| 36 | 29 | # |
| 37 | 30 | # Configuration subroutine to validate and canonicalize a configuration type. |
| 38 | 31 | # Supply the specified configuration type as an argument. |
| 39 | 32 | # If it is invalid, we print an error message on stderr and exit with code 1. |
| 40 | 33 | # Otherwise, we print the canonical config type on stdout and succeed. |
| @@ -73,13 +66,11 @@ | ||
| 73 | 66 | Report bugs and patches to <[email protected]>." |
| 74 | 67 | |
| 75 | 68 | version="\ |
| 76 | 69 | GNU config.sub ($timestamp) |
| 77 | 70 | |
| 78 | -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |
| 79 | -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free | |
| 80 | -Software Foundation, Inc. | |
| 71 | +Copyright 1992-2014 Free Software Foundation, Inc. | |
| 81 | 72 | |
| 82 | 73 | This is free software; see the source for copying conditions. There is NO |
| 83 | 74 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 84 | 75 | |
| 85 | 76 | help=" |
| @@ -123,17 +114,21 @@ | ||
| 123 | 114 | # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). |
| 124 | 115 | # Here we must recognize all the valid KERNEL-OS combinations. |
| 125 | 116 | maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` |
| 126 | 117 | case $maybe_os in |
| 127 | 118 | nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ |
| 128 | - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ | |
| 119 | + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ | |
| 129 | 120 | knetbsd*-gnu* | netbsd*-gnu* | \ |
| 130 | 121 | kopensolaris*-gnu* | \ |
| 131 | 122 | storm-chaos* | os2-emx* | rtmk-nova*) |
| 132 | 123 | os=-$maybe_os |
| 133 | 124 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` |
| 134 | 125 | ;; |
| 126 | + android-linux) | |
| 127 | + os=-linux-android | |
| 128 | + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown | |
| 129 | + ;; | |
| 135 | 130 | *) |
| 136 | 131 | basic_machine=`echo $1 | sed 's/-[^-]*$//'` |
| 137 | 132 | if [ $basic_machine != $1 ] |
| 138 | 133 | then os=`echo $1 | sed 's/.*-/-/'` |
| 139 | 134 | else os=; fi |
| @@ -152,16 +147,16 @@ | ||
| 152 | 147 | -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ |
| 153 | 148 | -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ |
| 154 | 149 | -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ |
| 155 | 150 | -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ |
| 156 | 151 | -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ |
| 157 | - -apple | -axis | -knuth | -cray | -microblaze) | |
| 152 | + -apple | -axis | -knuth | -cray | -microblaze*) | |
| 158 | 153 | os= |
| 159 | 154 | basic_machine=$1 |
| 160 | 155 | ;; |
| 161 | - -bluegene*) | |
| 162 | - os=-cnk | |
| 156 | + -bluegene*) | |
| 157 | + os=-cnk | |
| 163 | 158 | ;; |
| 164 | 159 | -sim | -cisco | -oki | -wec | -winbond) |
| 165 | 160 | os= |
| 166 | 161 | basic_machine=$1 |
| 167 | 162 | ;; |
| @@ -173,14 +168,14 @@ | ||
| 173 | 168 | ;; |
| 174 | 169 | -chorusos*) |
| 175 | 170 | os=-chorusos |
| 176 | 171 | basic_machine=$1 |
| 177 | 172 | ;; |
| 178 | - -chorusrdb) | |
| 179 | - os=-chorusrdb | |
| 173 | + -chorusrdb) | |
| 174 | + os=-chorusrdb | |
| 180 | 175 | basic_machine=$1 |
| 181 | - ;; | |
| 176 | + ;; | |
| 182 | 177 | -hiux*) |
| 183 | 178 | os=-hiuxwe2 |
| 184 | 179 | ;; |
| 185 | 180 | -sco6) |
| 186 | 181 | os=-sco5v6 |
| @@ -221,10 +216,16 @@ | ||
| 221 | 216 | basic_machine=clipper-intergraph |
| 222 | 217 | ;; |
| 223 | 218 | -isc*) |
| 224 | 219 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` |
| 225 | 220 | ;; |
| 221 | + -lynx*178) | |
| 222 | + os=-lynxos178 | |
| 223 | + ;; | |
| 224 | + -lynx*5) | |
| 225 | + os=-lynxos5 | |
| 226 | + ;; | |
| 226 | 227 | -lynx*) |
| 227 | 228 | os=-lynxos |
| 228 | 229 | ;; |
| 229 | 230 | -ptx*) |
| 230 | 231 | basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` |
| @@ -245,24 +246,32 @@ | ||
| 245 | 246 | case $basic_machine in |
| 246 | 247 | # Recognize the basic CPU types without company name. |
| 247 | 248 | # Some are omitted here because they have special meanings below. |
| 248 | 249 | 1750a | 580 \ |
| 249 | 250 | | a29k \ |
| 251 | + | aarch64 | aarch64_be \ | |
| 250 | 252 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ |
| 251 | 253 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ |
| 252 | 254 | | am33_2.0 \ |
| 253 | - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | |
| 255 | + | arc | arceb \ | |
| 256 | + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | |
| 257 | + | avr | avr32 \ | |
| 258 | + | be32 | be64 \ | |
| 254 | 259 | | bfin \ |
| 255 | - | c4x | clipper \ | |
| 260 | + | c4x | c8051 | clipper \ | |
| 256 | 261 | | d10v | d30v | dlx | dsp16xx \ |
| 262 | + | epiphany \ | |
| 257 | 263 | | fido | fr30 | frv \ |
| 258 | 264 | | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ |
| 265 | + | hexagon \ | |
| 259 | 266 | | i370 | i860 | i960 | ia64 \ |
| 260 | 267 | | ip2k | iq2000 \ |
| 268 | + | k1om \ | |
| 269 | + | le32 | le64 \ | |
| 261 | 270 | | lm32 \ |
| 262 | 271 | | m32c | m32r | m32rle | m68000 | m68k | m88k \ |
| 263 | - | maxq | mb | microblaze | mcore | mep | metag \ | |
| 272 | + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | |
| 264 | 273 | | mips | mipsbe | mipseb | mipsel | mipsle \ |
| 265 | 274 | | mips16 \ |
| 266 | 275 | | mips64 | mips64el \ |
| 267 | 276 | | mips64octeon | mips64octeonel \ |
| 268 | 277 | | mips64orion | mips64orionel \ |
| @@ -272,38 +281,41 @@ | ||
| 272 | 281 | | mips64vr4300 | mips64vr4300el \ |
| 273 | 282 | | mips64vr5000 | mips64vr5000el \ |
| 274 | 283 | | mips64vr5900 | mips64vr5900el \ |
| 275 | 284 | | mipsisa32 | mipsisa32el \ |
| 276 | 285 | | mipsisa32r2 | mipsisa32r2el \ |
| 286 | + | mipsisa32r6 | mipsisa32r6el \ | |
| 277 | 287 | | mipsisa64 | mipsisa64el \ |
| 278 | 288 | | mipsisa64r2 | mipsisa64r2el \ |
| 289 | + | mipsisa64r6 | mipsisa64r6el \ | |
| 279 | 290 | | mipsisa64sb1 | mipsisa64sb1el \ |
| 280 | 291 | | mipsisa64sr71k | mipsisa64sr71kel \ |
| 292 | + | mipsr5900 | mipsr5900el \ | |
| 281 | 293 | | mipstx39 | mipstx39el \ |
| 282 | 294 | | mn10200 | mn10300 \ |
| 283 | 295 | | moxie \ |
| 284 | 296 | | mt \ |
| 285 | 297 | | msp430 \ |
| 286 | 298 | | nds32 | nds32le | nds32be \ |
| 287 | - | nios | nios2 \ | |
| 299 | + | nios | nios2 | nios2eb | nios2el \ | |
| 288 | 300 | | ns16k | ns32k \ |
| 289 | - | or32 \ | |
| 301 | + | open8 | or1k | or1knd | or32 \ | |
| 290 | 302 | | pdp10 | pdp11 | pj | pjl \ |
| 291 | - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | |
| 303 | + | powerpc | powerpc64 | powerpc64le | powerpcle \ | |
| 292 | 304 | | pyramid \ |
| 293 | - | rx \ | |
| 305 | + | rl78 | rx \ | |
| 294 | 306 | | score \ |
| 295 | 307 | | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ |
| 296 | 308 | | sh64 | sh64le \ |
| 297 | 309 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ |
| 298 | 310 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ |
| 299 | - | spu | strongarm \ | |
| 300 | - | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | |
| 311 | + | spu \ | |
| 312 | + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | |
| 301 | 313 | | ubicom32 \ |
| 302 | - | v850 | v850e \ | |
| 314 | + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | |
| 303 | 315 | | we32k \ |
| 304 | - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | |
| 316 | + | x86 | xc16x | xstormy16 | xtensa \ | |
| 305 | 317 | | z8k | z80) |
| 306 | 318 | basic_machine=$basic_machine-unknown |
| 307 | 319 | ;; |
| 308 | 320 | c54x) |
| 309 | 321 | basic_machine=tic54x-unknown |
| @@ -312,20 +324,34 @@ | ||
| 312 | 324 | basic_machine=tic55x-unknown |
| 313 | 325 | ;; |
| 314 | 326 | c6x) |
| 315 | 327 | basic_machine=tic6x-unknown |
| 316 | 328 | ;; |
| 317 | - m6811 | m68hc11 | m6812 | m68hc12 | picochip) | |
| 318 | - # Motorola 68HC11/12. | |
| 329 | + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) | |
| 319 | 330 | basic_machine=$basic_machine-unknown |
| 320 | 331 | os=-none |
| 321 | 332 | ;; |
| 322 | 333 | m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) |
| 323 | 334 | ;; |
| 324 | 335 | ms1) |
| 325 | 336 | basic_machine=mt-unknown |
| 326 | 337 | ;; |
| 338 | + | |
| 339 | + strongarm | thumb | xscale) | |
| 340 | + basic_machine=arm-unknown | |
| 341 | + ;; | |
| 342 | + xgate) | |
| 343 | + basic_machine=$basic_machine-unknown | |
| 344 | + os=-none | |
| 345 | + ;; | |
| 346 | + xscaleeb) | |
| 347 | + basic_machine=armeb-unknown | |
| 348 | + ;; | |
| 349 | + | |
| 350 | + xscaleel) | |
| 351 | + basic_machine=armel-unknown | |
| 352 | + ;; | |
| 327 | 353 | |
| 328 | 354 | # We use `pc' rather than `unknown' |
| 329 | 355 | # because (1) that's what they normally are, and |
| 330 | 356 | # (2) the word "unknown" tends to confuse beginning users. |
| 331 | 357 | i*86 | x86_64) |
| @@ -337,29 +363,35 @@ | ||
| 337 | 363 | exit 1 |
| 338 | 364 | ;; |
| 339 | 365 | # Recognize the basic CPU types with company name. |
| 340 | 366 | 580-* \ |
| 341 | 367 | | a29k-* \ |
| 368 | + | aarch64-* | aarch64_be-* \ | |
| 342 | 369 | | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ |
| 343 | 370 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ |
| 344 | - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | |
| 371 | + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | |
| 345 | 372 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ |
| 346 | 373 | | avr-* | avr32-* \ |
| 374 | + | be32-* | be64-* \ | |
| 347 | 375 | | bfin-* | bs2000-* \ |
| 348 | 376 | | c[123]* | c30-* | [cjt]90-* | c4x-* \ |
| 349 | - | clipper-* | craynv-* | cydra-* \ | |
| 377 | + | c8051-* | clipper-* | craynv-* | cydra-* \ | |
| 350 | 378 | | d10v-* | d30v-* | dlx-* \ |
| 351 | 379 | | elxsi-* \ |
| 352 | 380 | | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ |
| 353 | 381 | | h8300-* | h8500-* \ |
| 354 | 382 | | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ |
| 383 | + | hexagon-* \ | |
| 355 | 384 | | i*86-* | i860-* | i960-* | ia64-* \ |
| 356 | 385 | | ip2k-* | iq2000-* \ |
| 386 | + | k1om-* \ | |
| 387 | + | le32-* | le64-* \ | |
| 357 | 388 | | lm32-* \ |
| 358 | 389 | | m32c-* | m32r-* | m32rle-* \ |
| 359 | 390 | | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ |
| 360 | - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | |
| 391 | + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | |
| 392 | + | microblaze-* | microblazeel-* \ | |
| 361 | 393 | | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ |
| 362 | 394 | | mips16-* \ |
| 363 | 395 | | mips64-* | mips64el-* \ |
| 364 | 396 | | mips64octeon-* | mips64octeonel-* \ |
| 365 | 397 | | mips64orion-* | mips64orionel-* \ |
| @@ -369,39 +401,45 @@ | ||
| 369 | 401 | | mips64vr4300-* | mips64vr4300el-* \ |
| 370 | 402 | | mips64vr5000-* | mips64vr5000el-* \ |
| 371 | 403 | | mips64vr5900-* | mips64vr5900el-* \ |
| 372 | 404 | | mipsisa32-* | mipsisa32el-* \ |
| 373 | 405 | | mipsisa32r2-* | mipsisa32r2el-* \ |
| 406 | + | mipsisa32r6-* | mipsisa32r6el-* \ | |
| 374 | 407 | | mipsisa64-* | mipsisa64el-* \ |
| 375 | 408 | | mipsisa64r2-* | mipsisa64r2el-* \ |
| 409 | + | mipsisa64r6-* | mipsisa64r6el-* \ | |
| 376 | 410 | | mipsisa64sb1-* | mipsisa64sb1el-* \ |
| 377 | 411 | | mipsisa64sr71k-* | mipsisa64sr71kel-* \ |
| 412 | + | mipsr5900-* | mipsr5900el-* \ | |
| 378 | 413 | | mipstx39-* | mipstx39el-* \ |
| 379 | 414 | | mmix-* \ |
| 380 | 415 | | mt-* \ |
| 381 | 416 | | msp430-* \ |
| 382 | 417 | | nds32-* | nds32le-* | nds32be-* \ |
| 383 | - | nios-* | nios2-* \ | |
| 418 | + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | |
| 384 | 419 | | none-* | np1-* | ns16k-* | ns32k-* \ |
| 420 | + | open8-* \ | |
| 421 | + | or1k*-* \ | |
| 385 | 422 | | orion-* \ |
| 386 | 423 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ |
| 387 | - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | |
| 424 | + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | |
| 388 | 425 | | pyramid-* \ |
| 389 | - | romp-* | rs6000-* | rx-* \ | |
| 426 | + | rl78-* | romp-* | rs6000-* | rx-* \ | |
| 390 | 427 | | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ |
| 391 | 428 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ |
| 392 | 429 | | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ |
| 393 | 430 | | sparclite-* \ |
| 394 | - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | |
| 395 | - | tahoe-* | thumb-* \ | |
| 431 | + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | |
| 432 | + | tahoe-* \ | |
| 396 | 433 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ |
| 397 | - | tile-* | tilegx-* \ | |
| 434 | + | tile*-* \ | |
| 398 | 435 | | tron-* \ |
| 399 | 436 | | ubicom32-* \ |
| 400 | - | v850-* | v850e-* | vax-* \ | |
| 437 | + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | |
| 438 | + | vax-* \ | |
| 401 | 439 | | we32k-* \ |
| 402 | - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | |
| 440 | + | x86-* | x86_64-* | xc16x-* | xps100-* \ | |
| 403 | 441 | | xstormy16-* | xtensa*-* \ |
| 404 | 442 | | ymp-* \ |
| 405 | 443 | | z8k-* | z80-*) |
| 406 | 444 | ;; |
| 407 | 445 | # Recognize the basic CPU types without company name, with glob match. |
| @@ -422,11 +460,11 @@ | ||
| 422 | 460 | ;; |
| 423 | 461 | a29khif) |
| 424 | 462 | basic_machine=a29k-amd |
| 425 | 463 | os=-udi |
| 426 | 464 | ;; |
| 427 | - abacus) | |
| 465 | + abacus) | |
| 428 | 466 | basic_machine=abacus-unknown |
| 429 | 467 | ;; |
| 430 | 468 | adobe68k) |
| 431 | 469 | basic_machine=m68010-adobe |
| 432 | 470 | os=-scout |
| @@ -505,11 +543,11 @@ | ||
| 505 | 543 | ;; |
| 506 | 544 | c90) |
| 507 | 545 | basic_machine=c90-cray |
| 508 | 546 | os=-unicos |
| 509 | 547 | ;; |
| 510 | - cegcc) | |
| 548 | + cegcc) | |
| 511 | 549 | basic_machine=arm-unknown |
| 512 | 550 | os=-cegcc |
| 513 | 551 | ;; |
| 514 | 552 | convex-c1) |
| 515 | 553 | basic_machine=c1-convex |
| @@ -537,11 +575,11 @@ | ||
| 537 | 575 | ;; |
| 538 | 576 | craynv) |
| 539 | 577 | basic_machine=craynv-cray |
| 540 | 578 | os=-unicosmp |
| 541 | 579 | ;; |
| 542 | - cr16) | |
| 580 | + cr16 | cr16-*) | |
| 543 | 581 | basic_machine=cr16-unknown |
| 544 | 582 | os=-elf |
| 545 | 583 | ;; |
| 546 | 584 | crds | unos) |
| 547 | 585 | basic_machine=m68k-crds |
| @@ -695,11 +733,10 @@ | ||
| 695 | 733 | os=-proelf |
| 696 | 734 | ;; |
| 697 | 735 | i370-ibm* | ibm*) |
| 698 | 736 | basic_machine=i370-ibm |
| 699 | 737 | ;; |
| 700 | -# I'm not sure what "Sysv32" means. Should this be sysv3.2? | |
| 701 | 738 | i*86v32) |
| 702 | 739 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` |
| 703 | 740 | os=-sysv32 |
| 704 | 741 | ;; |
| 705 | 742 | i*86v4*) |
| @@ -753,15 +790,19 @@ | ||
| 753 | 790 | ;; |
| 754 | 791 | merlin) |
| 755 | 792 | basic_machine=ns32k-utek |
| 756 | 793 | os=-sysv |
| 757 | 794 | ;; |
| 758 | - microblaze) | |
| 795 | + microblaze*) | |
| 759 | 796 | basic_machine=microblaze-xilinx |
| 760 | 797 | ;; |
| 798 | + mingw64) | |
| 799 | + basic_machine=x86_64-pc | |
| 800 | + os=-mingw64 | |
| 801 | + ;; | |
| 761 | 802 | mingw32) |
| 762 | - basic_machine=i386-pc | |
| 803 | + basic_machine=i686-pc | |
| 763 | 804 | os=-mingw32 |
| 764 | 805 | ;; |
| 765 | 806 | mingw32ce) |
| 766 | 807 | basic_machine=arm-unknown |
| 767 | 808 | os=-mingw32ce |
| @@ -792,18 +833,22 @@ | ||
| 792 | 833 | os=-msdos |
| 793 | 834 | ;; |
| 794 | 835 | ms1-*) |
| 795 | 836 | basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` |
| 796 | 837 | ;; |
| 838 | + msys) | |
| 839 | + basic_machine=i686-pc | |
| 840 | + os=-msys | |
| 841 | + ;; | |
| 797 | 842 | mvs) |
| 798 | 843 | basic_machine=i370-ibm |
| 799 | 844 | os=-mvs |
| 800 | 845 | ;; |
| 801 | - msys) | |
| 802 | - basic_machine=i386-pc | |
| 803 | - os=-msys | |
| 804 | - ;; | |
| 846 | + nacl) | |
| 847 | + basic_machine=le32-unknown | |
| 848 | + os=-nacl | |
| 849 | + ;; | |
| 805 | 850 | ncr3000) |
| 806 | 851 | basic_machine=i486-ncr |
| 807 | 852 | os=-sysv4 |
| 808 | 853 | ;; |
| 809 | 854 | netbsd386) |
| @@ -864,14 +909,14 @@ | ||
| 864 | 909 | os=-nonstopux |
| 865 | 910 | ;; |
| 866 | 911 | np1) |
| 867 | 912 | basic_machine=np1-gould |
| 868 | 913 | ;; |
| 869 | - neo-tandem) | |
| 914 | + neo-tandem) | |
| 870 | 915 | basic_machine=neo-tandem |
| 871 | 916 | ;; |
| 872 | - nse-tandem) | |
| 917 | + nse-tandem) | |
| 873 | 918 | basic_machine=nse-tandem |
| 874 | 919 | ;; |
| 875 | 920 | nsr-tandem) |
| 876 | 921 | basic_machine=nsr-tandem |
| 877 | 922 | ;; |
| @@ -952,13 +997,14 @@ | ||
| 952 | 997 | pn) |
| 953 | 998 | basic_machine=pn-gould |
| 954 | 999 | ;; |
| 955 | 1000 | power) basic_machine=power-ibm |
| 956 | 1001 | ;; |
| 957 | - ppc) basic_machine=powerpc-unknown | |
| 1002 | + ppc | ppcbe) basic_machine=powerpc-unknown | |
| 958 | 1003 | ;; |
| 959 | - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` | |
| 1004 | + ppc-* | ppcbe-*) | |
| 1005 | + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` | |
| 960 | 1006 | ;; |
| 961 | 1007 | ppcle | powerpclittle | ppc-le | powerpc-little) |
| 962 | 1008 | basic_machine=powerpcle-unknown |
| 963 | 1009 | ;; |
| 964 | 1010 | ppcle-* | powerpclittle-*) |
| @@ -979,11 +1025,15 @@ | ||
| 979 | 1025 | ;; |
| 980 | 1026 | pw32) |
| 981 | 1027 | basic_machine=i586-unknown |
| 982 | 1028 | os=-pw32 |
| 983 | 1029 | ;; |
| 984 | - rdos) | |
| 1030 | + rdos | rdos64) | |
| 1031 | + basic_machine=x86_64-pc | |
| 1032 | + os=-rdos | |
| 1033 | + ;; | |
| 1034 | + rdos32) | |
| 985 | 1035 | basic_machine=i386-pc |
| 986 | 1036 | os=-rdos |
| 987 | 1037 | ;; |
| 988 | 1038 | rom68k) |
| 989 | 1039 | basic_machine=m68k-rom68k |
| @@ -1048,10 +1098,13 @@ | ||
| 1048 | 1098 | ;; |
| 1049 | 1099 | stratus) |
| 1050 | 1100 | basic_machine=i860-stratus |
| 1051 | 1101 | os=-sysv4 |
| 1052 | 1102 | ;; |
| 1103 | + strongarm-* | thumb-*) | |
| 1104 | + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` | |
| 1105 | + ;; | |
| 1053 | 1106 | sun2) |
| 1054 | 1107 | basic_machine=m68000-sun |
| 1055 | 1108 | ;; |
| 1056 | 1109 | sun2os3) |
| 1057 | 1110 | basic_machine=m68000-sun |
| @@ -1104,17 +1157,12 @@ | ||
| 1104 | 1157 | ;; |
| 1105 | 1158 | t90) |
| 1106 | 1159 | basic_machine=t90-cray |
| 1107 | 1160 | os=-unicos |
| 1108 | 1161 | ;; |
| 1109 | - # This must be matched before tile*. | |
| 1110 | - tilegx*) | |
| 1111 | - basic_machine=tilegx-unknown | |
| 1112 | - os=-linux-gnu | |
| 1113 | - ;; | |
| 1114 | 1162 | tile*) |
| 1115 | - basic_machine=tile-unknown | |
| 1163 | + basic_machine=$basic_machine-unknown | |
| 1116 | 1164 | os=-linux-gnu |
| 1117 | 1165 | ;; |
| 1118 | 1166 | tx39) |
| 1119 | 1167 | basic_machine=mipstx39-unknown |
| 1120 | 1168 | ;; |
| @@ -1180,10 +1228,13 @@ | ||
| 1180 | 1228 | os=-mingw32 |
| 1181 | 1229 | ;; |
| 1182 | 1230 | xps | xps100) |
| 1183 | 1231 | basic_machine=xps100-honeywell |
| 1184 | 1232 | ;; |
| 1233 | + xscale-* | xscalee[bl]-*) | |
| 1234 | + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` | |
| 1235 | + ;; | |
| 1185 | 1236 | ymp) |
| 1186 | 1237 | basic_machine=ymp-cray |
| 1187 | 1238 | os=-unicos |
| 1188 | 1239 | ;; |
| 1189 | 1240 | z8k-*-coff) |
| @@ -1277,15 +1328,15 @@ | ||
| 1277 | 1328 | # Decode manufacturer-specific aliases for certain operating systems. |
| 1278 | 1329 | |
| 1279 | 1330 | if [ x"$os" != x"" ] |
| 1280 | 1331 | then |
| 1281 | 1332 | case $os in |
| 1282 | - # First match some system type aliases | |
| 1283 | - # that might get confused with valid system types. | |
| 1333 | + # First match some system type aliases | |
| 1334 | + # that might get confused with valid system types. | |
| 1284 | 1335 | # -solaris* is a basic system type, with this one exception. |
| 1285 | - -auroraux) | |
| 1286 | - os=-auroraux | |
| 1336 | + -auroraux) | |
| 1337 | + os=-auroraux | |
| 1287 | 1338 | ;; |
| 1288 | 1339 | -solaris1 | -solaris1.*) |
| 1289 | 1340 | os=`echo $os | sed -e 's|solaris1|sunos4|'` |
| 1290 | 1341 | ;; |
| 1291 | 1342 | -solaris) |
| @@ -1305,33 +1356,33 @@ | ||
| 1305 | 1356 | # Each alternative MUST END IN A *, to match a version number. |
| 1306 | 1357 | # -sysv* is not here because it comes later, after sysvr4. |
| 1307 | 1358 | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ |
| 1308 | 1359 | | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ |
| 1309 | 1360 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ |
| 1310 | - | -sym* | -kopensolaris* \ | |
| 1361 | + | -sym* | -kopensolaris* | -plan9* \ | |
| 1311 | 1362 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ |
| 1312 | 1363 | | -aos* | -aros* \ |
| 1313 | 1364 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ |
| 1314 | 1365 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ |
| 1315 | 1366 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ |
| 1316 | - | -openbsd* | -solidbsd* \ | |
| 1367 | + | -bitrig* | -openbsd* | -solidbsd* \ | |
| 1317 | 1368 | | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ |
| 1318 | 1369 | | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ |
| 1319 | 1370 | | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ |
| 1320 | 1371 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ |
| 1321 | 1372 | | -chorusos* | -chorusrdb* | -cegcc* \ |
| 1322 | 1373 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ |
| 1323 | - | -mingw32* | -linux-gnu* | -linux-android* \ | |
| 1324 | - | -linux-newlib* | -linux-uclibc* \ | |
| 1374 | + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | |
| 1375 | + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | |
| 1325 | 1376 | | -uxpv* | -beos* | -mpeix* | -udk* \ |
| 1326 | 1377 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ |
| 1327 | 1378 | | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ |
| 1328 | 1379 | | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ |
| 1329 | 1380 | | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ |
| 1330 | 1381 | | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ |
| 1331 | 1382 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ |
| 1332 | - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) | |
| 1383 | + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) | |
| 1333 | 1384 | # Remember, each alternative MUST END IN *, to match a version number. |
| 1334 | 1385 | ;; |
| 1335 | 1386 | -qnx*) |
| 1336 | 1387 | case $basic_machine in |
| 1337 | 1388 | x86-* | i*86-*) |
| @@ -1366,11 +1417,11 @@ | ||
| 1366 | 1417 | os=`echo $os | sed -e 's|sunos6|solaris3|'` |
| 1367 | 1418 | ;; |
| 1368 | 1419 | -opened*) |
| 1369 | 1420 | os=-openedition |
| 1370 | 1421 | ;; |
| 1371 | - -os400*) | |
| 1422 | + -os400*) | |
| 1372 | 1423 | os=-os400 |
| 1373 | 1424 | ;; |
| 1374 | 1425 | -wince*) |
| 1375 | 1426 | os=-wince |
| 1376 | 1427 | ;; |
| @@ -1415,11 +1466,11 @@ | ||
| 1415 | 1466 | os=`echo $os | sed -e 's|sinix|sysv|'` |
| 1416 | 1467 | ;; |
| 1417 | 1468 | -sinix*) |
| 1418 | 1469 | os=-sysv4 |
| 1419 | 1470 | ;; |
| 1420 | - -tpf*) | |
| 1471 | + -tpf*) | |
| 1421 | 1472 | os=-tpf |
| 1422 | 1473 | ;; |
| 1423 | 1474 | -triton*) |
| 1424 | 1475 | os=-sysv3 |
| 1425 | 1476 | ;; |
| @@ -1451,21 +1502,18 @@ | ||
| 1451 | 1502 | os=-mint |
| 1452 | 1503 | ;; |
| 1453 | 1504 | -aros*) |
| 1454 | 1505 | os=-aros |
| 1455 | 1506 | ;; |
| 1456 | - -kaos*) | |
| 1457 | - os=-kaos | |
| 1458 | - ;; | |
| 1459 | 1507 | -zvmoe) |
| 1460 | 1508 | os=-zvmoe |
| 1461 | 1509 | ;; |
| 1462 | 1510 | -dicos*) |
| 1463 | 1511 | os=-dicos |
| 1464 | 1512 | ;; |
| 1465 | - -nacl*) | |
| 1466 | - ;; | |
| 1513 | + -nacl*) | |
| 1514 | + ;; | |
| 1467 | 1515 | -none) |
| 1468 | 1516 | ;; |
| 1469 | 1517 | *) |
| 1470 | 1518 | # Get rid of the `-' at the beginning of $os. |
| 1471 | 1519 | os=`echo $os | sed 's/[^-]*-//'` |
| @@ -1484,14 +1532,14 @@ | ||
| 1484 | 1532 | # that MANUFACTURER isn't an operating system. Otherwise, code above |
| 1485 | 1533 | # will signal an error saying that MANUFACTURER isn't an operating |
| 1486 | 1534 | # system, and we'll never get to this point. |
| 1487 | 1535 | |
| 1488 | 1536 | case $basic_machine in |
| 1489 | - score-*) | |
| 1537 | + score-*) | |
| 1490 | 1538 | os=-elf |
| 1491 | 1539 | ;; |
| 1492 | - spu-*) | |
| 1540 | + spu-*) | |
| 1493 | 1541 | os=-elf |
| 1494 | 1542 | ;; |
| 1495 | 1543 | *-acorn) |
| 1496 | 1544 | os=-riscix1.2 |
| 1497 | 1545 | ;; |
| @@ -1499,12 +1547,18 @@ | ||
| 1499 | 1547 | os=-linux |
| 1500 | 1548 | ;; |
| 1501 | 1549 | arm*-semi) |
| 1502 | 1550 | os=-aout |
| 1503 | 1551 | ;; |
| 1504 | - c4x-* | tic4x-*) | |
| 1505 | - os=-coff | |
| 1552 | + c4x-* | tic4x-*) | |
| 1553 | + os=-coff | |
| 1554 | + ;; | |
| 1555 | + c8051-*) | |
| 1556 | + os=-elf | |
| 1557 | + ;; | |
| 1558 | + hexagon-*) | |
| 1559 | + os=-elf | |
| 1506 | 1560 | ;; |
| 1507 | 1561 | tic54x-*) |
| 1508 | 1562 | os=-coff |
| 1509 | 1563 | ;; |
| 1510 | 1564 | tic55x-*) |
| @@ -1529,18 +1583,15 @@ | ||
| 1529 | 1583 | i386-sun) |
| 1530 | 1584 | os=-sunos4.0.2 |
| 1531 | 1585 | ;; |
| 1532 | 1586 | m68000-sun) |
| 1533 | 1587 | os=-sunos3 |
| 1534 | - # This also exists in the configure program, but was not the | |
| 1535 | - # default. | |
| 1536 | - # os=-sunos4 | |
| 1537 | 1588 | ;; |
| 1538 | 1589 | m68*-cisco) |
| 1539 | 1590 | os=-aout |
| 1540 | 1591 | ;; |
| 1541 | - mep-*) | |
| 1592 | + mep-*) | |
| 1542 | 1593 | os=-elf |
| 1543 | 1594 | ;; |
| 1544 | 1595 | mips*-cisco) |
| 1545 | 1596 | os=-elf |
| 1546 | 1597 | ;; |
| @@ -1563,11 +1614,11 @@ | ||
| 1563 | 1614 | os=-haiku |
| 1564 | 1615 | ;; |
| 1565 | 1616 | *-ibm) |
| 1566 | 1617 | os=-aix |
| 1567 | 1618 | ;; |
| 1568 | - *-knuth) | |
| 1619 | + *-knuth) | |
| 1569 | 1620 | os=-mmixware |
| 1570 | 1621 | ;; |
| 1571 | 1622 | *-wec) |
| 1572 | 1623 | os=-proelf |
| 1573 | 1624 | ;; |
| 1574 | 1625 |
| --- autosetup/config.sub | |
| +++ autosetup/config.sub | |
| @@ -1,40 +1,33 @@ | |
| 1 | #! /bin/sh |
| 2 | # Configuration validation subroutine script. |
| 3 | # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
| 4 | # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
| 5 | # Free Software Foundation, Inc. |
| 6 | |
| 7 | timestamp='2010-09-11' |
| 8 | |
| 9 | # This file is (in principle) common to ALL GNU software. |
| 10 | # The presence of a machine in this file suggests that SOME GNU software |
| 11 | # can handle that machine. It does not imply ALL GNU software can. |
| 12 | # |
| 13 | # This file is free software; you can redistribute it and/or modify |
| 14 | # it under the terms of the GNU General Public License as published by |
| 15 | # the Free Software Foundation; either version 2 of the License, or |
| 16 | # (at your option) any later version. |
| 17 | # |
| 18 | # This program is distributed in the hope that it will be useful, |
| 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 | # GNU General Public License for more details. |
| 22 | # |
| 23 | # You should have received a copy of the GNU General Public License |
| 24 | # along with this program; if not, write to the Free Software |
| 25 | # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA |
| 26 | # 02110-1301, USA. |
| 27 | # |
| 28 | # As a special exception to the GNU General Public License, if you |
| 29 | # distribute this file as part of a program that contains a |
| 30 | # configuration script generated by Autoconf, you may include it under |
| 31 | # the same distribution terms that you use for the rest of that program. |
| 32 | |
| 33 | |
| 34 | # Please send patches to <[email protected]>. Submit a context |
| 35 | # diff and a properly formatted GNU ChangeLog entry. |
| 36 | # |
| 37 | # Configuration subroutine to validate and canonicalize a configuration type. |
| 38 | # Supply the specified configuration type as an argument. |
| 39 | # If it is invalid, we print an error message on stderr and exit with code 1. |
| 40 | # Otherwise, we print the canonical config type on stdout and succeed. |
| @@ -73,13 +66,11 @@ | |
| 73 | Report bugs and patches to <[email protected]>." |
| 74 | |
| 75 | version="\ |
| 76 | GNU config.sub ($timestamp) |
| 77 | |
| 78 | Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
| 79 | 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free |
| 80 | Software Foundation, Inc. |
| 81 | |
| 82 | This is free software; see the source for copying conditions. There is NO |
| 83 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 84 | |
| 85 | help=" |
| @@ -123,17 +114,21 @@ | |
| 123 | # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). |
| 124 | # Here we must recognize all the valid KERNEL-OS combinations. |
| 125 | maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` |
| 126 | case $maybe_os in |
| 127 | nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ |
| 128 | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ |
| 129 | knetbsd*-gnu* | netbsd*-gnu* | \ |
| 130 | kopensolaris*-gnu* | \ |
| 131 | storm-chaos* | os2-emx* | rtmk-nova*) |
| 132 | os=-$maybe_os |
| 133 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` |
| 134 | ;; |
| 135 | *) |
| 136 | basic_machine=`echo $1 | sed 's/-[^-]*$//'` |
| 137 | if [ $basic_machine != $1 ] |
| 138 | then os=`echo $1 | sed 's/.*-/-/'` |
| 139 | else os=; fi |
| @@ -152,16 +147,16 @@ | |
| 152 | -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ |
| 153 | -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ |
| 154 | -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ |
| 155 | -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ |
| 156 | -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ |
| 157 | -apple | -axis | -knuth | -cray | -microblaze) |
| 158 | os= |
| 159 | basic_machine=$1 |
| 160 | ;; |
| 161 | -bluegene*) |
| 162 | os=-cnk |
| 163 | ;; |
| 164 | -sim | -cisco | -oki | -wec | -winbond) |
| 165 | os= |
| 166 | basic_machine=$1 |
| 167 | ;; |
| @@ -173,14 +168,14 @@ | |
| 173 | ;; |
| 174 | -chorusos*) |
| 175 | os=-chorusos |
| 176 | basic_machine=$1 |
| 177 | ;; |
| 178 | -chorusrdb) |
| 179 | os=-chorusrdb |
| 180 | basic_machine=$1 |
| 181 | ;; |
| 182 | -hiux*) |
| 183 | os=-hiuxwe2 |
| 184 | ;; |
| 185 | -sco6) |
| 186 | os=-sco5v6 |
| @@ -221,10 +216,16 @@ | |
| 221 | basic_machine=clipper-intergraph |
| 222 | ;; |
| 223 | -isc*) |
| 224 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` |
| 225 | ;; |
| 226 | -lynx*) |
| 227 | os=-lynxos |
| 228 | ;; |
| 229 | -ptx*) |
| 230 | basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` |
| @@ -245,24 +246,32 @@ | |
| 245 | case $basic_machine in |
| 246 | # Recognize the basic CPU types without company name. |
| 247 | # Some are omitted here because they have special meanings below. |
| 248 | 1750a | 580 \ |
| 249 | | a29k \ |
| 250 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ |
| 251 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ |
| 252 | | am33_2.0 \ |
| 253 | | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ |
| 254 | | bfin \ |
| 255 | | c4x | clipper \ |
| 256 | | d10v | d30v | dlx | dsp16xx \ |
| 257 | | fido | fr30 | frv \ |
| 258 | | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ |
| 259 | | i370 | i860 | i960 | ia64 \ |
| 260 | | ip2k | iq2000 \ |
| 261 | | lm32 \ |
| 262 | | m32c | m32r | m32rle | m68000 | m68k | m88k \ |
| 263 | | maxq | mb | microblaze | mcore | mep | metag \ |
| 264 | | mips | mipsbe | mipseb | mipsel | mipsle \ |
| 265 | | mips16 \ |
| 266 | | mips64 | mips64el \ |
| 267 | | mips64octeon | mips64octeonel \ |
| 268 | | mips64orion | mips64orionel \ |
| @@ -272,38 +281,41 @@ | |
| 272 | | mips64vr4300 | mips64vr4300el \ |
| 273 | | mips64vr5000 | mips64vr5000el \ |
| 274 | | mips64vr5900 | mips64vr5900el \ |
| 275 | | mipsisa32 | mipsisa32el \ |
| 276 | | mipsisa32r2 | mipsisa32r2el \ |
| 277 | | mipsisa64 | mipsisa64el \ |
| 278 | | mipsisa64r2 | mipsisa64r2el \ |
| 279 | | mipsisa64sb1 | mipsisa64sb1el \ |
| 280 | | mipsisa64sr71k | mipsisa64sr71kel \ |
| 281 | | mipstx39 | mipstx39el \ |
| 282 | | mn10200 | mn10300 \ |
| 283 | | moxie \ |
| 284 | | mt \ |
| 285 | | msp430 \ |
| 286 | | nds32 | nds32le | nds32be \ |
| 287 | | nios | nios2 \ |
| 288 | | ns16k | ns32k \ |
| 289 | | or32 \ |
| 290 | | pdp10 | pdp11 | pj | pjl \ |
| 291 | | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ |
| 292 | | pyramid \ |
| 293 | | rx \ |
| 294 | | score \ |
| 295 | | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ |
| 296 | | sh64 | sh64le \ |
| 297 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ |
| 298 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ |
| 299 | | spu | strongarm \ |
| 300 | | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ |
| 301 | | ubicom32 \ |
| 302 | | v850 | v850e \ |
| 303 | | we32k \ |
| 304 | | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ |
| 305 | | z8k | z80) |
| 306 | basic_machine=$basic_machine-unknown |
| 307 | ;; |
| 308 | c54x) |
| 309 | basic_machine=tic54x-unknown |
| @@ -312,20 +324,34 @@ | |
| 312 | basic_machine=tic55x-unknown |
| 313 | ;; |
| 314 | c6x) |
| 315 | basic_machine=tic6x-unknown |
| 316 | ;; |
| 317 | m6811 | m68hc11 | m6812 | m68hc12 | picochip) |
| 318 | # Motorola 68HC11/12. |
| 319 | basic_machine=$basic_machine-unknown |
| 320 | os=-none |
| 321 | ;; |
| 322 | m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) |
| 323 | ;; |
| 324 | ms1) |
| 325 | basic_machine=mt-unknown |
| 326 | ;; |
| 327 | |
| 328 | # We use `pc' rather than `unknown' |
| 329 | # because (1) that's what they normally are, and |
| 330 | # (2) the word "unknown" tends to confuse beginning users. |
| 331 | i*86 | x86_64) |
| @@ -337,29 +363,35 @@ | |
| 337 | exit 1 |
| 338 | ;; |
| 339 | # Recognize the basic CPU types with company name. |
| 340 | 580-* \ |
| 341 | | a29k-* \ |
| 342 | | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ |
| 343 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ |
| 344 | | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ |
| 345 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ |
| 346 | | avr-* | avr32-* \ |
| 347 | | bfin-* | bs2000-* \ |
| 348 | | c[123]* | c30-* | [cjt]90-* | c4x-* \ |
| 349 | | clipper-* | craynv-* | cydra-* \ |
| 350 | | d10v-* | d30v-* | dlx-* \ |
| 351 | | elxsi-* \ |
| 352 | | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ |
| 353 | | h8300-* | h8500-* \ |
| 354 | | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ |
| 355 | | i*86-* | i860-* | i960-* | ia64-* \ |
| 356 | | ip2k-* | iq2000-* \ |
| 357 | | lm32-* \ |
| 358 | | m32c-* | m32r-* | m32rle-* \ |
| 359 | | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ |
| 360 | | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ |
| 361 | | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ |
| 362 | | mips16-* \ |
| 363 | | mips64-* | mips64el-* \ |
| 364 | | mips64octeon-* | mips64octeonel-* \ |
| 365 | | mips64orion-* | mips64orionel-* \ |
| @@ -369,39 +401,45 @@ | |
| 369 | | mips64vr4300-* | mips64vr4300el-* \ |
| 370 | | mips64vr5000-* | mips64vr5000el-* \ |
| 371 | | mips64vr5900-* | mips64vr5900el-* \ |
| 372 | | mipsisa32-* | mipsisa32el-* \ |
| 373 | | mipsisa32r2-* | mipsisa32r2el-* \ |
| 374 | | mipsisa64-* | mipsisa64el-* \ |
| 375 | | mipsisa64r2-* | mipsisa64r2el-* \ |
| 376 | | mipsisa64sb1-* | mipsisa64sb1el-* \ |
| 377 | | mipsisa64sr71k-* | mipsisa64sr71kel-* \ |
| 378 | | mipstx39-* | mipstx39el-* \ |
| 379 | | mmix-* \ |
| 380 | | mt-* \ |
| 381 | | msp430-* \ |
| 382 | | nds32-* | nds32le-* | nds32be-* \ |
| 383 | | nios-* | nios2-* \ |
| 384 | | none-* | np1-* | ns16k-* | ns32k-* \ |
| 385 | | orion-* \ |
| 386 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ |
| 387 | | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ |
| 388 | | pyramid-* \ |
| 389 | | romp-* | rs6000-* | rx-* \ |
| 390 | | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ |
| 391 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ |
| 392 | | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ |
| 393 | | sparclite-* \ |
| 394 | | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ |
| 395 | | tahoe-* | thumb-* \ |
| 396 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ |
| 397 | | tile-* | tilegx-* \ |
| 398 | | tron-* \ |
| 399 | | ubicom32-* \ |
| 400 | | v850-* | v850e-* | vax-* \ |
| 401 | | we32k-* \ |
| 402 | | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ |
| 403 | | xstormy16-* | xtensa*-* \ |
| 404 | | ymp-* \ |
| 405 | | z8k-* | z80-*) |
| 406 | ;; |
| 407 | # Recognize the basic CPU types without company name, with glob match. |
| @@ -422,11 +460,11 @@ | |
| 422 | ;; |
| 423 | a29khif) |
| 424 | basic_machine=a29k-amd |
| 425 | os=-udi |
| 426 | ;; |
| 427 | abacus) |
| 428 | basic_machine=abacus-unknown |
| 429 | ;; |
| 430 | adobe68k) |
| 431 | basic_machine=m68010-adobe |
| 432 | os=-scout |
| @@ -505,11 +543,11 @@ | |
| 505 | ;; |
| 506 | c90) |
| 507 | basic_machine=c90-cray |
| 508 | os=-unicos |
| 509 | ;; |
| 510 | cegcc) |
| 511 | basic_machine=arm-unknown |
| 512 | os=-cegcc |
| 513 | ;; |
| 514 | convex-c1) |
| 515 | basic_machine=c1-convex |
| @@ -537,11 +575,11 @@ | |
| 537 | ;; |
| 538 | craynv) |
| 539 | basic_machine=craynv-cray |
| 540 | os=-unicosmp |
| 541 | ;; |
| 542 | cr16) |
| 543 | basic_machine=cr16-unknown |
| 544 | os=-elf |
| 545 | ;; |
| 546 | crds | unos) |
| 547 | basic_machine=m68k-crds |
| @@ -695,11 +733,10 @@ | |
| 695 | os=-proelf |
| 696 | ;; |
| 697 | i370-ibm* | ibm*) |
| 698 | basic_machine=i370-ibm |
| 699 | ;; |
| 700 | # I'm not sure what "Sysv32" means. Should this be sysv3.2? |
| 701 | i*86v32) |
| 702 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` |
| 703 | os=-sysv32 |
| 704 | ;; |
| 705 | i*86v4*) |
| @@ -753,15 +790,19 @@ | |
| 753 | ;; |
| 754 | merlin) |
| 755 | basic_machine=ns32k-utek |
| 756 | os=-sysv |
| 757 | ;; |
| 758 | microblaze) |
| 759 | basic_machine=microblaze-xilinx |
| 760 | ;; |
| 761 | mingw32) |
| 762 | basic_machine=i386-pc |
| 763 | os=-mingw32 |
| 764 | ;; |
| 765 | mingw32ce) |
| 766 | basic_machine=arm-unknown |
| 767 | os=-mingw32ce |
| @@ -792,18 +833,22 @@ | |
| 792 | os=-msdos |
| 793 | ;; |
| 794 | ms1-*) |
| 795 | basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` |
| 796 | ;; |
| 797 | mvs) |
| 798 | basic_machine=i370-ibm |
| 799 | os=-mvs |
| 800 | ;; |
| 801 | msys) |
| 802 | basic_machine=i386-pc |
| 803 | os=-msys |
| 804 | ;; |
| 805 | ncr3000) |
| 806 | basic_machine=i486-ncr |
| 807 | os=-sysv4 |
| 808 | ;; |
| 809 | netbsd386) |
| @@ -864,14 +909,14 @@ | |
| 864 | os=-nonstopux |
| 865 | ;; |
| 866 | np1) |
| 867 | basic_machine=np1-gould |
| 868 | ;; |
| 869 | neo-tandem) |
| 870 | basic_machine=neo-tandem |
| 871 | ;; |
| 872 | nse-tandem) |
| 873 | basic_machine=nse-tandem |
| 874 | ;; |
| 875 | nsr-tandem) |
| 876 | basic_machine=nsr-tandem |
| 877 | ;; |
| @@ -952,13 +997,14 @@ | |
| 952 | pn) |
| 953 | basic_machine=pn-gould |
| 954 | ;; |
| 955 | power) basic_machine=power-ibm |
| 956 | ;; |
| 957 | ppc) basic_machine=powerpc-unknown |
| 958 | ;; |
| 959 | ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` |
| 960 | ;; |
| 961 | ppcle | powerpclittle | ppc-le | powerpc-little) |
| 962 | basic_machine=powerpcle-unknown |
| 963 | ;; |
| 964 | ppcle-* | powerpclittle-*) |
| @@ -979,11 +1025,15 @@ | |
| 979 | ;; |
| 980 | pw32) |
| 981 | basic_machine=i586-unknown |
| 982 | os=-pw32 |
| 983 | ;; |
| 984 | rdos) |
| 985 | basic_machine=i386-pc |
| 986 | os=-rdos |
| 987 | ;; |
| 988 | rom68k) |
| 989 | basic_machine=m68k-rom68k |
| @@ -1048,10 +1098,13 @@ | |
| 1048 | ;; |
| 1049 | stratus) |
| 1050 | basic_machine=i860-stratus |
| 1051 | os=-sysv4 |
| 1052 | ;; |
| 1053 | sun2) |
| 1054 | basic_machine=m68000-sun |
| 1055 | ;; |
| 1056 | sun2os3) |
| 1057 | basic_machine=m68000-sun |
| @@ -1104,17 +1157,12 @@ | |
| 1104 | ;; |
| 1105 | t90) |
| 1106 | basic_machine=t90-cray |
| 1107 | os=-unicos |
| 1108 | ;; |
| 1109 | # This must be matched before tile*. |
| 1110 | tilegx*) |
| 1111 | basic_machine=tilegx-unknown |
| 1112 | os=-linux-gnu |
| 1113 | ;; |
| 1114 | tile*) |
| 1115 | basic_machine=tile-unknown |
| 1116 | os=-linux-gnu |
| 1117 | ;; |
| 1118 | tx39) |
| 1119 | basic_machine=mipstx39-unknown |
| 1120 | ;; |
| @@ -1180,10 +1228,13 @@ | |
| 1180 | os=-mingw32 |
| 1181 | ;; |
| 1182 | xps | xps100) |
| 1183 | basic_machine=xps100-honeywell |
| 1184 | ;; |
| 1185 | ymp) |
| 1186 | basic_machine=ymp-cray |
| 1187 | os=-unicos |
| 1188 | ;; |
| 1189 | z8k-*-coff) |
| @@ -1277,15 +1328,15 @@ | |
| 1277 | # Decode manufacturer-specific aliases for certain operating systems. |
| 1278 | |
| 1279 | if [ x"$os" != x"" ] |
| 1280 | then |
| 1281 | case $os in |
| 1282 | # First match some system type aliases |
| 1283 | # that might get confused with valid system types. |
| 1284 | # -solaris* is a basic system type, with this one exception. |
| 1285 | -auroraux) |
| 1286 | os=-auroraux |
| 1287 | ;; |
| 1288 | -solaris1 | -solaris1.*) |
| 1289 | os=`echo $os | sed -e 's|solaris1|sunos4|'` |
| 1290 | ;; |
| 1291 | -solaris) |
| @@ -1305,33 +1356,33 @@ | |
| 1305 | # Each alternative MUST END IN A *, to match a version number. |
| 1306 | # -sysv* is not here because it comes later, after sysvr4. |
| 1307 | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ |
| 1308 | | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ |
| 1309 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ |
| 1310 | | -sym* | -kopensolaris* \ |
| 1311 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ |
| 1312 | | -aos* | -aros* \ |
| 1313 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ |
| 1314 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ |
| 1315 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ |
| 1316 | | -openbsd* | -solidbsd* \ |
| 1317 | | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ |
| 1318 | | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ |
| 1319 | | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ |
| 1320 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ |
| 1321 | | -chorusos* | -chorusrdb* | -cegcc* \ |
| 1322 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ |
| 1323 | | -mingw32* | -linux-gnu* | -linux-android* \ |
| 1324 | | -linux-newlib* | -linux-uclibc* \ |
| 1325 | | -uxpv* | -beos* | -mpeix* | -udk* \ |
| 1326 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ |
| 1327 | | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ |
| 1328 | | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ |
| 1329 | | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ |
| 1330 | | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ |
| 1331 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ |
| 1332 | | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) |
| 1333 | # Remember, each alternative MUST END IN *, to match a version number. |
| 1334 | ;; |
| 1335 | -qnx*) |
| 1336 | case $basic_machine in |
| 1337 | x86-* | i*86-*) |
| @@ -1366,11 +1417,11 @@ | |
| 1366 | os=`echo $os | sed -e 's|sunos6|solaris3|'` |
| 1367 | ;; |
| 1368 | -opened*) |
| 1369 | os=-openedition |
| 1370 | ;; |
| 1371 | -os400*) |
| 1372 | os=-os400 |
| 1373 | ;; |
| 1374 | -wince*) |
| 1375 | os=-wince |
| 1376 | ;; |
| @@ -1415,11 +1466,11 @@ | |
| 1415 | os=`echo $os | sed -e 's|sinix|sysv|'` |
| 1416 | ;; |
| 1417 | -sinix*) |
| 1418 | os=-sysv4 |
| 1419 | ;; |
| 1420 | -tpf*) |
| 1421 | os=-tpf |
| 1422 | ;; |
| 1423 | -triton*) |
| 1424 | os=-sysv3 |
| 1425 | ;; |
| @@ -1451,21 +1502,18 @@ | |
| 1451 | os=-mint |
| 1452 | ;; |
| 1453 | -aros*) |
| 1454 | os=-aros |
| 1455 | ;; |
| 1456 | -kaos*) |
| 1457 | os=-kaos |
| 1458 | ;; |
| 1459 | -zvmoe) |
| 1460 | os=-zvmoe |
| 1461 | ;; |
| 1462 | -dicos*) |
| 1463 | os=-dicos |
| 1464 | ;; |
| 1465 | -nacl*) |
| 1466 | ;; |
| 1467 | -none) |
| 1468 | ;; |
| 1469 | *) |
| 1470 | # Get rid of the `-' at the beginning of $os. |
| 1471 | os=`echo $os | sed 's/[^-]*-//'` |
| @@ -1484,14 +1532,14 @@ | |
| 1484 | # that MANUFACTURER isn't an operating system. Otherwise, code above |
| 1485 | # will signal an error saying that MANUFACTURER isn't an operating |
| 1486 | # system, and we'll never get to this point. |
| 1487 | |
| 1488 | case $basic_machine in |
| 1489 | score-*) |
| 1490 | os=-elf |
| 1491 | ;; |
| 1492 | spu-*) |
| 1493 | os=-elf |
| 1494 | ;; |
| 1495 | *-acorn) |
| 1496 | os=-riscix1.2 |
| 1497 | ;; |
| @@ -1499,12 +1547,18 @@ | |
| 1499 | os=-linux |
| 1500 | ;; |
| 1501 | arm*-semi) |
| 1502 | os=-aout |
| 1503 | ;; |
| 1504 | c4x-* | tic4x-*) |
| 1505 | os=-coff |
| 1506 | ;; |
| 1507 | tic54x-*) |
| 1508 | os=-coff |
| 1509 | ;; |
| 1510 | tic55x-*) |
| @@ -1529,18 +1583,15 @@ | |
| 1529 | i386-sun) |
| 1530 | os=-sunos4.0.2 |
| 1531 | ;; |
| 1532 | m68000-sun) |
| 1533 | os=-sunos3 |
| 1534 | # This also exists in the configure program, but was not the |
| 1535 | # default. |
| 1536 | # os=-sunos4 |
| 1537 | ;; |
| 1538 | m68*-cisco) |
| 1539 | os=-aout |
| 1540 | ;; |
| 1541 | mep-*) |
| 1542 | os=-elf |
| 1543 | ;; |
| 1544 | mips*-cisco) |
| 1545 | os=-elf |
| 1546 | ;; |
| @@ -1563,11 +1614,11 @@ | |
| 1563 | os=-haiku |
| 1564 | ;; |
| 1565 | *-ibm) |
| 1566 | os=-aix |
| 1567 | ;; |
| 1568 | *-knuth) |
| 1569 | os=-mmixware |
| 1570 | ;; |
| 1571 | *-wec) |
| 1572 | os=-proelf |
| 1573 | ;; |
| 1574 |
| --- autosetup/config.sub | |
| +++ autosetup/config.sub | |
| @@ -1,40 +1,33 @@ | |
| 1 | #! /bin/sh |
| 2 | # Configuration validation subroutine script. |
| 3 | # Copyright 1992-2014 Free Software Foundation, Inc. |
| 4 | |
| 5 | timestamp='2014-05-01' |
| 6 | |
| 7 | # This file is free software; you can redistribute it and/or modify it |
| 8 | # under the terms of the GNU General Public License as published by |
| 9 | # the Free Software Foundation; either version 3 of the License, or |
| 10 | # (at your option) any later version. |
| 11 | # |
| 12 | # This program is distributed in the hope that it will be useful, but |
| 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | # General Public License for more details. |
| 16 | # |
| 17 | # You should have received a copy of the GNU General Public License |
| 18 | # along with this program; if not, see <http://www.gnu.org/licenses/>. |
| 19 | # |
| 20 | # As a special exception to the GNU General Public License, if you |
| 21 | # distribute this file as part of a program that contains a |
| 22 | # configuration script generated by Autoconf, you may include it under |
| 23 | # the same distribution terms that you use for the rest of that |
| 24 | # program. This Exception is an additional permission under section 7 |
| 25 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 26 | |
| 27 | |
| 28 | # Please send patches with a ChangeLog entry to [email protected]. |
| 29 | # |
| 30 | # Configuration subroutine to validate and canonicalize a configuration type. |
| 31 | # Supply the specified configuration type as an argument. |
| 32 | # If it is invalid, we print an error message on stderr and exit with code 1. |
| 33 | # Otherwise, we print the canonical config type on stdout and succeed. |
| @@ -73,13 +66,11 @@ | |
| 66 | Report bugs and patches to <[email protected]>." |
| 67 | |
| 68 | version="\ |
| 69 | GNU config.sub ($timestamp) |
| 70 | |
| 71 | Copyright 1992-2014 Free Software Foundation, Inc. |
| 72 | |
| 73 | This is free software; see the source for copying conditions. There is NO |
| 74 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| 75 | |
| 76 | help=" |
| @@ -123,17 +114,21 @@ | |
| 114 | # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). |
| 115 | # Here we must recognize all the valid KERNEL-OS combinations. |
| 116 | maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` |
| 117 | case $maybe_os in |
| 118 | nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ |
| 119 | linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ |
| 120 | knetbsd*-gnu* | netbsd*-gnu* | \ |
| 121 | kopensolaris*-gnu* | \ |
| 122 | storm-chaos* | os2-emx* | rtmk-nova*) |
| 123 | os=-$maybe_os |
| 124 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` |
| 125 | ;; |
| 126 | android-linux) |
| 127 | os=-linux-android |
| 128 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown |
| 129 | ;; |
| 130 | *) |
| 131 | basic_machine=`echo $1 | sed 's/-[^-]*$//'` |
| 132 | if [ $basic_machine != $1 ] |
| 133 | then os=`echo $1 | sed 's/.*-/-/'` |
| 134 | else os=; fi |
| @@ -152,16 +147,16 @@ | |
| 147 | -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ |
| 148 | -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ |
| 149 | -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ |
| 150 | -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ |
| 151 | -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ |
| 152 | -apple | -axis | -knuth | -cray | -microblaze*) |
| 153 | os= |
| 154 | basic_machine=$1 |
| 155 | ;; |
| 156 | -bluegene*) |
| 157 | os=-cnk |
| 158 | ;; |
| 159 | -sim | -cisco | -oki | -wec | -winbond) |
| 160 | os= |
| 161 | basic_machine=$1 |
| 162 | ;; |
| @@ -173,14 +168,14 @@ | |
| 168 | ;; |
| 169 | -chorusos*) |
| 170 | os=-chorusos |
| 171 | basic_machine=$1 |
| 172 | ;; |
| 173 | -chorusrdb) |
| 174 | os=-chorusrdb |
| 175 | basic_machine=$1 |
| 176 | ;; |
| 177 | -hiux*) |
| 178 | os=-hiuxwe2 |
| 179 | ;; |
| 180 | -sco6) |
| 181 | os=-sco5v6 |
| @@ -221,10 +216,16 @@ | |
| 216 | basic_machine=clipper-intergraph |
| 217 | ;; |
| 218 | -isc*) |
| 219 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` |
| 220 | ;; |
| 221 | -lynx*178) |
| 222 | os=-lynxos178 |
| 223 | ;; |
| 224 | -lynx*5) |
| 225 | os=-lynxos5 |
| 226 | ;; |
| 227 | -lynx*) |
| 228 | os=-lynxos |
| 229 | ;; |
| 230 | -ptx*) |
| 231 | basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` |
| @@ -245,24 +246,32 @@ | |
| 246 | case $basic_machine in |
| 247 | # Recognize the basic CPU types without company name. |
| 248 | # Some are omitted here because they have special meanings below. |
| 249 | 1750a | 580 \ |
| 250 | | a29k \ |
| 251 | | aarch64 | aarch64_be \ |
| 252 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ |
| 253 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ |
| 254 | | am33_2.0 \ |
| 255 | | arc | arceb \ |
| 256 | | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ |
| 257 | | avr | avr32 \ |
| 258 | | be32 | be64 \ |
| 259 | | bfin \ |
| 260 | | c4x | c8051 | clipper \ |
| 261 | | d10v | d30v | dlx | dsp16xx \ |
| 262 | | epiphany \ |
| 263 | | fido | fr30 | frv \ |
| 264 | | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ |
| 265 | | hexagon \ |
| 266 | | i370 | i860 | i960 | ia64 \ |
| 267 | | ip2k | iq2000 \ |
| 268 | | k1om \ |
| 269 | | le32 | le64 \ |
| 270 | | lm32 \ |
| 271 | | m32c | m32r | m32rle | m68000 | m68k | m88k \ |
| 272 | | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ |
| 273 | | mips | mipsbe | mipseb | mipsel | mipsle \ |
| 274 | | mips16 \ |
| 275 | | mips64 | mips64el \ |
| 276 | | mips64octeon | mips64octeonel \ |
| 277 | | mips64orion | mips64orionel \ |
| @@ -272,38 +281,41 @@ | |
| 281 | | mips64vr4300 | mips64vr4300el \ |
| 282 | | mips64vr5000 | mips64vr5000el \ |
| 283 | | mips64vr5900 | mips64vr5900el \ |
| 284 | | mipsisa32 | mipsisa32el \ |
| 285 | | mipsisa32r2 | mipsisa32r2el \ |
| 286 | | mipsisa32r6 | mipsisa32r6el \ |
| 287 | | mipsisa64 | mipsisa64el \ |
| 288 | | mipsisa64r2 | mipsisa64r2el \ |
| 289 | | mipsisa64r6 | mipsisa64r6el \ |
| 290 | | mipsisa64sb1 | mipsisa64sb1el \ |
| 291 | | mipsisa64sr71k | mipsisa64sr71kel \ |
| 292 | | mipsr5900 | mipsr5900el \ |
| 293 | | mipstx39 | mipstx39el \ |
| 294 | | mn10200 | mn10300 \ |
| 295 | | moxie \ |
| 296 | | mt \ |
| 297 | | msp430 \ |
| 298 | | nds32 | nds32le | nds32be \ |
| 299 | | nios | nios2 | nios2eb | nios2el \ |
| 300 | | ns16k | ns32k \ |
| 301 | | open8 | or1k | or1knd | or32 \ |
| 302 | | pdp10 | pdp11 | pj | pjl \ |
| 303 | | powerpc | powerpc64 | powerpc64le | powerpcle \ |
| 304 | | pyramid \ |
| 305 | | rl78 | rx \ |
| 306 | | score \ |
| 307 | | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ |
| 308 | | sh64 | sh64le \ |
| 309 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ |
| 310 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ |
| 311 | | spu \ |
| 312 | | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ |
| 313 | | ubicom32 \ |
| 314 | | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ |
| 315 | | we32k \ |
| 316 | | x86 | xc16x | xstormy16 | xtensa \ |
| 317 | | z8k | z80) |
| 318 | basic_machine=$basic_machine-unknown |
| 319 | ;; |
| 320 | c54x) |
| 321 | basic_machine=tic54x-unknown |
| @@ -312,20 +324,34 @@ | |
| 324 | basic_machine=tic55x-unknown |
| 325 | ;; |
| 326 | c6x) |
| 327 | basic_machine=tic6x-unknown |
| 328 | ;; |
| 329 | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) |
| 330 | basic_machine=$basic_machine-unknown |
| 331 | os=-none |
| 332 | ;; |
| 333 | m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) |
| 334 | ;; |
| 335 | ms1) |
| 336 | basic_machine=mt-unknown |
| 337 | ;; |
| 338 | |
| 339 | strongarm | thumb | xscale) |
| 340 | basic_machine=arm-unknown |
| 341 | ;; |
| 342 | xgate) |
| 343 | basic_machine=$basic_machine-unknown |
| 344 | os=-none |
| 345 | ;; |
| 346 | xscaleeb) |
| 347 | basic_machine=armeb-unknown |
| 348 | ;; |
| 349 | |
| 350 | xscaleel) |
| 351 | basic_machine=armel-unknown |
| 352 | ;; |
| 353 | |
| 354 | # We use `pc' rather than `unknown' |
| 355 | # because (1) that's what they normally are, and |
| 356 | # (2) the word "unknown" tends to confuse beginning users. |
| 357 | i*86 | x86_64) |
| @@ -337,29 +363,35 @@ | |
| 363 | exit 1 |
| 364 | ;; |
| 365 | # Recognize the basic CPU types with company name. |
| 366 | 580-* \ |
| 367 | | a29k-* \ |
| 368 | | aarch64-* | aarch64_be-* \ |
| 369 | | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ |
| 370 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ |
| 371 | | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ |
| 372 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ |
| 373 | | avr-* | avr32-* \ |
| 374 | | be32-* | be64-* \ |
| 375 | | bfin-* | bs2000-* \ |
| 376 | | c[123]* | c30-* | [cjt]90-* | c4x-* \ |
| 377 | | c8051-* | clipper-* | craynv-* | cydra-* \ |
| 378 | | d10v-* | d30v-* | dlx-* \ |
| 379 | | elxsi-* \ |
| 380 | | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ |
| 381 | | h8300-* | h8500-* \ |
| 382 | | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ |
| 383 | | hexagon-* \ |
| 384 | | i*86-* | i860-* | i960-* | ia64-* \ |
| 385 | | ip2k-* | iq2000-* \ |
| 386 | | k1om-* \ |
| 387 | | le32-* | le64-* \ |
| 388 | | lm32-* \ |
| 389 | | m32c-* | m32r-* | m32rle-* \ |
| 390 | | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ |
| 391 | | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ |
| 392 | | microblaze-* | microblazeel-* \ |
| 393 | | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ |
| 394 | | mips16-* \ |
| 395 | | mips64-* | mips64el-* \ |
| 396 | | mips64octeon-* | mips64octeonel-* \ |
| 397 | | mips64orion-* | mips64orionel-* \ |
| @@ -369,39 +401,45 @@ | |
| 401 | | mips64vr4300-* | mips64vr4300el-* \ |
| 402 | | mips64vr5000-* | mips64vr5000el-* \ |
| 403 | | mips64vr5900-* | mips64vr5900el-* \ |
| 404 | | mipsisa32-* | mipsisa32el-* \ |
| 405 | | mipsisa32r2-* | mipsisa32r2el-* \ |
| 406 | | mipsisa32r6-* | mipsisa32r6el-* \ |
| 407 | | mipsisa64-* | mipsisa64el-* \ |
| 408 | | mipsisa64r2-* | mipsisa64r2el-* \ |
| 409 | | mipsisa64r6-* | mipsisa64r6el-* \ |
| 410 | | mipsisa64sb1-* | mipsisa64sb1el-* \ |
| 411 | | mipsisa64sr71k-* | mipsisa64sr71kel-* \ |
| 412 | | mipsr5900-* | mipsr5900el-* \ |
| 413 | | mipstx39-* | mipstx39el-* \ |
| 414 | | mmix-* \ |
| 415 | | mt-* \ |
| 416 | | msp430-* \ |
| 417 | | nds32-* | nds32le-* | nds32be-* \ |
| 418 | | nios-* | nios2-* | nios2eb-* | nios2el-* \ |
| 419 | | none-* | np1-* | ns16k-* | ns32k-* \ |
| 420 | | open8-* \ |
| 421 | | or1k*-* \ |
| 422 | | orion-* \ |
| 423 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ |
| 424 | | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ |
| 425 | | pyramid-* \ |
| 426 | | rl78-* | romp-* | rs6000-* | rx-* \ |
| 427 | | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ |
| 428 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ |
| 429 | | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ |
| 430 | | sparclite-* \ |
| 431 | | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ |
| 432 | | tahoe-* \ |
| 433 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ |
| 434 | | tile*-* \ |
| 435 | | tron-* \ |
| 436 | | ubicom32-* \ |
| 437 | | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ |
| 438 | | vax-* \ |
| 439 | | we32k-* \ |
| 440 | | x86-* | x86_64-* | xc16x-* | xps100-* \ |
| 441 | | xstormy16-* | xtensa*-* \ |
| 442 | | ymp-* \ |
| 443 | | z8k-* | z80-*) |
| 444 | ;; |
| 445 | # Recognize the basic CPU types without company name, with glob match. |
| @@ -422,11 +460,11 @@ | |
| 460 | ;; |
| 461 | a29khif) |
| 462 | basic_machine=a29k-amd |
| 463 | os=-udi |
| 464 | ;; |
| 465 | abacus) |
| 466 | basic_machine=abacus-unknown |
| 467 | ;; |
| 468 | adobe68k) |
| 469 | basic_machine=m68010-adobe |
| 470 | os=-scout |
| @@ -505,11 +543,11 @@ | |
| 543 | ;; |
| 544 | c90) |
| 545 | basic_machine=c90-cray |
| 546 | os=-unicos |
| 547 | ;; |
| 548 | cegcc) |
| 549 | basic_machine=arm-unknown |
| 550 | os=-cegcc |
| 551 | ;; |
| 552 | convex-c1) |
| 553 | basic_machine=c1-convex |
| @@ -537,11 +575,11 @@ | |
| 575 | ;; |
| 576 | craynv) |
| 577 | basic_machine=craynv-cray |
| 578 | os=-unicosmp |
| 579 | ;; |
| 580 | cr16 | cr16-*) |
| 581 | basic_machine=cr16-unknown |
| 582 | os=-elf |
| 583 | ;; |
| 584 | crds | unos) |
| 585 | basic_machine=m68k-crds |
| @@ -695,11 +733,10 @@ | |
| 733 | os=-proelf |
| 734 | ;; |
| 735 | i370-ibm* | ibm*) |
| 736 | basic_machine=i370-ibm |
| 737 | ;; |
| 738 | i*86v32) |
| 739 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` |
| 740 | os=-sysv32 |
| 741 | ;; |
| 742 | i*86v4*) |
| @@ -753,15 +790,19 @@ | |
| 790 | ;; |
| 791 | merlin) |
| 792 | basic_machine=ns32k-utek |
| 793 | os=-sysv |
| 794 | ;; |
| 795 | microblaze*) |
| 796 | basic_machine=microblaze-xilinx |
| 797 | ;; |
| 798 | mingw64) |
| 799 | basic_machine=x86_64-pc |
| 800 | os=-mingw64 |
| 801 | ;; |
| 802 | mingw32) |
| 803 | basic_machine=i686-pc |
| 804 | os=-mingw32 |
| 805 | ;; |
| 806 | mingw32ce) |
| 807 | basic_machine=arm-unknown |
| 808 | os=-mingw32ce |
| @@ -792,18 +833,22 @@ | |
| 833 | os=-msdos |
| 834 | ;; |
| 835 | ms1-*) |
| 836 | basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` |
| 837 | ;; |
| 838 | msys) |
| 839 | basic_machine=i686-pc |
| 840 | os=-msys |
| 841 | ;; |
| 842 | mvs) |
| 843 | basic_machine=i370-ibm |
| 844 | os=-mvs |
| 845 | ;; |
| 846 | nacl) |
| 847 | basic_machine=le32-unknown |
| 848 | os=-nacl |
| 849 | ;; |
| 850 | ncr3000) |
| 851 | basic_machine=i486-ncr |
| 852 | os=-sysv4 |
| 853 | ;; |
| 854 | netbsd386) |
| @@ -864,14 +909,14 @@ | |
| 909 | os=-nonstopux |
| 910 | ;; |
| 911 | np1) |
| 912 | basic_machine=np1-gould |
| 913 | ;; |
| 914 | neo-tandem) |
| 915 | basic_machine=neo-tandem |
| 916 | ;; |
| 917 | nse-tandem) |
| 918 | basic_machine=nse-tandem |
| 919 | ;; |
| 920 | nsr-tandem) |
| 921 | basic_machine=nsr-tandem |
| 922 | ;; |
| @@ -952,13 +997,14 @@ | |
| 997 | pn) |
| 998 | basic_machine=pn-gould |
| 999 | ;; |
| 1000 | power) basic_machine=power-ibm |
| 1001 | ;; |
| 1002 | ppc | ppcbe) basic_machine=powerpc-unknown |
| 1003 | ;; |
| 1004 | ppc-* | ppcbe-*) |
| 1005 | basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` |
| 1006 | ;; |
| 1007 | ppcle | powerpclittle | ppc-le | powerpc-little) |
| 1008 | basic_machine=powerpcle-unknown |
| 1009 | ;; |
| 1010 | ppcle-* | powerpclittle-*) |
| @@ -979,11 +1025,15 @@ | |
| 1025 | ;; |
| 1026 | pw32) |
| 1027 | basic_machine=i586-unknown |
| 1028 | os=-pw32 |
| 1029 | ;; |
| 1030 | rdos | rdos64) |
| 1031 | basic_machine=x86_64-pc |
| 1032 | os=-rdos |
| 1033 | ;; |
| 1034 | rdos32) |
| 1035 | basic_machine=i386-pc |
| 1036 | os=-rdos |
| 1037 | ;; |
| 1038 | rom68k) |
| 1039 | basic_machine=m68k-rom68k |
| @@ -1048,10 +1098,13 @@ | |
| 1098 | ;; |
| 1099 | stratus) |
| 1100 | basic_machine=i860-stratus |
| 1101 | os=-sysv4 |
| 1102 | ;; |
| 1103 | strongarm-* | thumb-*) |
| 1104 | basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` |
| 1105 | ;; |
| 1106 | sun2) |
| 1107 | basic_machine=m68000-sun |
| 1108 | ;; |
| 1109 | sun2os3) |
| 1110 | basic_machine=m68000-sun |
| @@ -1104,17 +1157,12 @@ | |
| 1157 | ;; |
| 1158 | t90) |
| 1159 | basic_machine=t90-cray |
| 1160 | os=-unicos |
| 1161 | ;; |
| 1162 | tile*) |
| 1163 | basic_machine=$basic_machine-unknown |
| 1164 | os=-linux-gnu |
| 1165 | ;; |
| 1166 | tx39) |
| 1167 | basic_machine=mipstx39-unknown |
| 1168 | ;; |
| @@ -1180,10 +1228,13 @@ | |
| 1228 | os=-mingw32 |
| 1229 | ;; |
| 1230 | xps | xps100) |
| 1231 | basic_machine=xps100-honeywell |
| 1232 | ;; |
| 1233 | xscale-* | xscalee[bl]-*) |
| 1234 | basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` |
| 1235 | ;; |
| 1236 | ymp) |
| 1237 | basic_machine=ymp-cray |
| 1238 | os=-unicos |
| 1239 | ;; |
| 1240 | z8k-*-coff) |
| @@ -1277,15 +1328,15 @@ | |
| 1328 | # Decode manufacturer-specific aliases for certain operating systems. |
| 1329 | |
| 1330 | if [ x"$os" != x"" ] |
| 1331 | then |
| 1332 | case $os in |
| 1333 | # First match some system type aliases |
| 1334 | # that might get confused with valid system types. |
| 1335 | # -solaris* is a basic system type, with this one exception. |
| 1336 | -auroraux) |
| 1337 | os=-auroraux |
| 1338 | ;; |
| 1339 | -solaris1 | -solaris1.*) |
| 1340 | os=`echo $os | sed -e 's|solaris1|sunos4|'` |
| 1341 | ;; |
| 1342 | -solaris) |
| @@ -1305,33 +1356,33 @@ | |
| 1356 | # Each alternative MUST END IN A *, to match a version number. |
| 1357 | # -sysv* is not here because it comes later, after sysvr4. |
| 1358 | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ |
| 1359 | | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ |
| 1360 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ |
| 1361 | | -sym* | -kopensolaris* | -plan9* \ |
| 1362 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ |
| 1363 | | -aos* | -aros* \ |
| 1364 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ |
| 1365 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ |
| 1366 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ |
| 1367 | | -bitrig* | -openbsd* | -solidbsd* \ |
| 1368 | | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ |
| 1369 | | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ |
| 1370 | | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ |
| 1371 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ |
| 1372 | | -chorusos* | -chorusrdb* | -cegcc* \ |
| 1373 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ |
| 1374 | | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ |
| 1375 | | -linux-newlib* | -linux-musl* | -linux-uclibc* \ |
| 1376 | | -uxpv* | -beos* | -mpeix* | -udk* \ |
| 1377 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ |
| 1378 | | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ |
| 1379 | | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ |
| 1380 | | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ |
| 1381 | | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ |
| 1382 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ |
| 1383 | | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) |
| 1384 | # Remember, each alternative MUST END IN *, to match a version number. |
| 1385 | ;; |
| 1386 | -qnx*) |
| 1387 | case $basic_machine in |
| 1388 | x86-* | i*86-*) |
| @@ -1366,11 +1417,11 @@ | |
| 1417 | os=`echo $os | sed -e 's|sunos6|solaris3|'` |
| 1418 | ;; |
| 1419 | -opened*) |
| 1420 | os=-openedition |
| 1421 | ;; |
| 1422 | -os400*) |
| 1423 | os=-os400 |
| 1424 | ;; |
| 1425 | -wince*) |
| 1426 | os=-wince |
| 1427 | ;; |
| @@ -1415,11 +1466,11 @@ | |
| 1466 | os=`echo $os | sed -e 's|sinix|sysv|'` |
| 1467 | ;; |
| 1468 | -sinix*) |
| 1469 | os=-sysv4 |
| 1470 | ;; |
| 1471 | -tpf*) |
| 1472 | os=-tpf |
| 1473 | ;; |
| 1474 | -triton*) |
| 1475 | os=-sysv3 |
| 1476 | ;; |
| @@ -1451,21 +1502,18 @@ | |
| 1502 | os=-mint |
| 1503 | ;; |
| 1504 | -aros*) |
| 1505 | os=-aros |
| 1506 | ;; |
| 1507 | -zvmoe) |
| 1508 | os=-zvmoe |
| 1509 | ;; |
| 1510 | -dicos*) |
| 1511 | os=-dicos |
| 1512 | ;; |
| 1513 | -nacl*) |
| 1514 | ;; |
| 1515 | -none) |
| 1516 | ;; |
| 1517 | *) |
| 1518 | # Get rid of the `-' at the beginning of $os. |
| 1519 | os=`echo $os | sed 's/[^-]*-//'` |
| @@ -1484,14 +1532,14 @@ | |
| 1532 | # that MANUFACTURER isn't an operating system. Otherwise, code above |
| 1533 | # will signal an error saying that MANUFACTURER isn't an operating |
| 1534 | # system, and we'll never get to this point. |
| 1535 | |
| 1536 | case $basic_machine in |
| 1537 | score-*) |
| 1538 | os=-elf |
| 1539 | ;; |
| 1540 | spu-*) |
| 1541 | os=-elf |
| 1542 | ;; |
| 1543 | *-acorn) |
| 1544 | os=-riscix1.2 |
| 1545 | ;; |
| @@ -1499,12 +1547,18 @@ | |
| 1547 | os=-linux |
| 1548 | ;; |
| 1549 | arm*-semi) |
| 1550 | os=-aout |
| 1551 | ;; |
| 1552 | c4x-* | tic4x-*) |
| 1553 | os=-coff |
| 1554 | ;; |
| 1555 | c8051-*) |
| 1556 | os=-elf |
| 1557 | ;; |
| 1558 | hexagon-*) |
| 1559 | os=-elf |
| 1560 | ;; |
| 1561 | tic54x-*) |
| 1562 | os=-coff |
| 1563 | ;; |
| 1564 | tic55x-*) |
| @@ -1529,18 +1583,15 @@ | |
| 1583 | i386-sun) |
| 1584 | os=-sunos4.0.2 |
| 1585 | ;; |
| 1586 | m68000-sun) |
| 1587 | os=-sunos3 |
| 1588 | ;; |
| 1589 | m68*-cisco) |
| 1590 | os=-aout |
| 1591 | ;; |
| 1592 | mep-*) |
| 1593 | os=-elf |
| 1594 | ;; |
| 1595 | mips*-cisco) |
| 1596 | os=-elf |
| 1597 | ;; |
| @@ -1563,11 +1614,11 @@ | |
| 1614 | os=-haiku |
| 1615 | ;; |
| 1616 | *-ibm) |
| 1617 | os=-aix |
| 1618 | ;; |
| 1619 | *-knuth) |
| 1620 | os=-mmixware |
| 1621 | ;; |
| 1622 | *-wec) |
| 1623 | os=-proelf |
| 1624 | ;; |
| 1625 |
+20
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -123,10 +123,14 @@ | ||
| 123 | 123 | */ |
| 124 | 124 | void test_reserved_names(void){ |
| 125 | 125 | int i; |
| 126 | 126 | const char *z; |
| 127 | 127 | int omitRepo = find_option("omitrepo",0,0)!=0; |
| 128 | + | |
| 129 | + /* We should be done with options.. */ | |
| 130 | + verify_all_options(); | |
| 131 | + | |
| 128 | 132 | db_must_be_within_tree(); |
| 129 | 133 | for(i=0; (z = fossil_reserved_name(i, omitRepo))!=0; i++){ |
| 130 | 134 | fossil_print("%3d: %s\n", i, z); |
| 131 | 135 | } |
| 132 | 136 | fossil_print("ALL: (%s)\n", fossil_all_reserved_names(omitRepo)); |
| @@ -257,10 +261,14 @@ | ||
| 257 | 261 | zCleanFlag = find_option("clean",0,1); |
| 258 | 262 | zIgnoreFlag = find_option("ignore",0,1); |
| 259 | 263 | forceFlag = find_option("force","f",0)!=0; |
| 260 | 264 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 261 | 265 | capture_case_sensitive_option(); |
| 266 | + | |
| 267 | + /* We should be done with options.. */ | |
| 268 | + verify_all_options(); | |
| 269 | + | |
| 262 | 270 | db_must_be_within_tree(); |
| 263 | 271 | if( zCleanFlag==0 ){ |
| 264 | 272 | zCleanFlag = db_get("clean-glob", 0); |
| 265 | 273 | } |
| 266 | 274 | if( zIgnoreFlag==0 ){ |
| @@ -346,10 +354,14 @@ | ||
| 346 | 354 | void delete_cmd(void){ |
| 347 | 355 | int i; |
| 348 | 356 | Stmt loop; |
| 349 | 357 | |
| 350 | 358 | capture_case_sensitive_option(); |
| 359 | + | |
| 360 | + /* We should be done with options.. */ | |
| 361 | + verify_all_options(); | |
| 362 | + | |
| 351 | 363 | db_must_be_within_tree(); |
| 352 | 364 | db_begin_transaction(); |
| 353 | 365 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)", |
| 354 | 366 | filename_collation()); |
| 355 | 367 | for(i=2; i<g.argc; i++){ |
| @@ -511,10 +523,14 @@ | ||
| 511 | 523 | |
| 512 | 524 | if( !dryRunFlag ){ |
| 513 | 525 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 514 | 526 | } |
| 515 | 527 | capture_case_sensitive_option(); |
| 528 | + | |
| 529 | + /* We should be done with options.. */ | |
| 530 | + verify_all_options(); | |
| 531 | + | |
| 516 | 532 | db_must_be_within_tree(); |
| 517 | 533 | if( zCleanFlag==0 ){ |
| 518 | 534 | zCleanFlag = db_get("clean-glob", 0); |
| 519 | 535 | } |
| 520 | 536 | if( zIgnoreFlag==0 ){ |
| @@ -620,10 +636,14 @@ | ||
| 620 | 636 | Blob dest; |
| 621 | 637 | Stmt q; |
| 622 | 638 | |
| 623 | 639 | capture_case_sensitive_option(); |
| 624 | 640 | db_must_be_within_tree(); |
| 641 | + | |
| 642 | + /* We should be done with options.. */ | |
| 643 | + verify_all_options(); | |
| 644 | + | |
| 625 | 645 | vid = db_lget_int("checkout", 0); |
| 626 | 646 | if( vid==0 ){ |
| 627 | 647 | fossil_fatal("no checkout rename files in"); |
| 628 | 648 | } |
| 629 | 649 | if( g.argc<4 ){ |
| 630 | 650 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -123,10 +123,14 @@ | |
| 123 | */ |
| 124 | void test_reserved_names(void){ |
| 125 | int i; |
| 126 | const char *z; |
| 127 | int omitRepo = find_option("omitrepo",0,0)!=0; |
| 128 | db_must_be_within_tree(); |
| 129 | for(i=0; (z = fossil_reserved_name(i, omitRepo))!=0; i++){ |
| 130 | fossil_print("%3d: %s\n", i, z); |
| 131 | } |
| 132 | fossil_print("ALL: (%s)\n", fossil_all_reserved_names(omitRepo)); |
| @@ -257,10 +261,14 @@ | |
| 257 | zCleanFlag = find_option("clean",0,1); |
| 258 | zIgnoreFlag = find_option("ignore",0,1); |
| 259 | forceFlag = find_option("force","f",0)!=0; |
| 260 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 261 | capture_case_sensitive_option(); |
| 262 | db_must_be_within_tree(); |
| 263 | if( zCleanFlag==0 ){ |
| 264 | zCleanFlag = db_get("clean-glob", 0); |
| 265 | } |
| 266 | if( zIgnoreFlag==0 ){ |
| @@ -346,10 +354,14 @@ | |
| 346 | void delete_cmd(void){ |
| 347 | int i; |
| 348 | Stmt loop; |
| 349 | |
| 350 | capture_case_sensitive_option(); |
| 351 | db_must_be_within_tree(); |
| 352 | db_begin_transaction(); |
| 353 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)", |
| 354 | filename_collation()); |
| 355 | for(i=2; i<g.argc; i++){ |
| @@ -511,10 +523,14 @@ | |
| 511 | |
| 512 | if( !dryRunFlag ){ |
| 513 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 514 | } |
| 515 | capture_case_sensitive_option(); |
| 516 | db_must_be_within_tree(); |
| 517 | if( zCleanFlag==0 ){ |
| 518 | zCleanFlag = db_get("clean-glob", 0); |
| 519 | } |
| 520 | if( zIgnoreFlag==0 ){ |
| @@ -620,10 +636,14 @@ | |
| 620 | Blob dest; |
| 621 | Stmt q; |
| 622 | |
| 623 | capture_case_sensitive_option(); |
| 624 | db_must_be_within_tree(); |
| 625 | vid = db_lget_int("checkout", 0); |
| 626 | if( vid==0 ){ |
| 627 | fossil_fatal("no checkout rename files in"); |
| 628 | } |
| 629 | if( g.argc<4 ){ |
| 630 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -123,10 +123,14 @@ | |
| 123 | */ |
| 124 | void test_reserved_names(void){ |
| 125 | int i; |
| 126 | const char *z; |
| 127 | int omitRepo = find_option("omitrepo",0,0)!=0; |
| 128 | |
| 129 | /* We should be done with options.. */ |
| 130 | verify_all_options(); |
| 131 | |
| 132 | db_must_be_within_tree(); |
| 133 | for(i=0; (z = fossil_reserved_name(i, omitRepo))!=0; i++){ |
| 134 | fossil_print("%3d: %s\n", i, z); |
| 135 | } |
| 136 | fossil_print("ALL: (%s)\n", fossil_all_reserved_names(omitRepo)); |
| @@ -257,10 +261,14 @@ | |
| 261 | zCleanFlag = find_option("clean",0,1); |
| 262 | zIgnoreFlag = find_option("ignore",0,1); |
| 263 | forceFlag = find_option("force","f",0)!=0; |
| 264 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 265 | capture_case_sensitive_option(); |
| 266 | |
| 267 | /* We should be done with options.. */ |
| 268 | verify_all_options(); |
| 269 | |
| 270 | db_must_be_within_tree(); |
| 271 | if( zCleanFlag==0 ){ |
| 272 | zCleanFlag = db_get("clean-glob", 0); |
| 273 | } |
| 274 | if( zIgnoreFlag==0 ){ |
| @@ -346,10 +354,14 @@ | |
| 354 | void delete_cmd(void){ |
| 355 | int i; |
| 356 | Stmt loop; |
| 357 | |
| 358 | capture_case_sensitive_option(); |
| 359 | |
| 360 | /* We should be done with options.. */ |
| 361 | verify_all_options(); |
| 362 | |
| 363 | db_must_be_within_tree(); |
| 364 | db_begin_transaction(); |
| 365 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)", |
| 366 | filename_collation()); |
| 367 | for(i=2; i<g.argc; i++){ |
| @@ -511,10 +523,14 @@ | |
| 523 | |
| 524 | if( !dryRunFlag ){ |
| 525 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 526 | } |
| 527 | capture_case_sensitive_option(); |
| 528 | |
| 529 | /* We should be done with options.. */ |
| 530 | verify_all_options(); |
| 531 | |
| 532 | db_must_be_within_tree(); |
| 533 | if( zCleanFlag==0 ){ |
| 534 | zCleanFlag = db_get("clean-glob", 0); |
| 535 | } |
| 536 | if( zIgnoreFlag==0 ){ |
| @@ -620,10 +636,14 @@ | |
| 636 | Blob dest; |
| 637 | Stmt q; |
| 638 | |
| 639 | capture_case_sensitive_option(); |
| 640 | db_must_be_within_tree(); |
| 641 | |
| 642 | /* We should be done with options.. */ |
| 643 | verify_all_options(); |
| 644 | |
| 645 | vid = db_lget_int("checkout", 0); |
| 646 | if( vid==0 ){ |
| 647 | fossil_fatal("no checkout rename files in"); |
| 648 | } |
| 649 | if( g.argc<4 ){ |
| 650 |
+19
-2
| --- src/allrepo.c | ||
| +++ src/allrepo.c | ||
| @@ -107,10 +107,12 @@ | ||
| 107 | 107 | ** |
| 108 | 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | 109 | ** subsequent clean, extras, list, pull, push, rebuild, and |
| 110 | 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | 111 | ** local checkouts to be ignored instead. |
| 112 | +** | |
| 113 | +** info Run the "info" command on all repositories. | |
| 112 | 114 | ** |
| 113 | 115 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 114 | 116 | ** option causes all local checkouts to be listed instead. |
| 115 | 117 | ** |
| 116 | 118 | ** pull Run a "pull" operation on all repositories. Only the |
| @@ -155,10 +157,11 @@ | ||
| 155 | 157 | int dryRunFlag = 0; |
| 156 | 158 | int showFile = find_option("showfile",0,0)!=0; |
| 157 | 159 | int stopOnError = find_option("dontstop",0,0)==0; |
| 158 | 160 | int rc; |
| 159 | 161 | int nToDel = 0; |
| 162 | + int showLabel = 0; | |
| 160 | 163 | |
| 161 | 164 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 162 | 165 | if( !dryRunFlag ){ |
| 163 | 166 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 164 | 167 | } |
| @@ -258,32 +261,40 @@ | ||
| 258 | 261 | } |
| 259 | 262 | fossil_free(zSql); |
| 260 | 263 | } |
| 261 | 264 | db_end_transaction(0); |
| 262 | 265 | return; |
| 266 | + }else if( strncmp(zCmd, "info", n)==0 ){ | |
| 267 | + zCmd = "info"; | |
| 268 | + showLabel = 1; | |
| 269 | + quiet = 1; | |
| 263 | 270 | }else{ |
| 264 | 271 | fossil_fatal("\"all\" subcommand should be one of: " |
| 265 | 272 | "changes clean extras ignore list ls push pull rebuild sync"); |
| 266 | 273 | } |
| 267 | 274 | verify_all_options(); |
| 268 | 275 | zFossil = quoteFilename(g.nameOfExe); |
| 276 | + db_multi_exec("CREATE TEMP TABLE repolist(name,tag);"); | |
| 269 | 277 | if( useCheckouts ){ |
| 270 | - db_prepare(&q, | |
| 278 | + db_multi_exec( | |
| 279 | + "INSERT INTO repolist " | |
| 271 | 280 | "SELECT DISTINCT substr(name, 7), name COLLATE nocase" |
| 272 | 281 | " FROM global_config" |
| 273 | 282 | " WHERE substr(name, 1, 6)=='ckout:'" |
| 274 | 283 | " ORDER BY 1" |
| 275 | 284 | ); |
| 276 | 285 | }else{ |
| 277 | - db_prepare(&q, | |
| 286 | + db_multi_exec( | |
| 287 | + "INSERT INTO repolist " | |
| 278 | 288 | "SELECT DISTINCT substr(name, 6), name COLLATE nocase" |
| 279 | 289 | " FROM global_config" |
| 280 | 290 | " WHERE substr(name, 1, 5)=='repo:'" |
| 281 | 291 | " ORDER BY 1" |
| 282 | 292 | ); |
| 283 | 293 | } |
| 284 | 294 | db_multi_exec("CREATE TEMP TABLE todel(x TEXT)"); |
| 295 | + db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1"); | |
| 285 | 296 | while( db_step(&q)==SQLITE_ROW ){ |
| 286 | 297 | const char *zFilename = db_column_text(&q, 0); |
| 287 | 298 | if( file_access(zFilename, F_OK) |
| 288 | 299 | || !file_is_canonical(zFilename) |
| 289 | 300 | || (useCheckouts && file_isdir(zFilename)!=1) |
| @@ -300,10 +311,16 @@ | ||
| 300 | 311 | zFilename); |
| 301 | 312 | } |
| 302 | 313 | zQFilename = quoteFilename(zFilename); |
| 303 | 314 | zSyscmd = mprintf("%s %s %s%s", |
| 304 | 315 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 316 | + if( showLabel ){ | |
| 317 | + int len = (int)strlen(zFilename); | |
| 318 | + int nStar = 80 - (len + 15); | |
| 319 | + if( nStar<2 ) nStar = 1; | |
| 320 | + fossil_print("%.13c %s %.*c\n", '*', zFilename, nStar, '*'); | |
| 321 | + } | |
| 305 | 322 | if( !quiet || dryRunFlag ){ |
| 306 | 323 | fossil_print("%s\n", zSyscmd); |
| 307 | 324 | fflush(stdout); |
| 308 | 325 | } |
| 309 | 326 | rc = dryRunFlag ? 0 : fossil_system(zSyscmd); |
| 310 | 327 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -107,10 +107,12 @@ | |
| 107 | ** |
| 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | ** subsequent clean, extras, list, pull, push, rebuild, and |
| 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | ** local checkouts to be ignored instead. |
| 112 | ** |
| 113 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 114 | ** option causes all local checkouts to be listed instead. |
| 115 | ** |
| 116 | ** pull Run a "pull" operation on all repositories. Only the |
| @@ -155,10 +157,11 @@ | |
| 155 | int dryRunFlag = 0; |
| 156 | int showFile = find_option("showfile",0,0)!=0; |
| 157 | int stopOnError = find_option("dontstop",0,0)==0; |
| 158 | int rc; |
| 159 | int nToDel = 0; |
| 160 | |
| 161 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 162 | if( !dryRunFlag ){ |
| 163 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 164 | } |
| @@ -258,32 +261,40 @@ | |
| 258 | } |
| 259 | fossil_free(zSql); |
| 260 | } |
| 261 | db_end_transaction(0); |
| 262 | return; |
| 263 | }else{ |
| 264 | fossil_fatal("\"all\" subcommand should be one of: " |
| 265 | "changes clean extras ignore list ls push pull rebuild sync"); |
| 266 | } |
| 267 | verify_all_options(); |
| 268 | zFossil = quoteFilename(g.nameOfExe); |
| 269 | if( useCheckouts ){ |
| 270 | db_prepare(&q, |
| 271 | "SELECT DISTINCT substr(name, 7), name COLLATE nocase" |
| 272 | " FROM global_config" |
| 273 | " WHERE substr(name, 1, 6)=='ckout:'" |
| 274 | " ORDER BY 1" |
| 275 | ); |
| 276 | }else{ |
| 277 | db_prepare(&q, |
| 278 | "SELECT DISTINCT substr(name, 6), name COLLATE nocase" |
| 279 | " FROM global_config" |
| 280 | " WHERE substr(name, 1, 5)=='repo:'" |
| 281 | " ORDER BY 1" |
| 282 | ); |
| 283 | } |
| 284 | db_multi_exec("CREATE TEMP TABLE todel(x TEXT)"); |
| 285 | while( db_step(&q)==SQLITE_ROW ){ |
| 286 | const char *zFilename = db_column_text(&q, 0); |
| 287 | if( file_access(zFilename, F_OK) |
| 288 | || !file_is_canonical(zFilename) |
| 289 | || (useCheckouts && file_isdir(zFilename)!=1) |
| @@ -300,10 +311,16 @@ | |
| 300 | zFilename); |
| 301 | } |
| 302 | zQFilename = quoteFilename(zFilename); |
| 303 | zSyscmd = mprintf("%s %s %s%s", |
| 304 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 305 | if( !quiet || dryRunFlag ){ |
| 306 | fossil_print("%s\n", zSyscmd); |
| 307 | fflush(stdout); |
| 308 | } |
| 309 | rc = dryRunFlag ? 0 : fossil_system(zSyscmd); |
| 310 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -107,10 +107,12 @@ | |
| 107 | ** |
| 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | ** subsequent clean, extras, list, pull, push, rebuild, and |
| 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | ** local checkouts to be ignored instead. |
| 112 | ** |
| 113 | ** info Run the "info" command on all repositories. |
| 114 | ** |
| 115 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 116 | ** option causes all local checkouts to be listed instead. |
| 117 | ** |
| 118 | ** pull Run a "pull" operation on all repositories. Only the |
| @@ -155,10 +157,11 @@ | |
| 157 | int dryRunFlag = 0; |
| 158 | int showFile = find_option("showfile",0,0)!=0; |
| 159 | int stopOnError = find_option("dontstop",0,0)==0; |
| 160 | int rc; |
| 161 | int nToDel = 0; |
| 162 | int showLabel = 0; |
| 163 | |
| 164 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 165 | if( !dryRunFlag ){ |
| 166 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 167 | } |
| @@ -258,32 +261,40 @@ | |
| 261 | } |
| 262 | fossil_free(zSql); |
| 263 | } |
| 264 | db_end_transaction(0); |
| 265 | return; |
| 266 | }else if( strncmp(zCmd, "info", n)==0 ){ |
| 267 | zCmd = "info"; |
| 268 | showLabel = 1; |
| 269 | quiet = 1; |
| 270 | }else{ |
| 271 | fossil_fatal("\"all\" subcommand should be one of: " |
| 272 | "changes clean extras ignore list ls push pull rebuild sync"); |
| 273 | } |
| 274 | verify_all_options(); |
| 275 | zFossil = quoteFilename(g.nameOfExe); |
| 276 | db_multi_exec("CREATE TEMP TABLE repolist(name,tag);"); |
| 277 | if( useCheckouts ){ |
| 278 | db_multi_exec( |
| 279 | "INSERT INTO repolist " |
| 280 | "SELECT DISTINCT substr(name, 7), name COLLATE nocase" |
| 281 | " FROM global_config" |
| 282 | " WHERE substr(name, 1, 6)=='ckout:'" |
| 283 | " ORDER BY 1" |
| 284 | ); |
| 285 | }else{ |
| 286 | db_multi_exec( |
| 287 | "INSERT INTO repolist " |
| 288 | "SELECT DISTINCT substr(name, 6), name COLLATE nocase" |
| 289 | " FROM global_config" |
| 290 | " WHERE substr(name, 1, 5)=='repo:'" |
| 291 | " ORDER BY 1" |
| 292 | ); |
| 293 | } |
| 294 | db_multi_exec("CREATE TEMP TABLE todel(x TEXT)"); |
| 295 | db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1"); |
| 296 | while( db_step(&q)==SQLITE_ROW ){ |
| 297 | const char *zFilename = db_column_text(&q, 0); |
| 298 | if( file_access(zFilename, F_OK) |
| 299 | || !file_is_canonical(zFilename) |
| 300 | || (useCheckouts && file_isdir(zFilename)!=1) |
| @@ -300,10 +311,16 @@ | |
| 311 | zFilename); |
| 312 | } |
| 313 | zQFilename = quoteFilename(zFilename); |
| 314 | zSyscmd = mprintf("%s %s %s%s", |
| 315 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 316 | if( showLabel ){ |
| 317 | int len = (int)strlen(zFilename); |
| 318 | int nStar = 80 - (len + 15); |
| 319 | if( nStar<2 ) nStar = 1; |
| 320 | fossil_print("%.13c %s %.*c\n", '*', zFilename, nStar, '*'); |
| 321 | } |
| 322 | if( !quiet || dryRunFlag ){ |
| 323 | fossil_print("%s\n", zSyscmd); |
| 324 | fflush(stdout); |
| 325 | } |
| 326 | rc = dryRunFlag ? 0 : fossil_system(zSyscmd); |
| 327 |
+8
-8
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -29,11 +29,11 @@ | ||
| 29 | 29 | ** |
| 30 | 30 | ** List attachments. |
| 31 | 31 | ** Either one of tkt= or page= are supplied or neither. If neither |
| 32 | 32 | ** are given, all attachments are listed. If one is given, only |
| 33 | 33 | ** attachments for the designated ticket or wiki page are shown. |
| 34 | -** TICKETUUID must be complete | |
| 34 | +** TICKETUUID must be complete | |
| 35 | 35 | */ |
| 36 | 36 | void attachlist_page(void){ |
| 37 | 37 | const char *zPage = P("page"); |
| 38 | 38 | const char *zTkt = P("tkt"); |
| 39 | 39 | Blob sql; |
| @@ -53,11 +53,11 @@ | ||
| 53 | 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | 54 | style_header("Attachments To %h", zPage); |
| 55 | 55 | blob_appendf(&sql, " WHERE target=%Q", zPage); |
| 56 | 56 | }else if( zTkt ){ |
| 57 | 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | - style_header("Attachments To Ticket %.10s", zTkt); | |
| 58 | + style_header("Attachments To Ticket %S", zTkt); | |
| 59 | 59 | blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | 60 | }else{ |
| 61 | 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | 62 | style_header("All Attachments"); |
| 63 | 63 | } |
| @@ -75,11 +75,11 @@ | ||
| 75 | 75 | int attachid = db_column_int(&q, 7); |
| 76 | 76 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 77 | 77 | int i; |
| 78 | 78 | char *zUrlTail; |
| 79 | 79 | for(i=0; zFilename[i]; i++){ |
| 80 | - if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ | |
| 80 | + if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ | |
| 81 | 81 | zFilename = &zFilename[i+1]; |
| 82 | 82 | i = -1; |
| 83 | 83 | } |
| 84 | 84 | } |
| 85 | 85 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| @@ -253,11 +253,11 @@ | ||
| 253 | 253 | zTargetType = mprintf("Wiki Page <a href=\"%s/wiki?name=%h\">%h</a>", |
| 254 | 254 | g.zTop, zPage, zPage); |
| 255 | 255 | }else{ |
| 256 | 256 | if( g.perm.ApndTkt==0 || g.perm.Attach==0 ) login_needed(); |
| 257 | 257 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 258 | - zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" | |
| 258 | + zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" | |
| 259 | 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | 261 | } |
| 262 | 262 | zTarget = zTkt; |
| 263 | 263 | zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>", |
| @@ -445,11 +445,11 @@ | ||
| 445 | 445 | @ <p>Confirm you want to delete the attachment shown below. |
| 446 | 446 | @ <input type="submit" name="confirm" value="Confirm"> |
| 447 | 447 | @ </form> |
| 448 | 448 | } |
| 449 | 449 | |
| 450 | - isModerator = g.perm.Admin || | |
| 450 | + isModerator = g.perm.Admin || | |
| 451 | 451 | (zTktUuid && g.perm.ModTkt) || |
| 452 | 452 | (zWikiName && g.perm.ModWiki); |
| 453 | 453 | if( isModerator && (zModAction = P("modaction"))!=0 ){ |
| 454 | 454 | if( strcmp(zModAction,"delete")==0 ){ |
| 455 | 455 | moderation_disapprove(rid); |
| @@ -500,11 +500,11 @@ | ||
| 500 | 500 | if( g.perm.Setup ){ |
| 501 | 501 | @ <tr><th>MIME-Type:</th><td>%h(zMime)</td></tr> |
| 502 | 502 | } |
| 503 | 503 | @ <tr><th valign="top">Description:</th><td valign="top">%h(zDesc)</td></tr> |
| 504 | 504 | @ </table> |
| 505 | - | |
| 505 | + | |
| 506 | 506 | if( isModerator && modPending ){ |
| 507 | 507 | @ <div class="section">Moderation</div> |
| 508 | 508 | @ <blockquote> |
| 509 | 509 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 510 | 510 | @ <label><input type="radio" name="modaction" value="delete"> |
| @@ -557,11 +557,11 @@ | ||
| 557 | 557 | db_prepare(&q, |
| 558 | 558 | "SELECT datetime(mtime%s), filename, user," |
| 559 | 559 | " (SELECT uuid FROM blob WHERE rid=attachid), src" |
| 560 | 560 | " FROM attachment" |
| 561 | 561 | " WHERE isLatest AND src!='' AND target=%Q" |
| 562 | - " ORDER BY mtime DESC", | |
| 562 | + " ORDER BY mtime DESC", | |
| 563 | 563 | timeline_utc(), zTarget |
| 564 | 564 | ); |
| 565 | 565 | while( db_step(&q)==SQLITE_ROW ){ |
| 566 | 566 | const char *zDate = db_column_text(&q, 0); |
| 567 | 567 | const char *zFile = db_column_text(&q, 1); |
| @@ -582,7 +582,7 @@ | ||
| 582 | 582 | } |
| 583 | 583 | if( cnt ){ |
| 584 | 584 | @ </ul> |
| 585 | 585 | } |
| 586 | 586 | db_finalize(&q); |
| 587 | - | |
| 587 | + | |
| 588 | 588 | } |
| 589 | 589 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -29,11 +29,11 @@ | |
| 29 | ** |
| 30 | ** List attachments. |
| 31 | ** Either one of tkt= or page= are supplied or neither. If neither |
| 32 | ** are given, all attachments are listed. If one is given, only |
| 33 | ** attachments for the designated ticket or wiki page are shown. |
| 34 | ** TICKETUUID must be complete |
| 35 | */ |
| 36 | void attachlist_page(void){ |
| 37 | const char *zPage = P("page"); |
| 38 | const char *zTkt = P("tkt"); |
| 39 | Blob sql; |
| @@ -53,11 +53,11 @@ | |
| 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_appendf(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | style_header("Attachments To Ticket %.10s", zTkt); |
| 59 | blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | style_header("All Attachments"); |
| 63 | } |
| @@ -75,11 +75,11 @@ | |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 77 | int i; |
| 78 | char *zUrlTail; |
| 79 | for(i=0; zFilename[i]; i++){ |
| 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 81 | zFilename = &zFilename[i+1]; |
| 82 | i = -1; |
| 83 | } |
| 84 | } |
| 85 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| @@ -253,11 +253,11 @@ | |
| 253 | zTargetType = mprintf("Wiki Page <a href=\"%s/wiki?name=%h\">%h</a>", |
| 254 | g.zTop, zPage, zPage); |
| 255 | }else{ |
| 256 | if( g.perm.ApndTkt==0 || g.perm.Attach==0 ) login_needed(); |
| 257 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | } |
| 262 | zTarget = zTkt; |
| 263 | zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>", |
| @@ -445,11 +445,11 @@ | |
| 445 | @ <p>Confirm you want to delete the attachment shown below. |
| 446 | @ <input type="submit" name="confirm" value="Confirm"> |
| 447 | @ </form> |
| 448 | } |
| 449 | |
| 450 | isModerator = g.perm.Admin || |
| 451 | (zTktUuid && g.perm.ModTkt) || |
| 452 | (zWikiName && g.perm.ModWiki); |
| 453 | if( isModerator && (zModAction = P("modaction"))!=0 ){ |
| 454 | if( strcmp(zModAction,"delete")==0 ){ |
| 455 | moderation_disapprove(rid); |
| @@ -500,11 +500,11 @@ | |
| 500 | if( g.perm.Setup ){ |
| 501 | @ <tr><th>MIME-Type:</th><td>%h(zMime)</td></tr> |
| 502 | } |
| 503 | @ <tr><th valign="top">Description:</th><td valign="top">%h(zDesc)</td></tr> |
| 504 | @ </table> |
| 505 | |
| 506 | if( isModerator && modPending ){ |
| 507 | @ <div class="section">Moderation</div> |
| 508 | @ <blockquote> |
| 509 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 510 | @ <label><input type="radio" name="modaction" value="delete"> |
| @@ -557,11 +557,11 @@ | |
| 557 | db_prepare(&q, |
| 558 | "SELECT datetime(mtime%s), filename, user," |
| 559 | " (SELECT uuid FROM blob WHERE rid=attachid), src" |
| 560 | " FROM attachment" |
| 561 | " WHERE isLatest AND src!='' AND target=%Q" |
| 562 | " ORDER BY mtime DESC", |
| 563 | timeline_utc(), zTarget |
| 564 | ); |
| 565 | while( db_step(&q)==SQLITE_ROW ){ |
| 566 | const char *zDate = db_column_text(&q, 0); |
| 567 | const char *zFile = db_column_text(&q, 1); |
| @@ -582,7 +582,7 @@ | |
| 582 | } |
| 583 | if( cnt ){ |
| 584 | @ </ul> |
| 585 | } |
| 586 | db_finalize(&q); |
| 587 | |
| 588 | } |
| 589 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -29,11 +29,11 @@ | |
| 29 | ** |
| 30 | ** List attachments. |
| 31 | ** Either one of tkt= or page= are supplied or neither. If neither |
| 32 | ** are given, all attachments are listed. If one is given, only |
| 33 | ** attachments for the designated ticket or wiki page are shown. |
| 34 | ** TICKETUUID must be complete |
| 35 | */ |
| 36 | void attachlist_page(void){ |
| 37 | const char *zPage = P("page"); |
| 38 | const char *zTkt = P("tkt"); |
| 39 | Blob sql; |
| @@ -53,11 +53,11 @@ | |
| 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_appendf(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | style_header("All Attachments"); |
| 63 | } |
| @@ -75,11 +75,11 @@ | |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 77 | int i; |
| 78 | char *zUrlTail; |
| 79 | for(i=0; zFilename[i]; i++){ |
| 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 81 | zFilename = &zFilename[i+1]; |
| 82 | i = -1; |
| 83 | } |
| 84 | } |
| 85 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| @@ -253,11 +253,11 @@ | |
| 253 | zTargetType = mprintf("Wiki Page <a href=\"%s/wiki?name=%h\">%h</a>", |
| 254 | g.zTop, zPage, zPage); |
| 255 | }else{ |
| 256 | if( g.perm.ApndTkt==0 || g.perm.Attach==0 ) login_needed(); |
| 257 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | } |
| 262 | zTarget = zTkt; |
| 263 | zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>", |
| @@ -445,11 +445,11 @@ | |
| 445 | @ <p>Confirm you want to delete the attachment shown below. |
| 446 | @ <input type="submit" name="confirm" value="Confirm"> |
| 447 | @ </form> |
| 448 | } |
| 449 | |
| 450 | isModerator = g.perm.Admin || |
| 451 | (zTktUuid && g.perm.ModTkt) || |
| 452 | (zWikiName && g.perm.ModWiki); |
| 453 | if( isModerator && (zModAction = P("modaction"))!=0 ){ |
| 454 | if( strcmp(zModAction,"delete")==0 ){ |
| 455 | moderation_disapprove(rid); |
| @@ -500,11 +500,11 @@ | |
| 500 | if( g.perm.Setup ){ |
| 501 | @ <tr><th>MIME-Type:</th><td>%h(zMime)</td></tr> |
| 502 | } |
| 503 | @ <tr><th valign="top">Description:</th><td valign="top">%h(zDesc)</td></tr> |
| 504 | @ </table> |
| 505 | |
| 506 | if( isModerator && modPending ){ |
| 507 | @ <div class="section">Moderation</div> |
| 508 | @ <blockquote> |
| 509 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 510 | @ <label><input type="radio" name="modaction" value="delete"> |
| @@ -557,11 +557,11 @@ | |
| 557 | db_prepare(&q, |
| 558 | "SELECT datetime(mtime%s), filename, user," |
| 559 | " (SELECT uuid FROM blob WHERE rid=attachid), src" |
| 560 | " FROM attachment" |
| 561 | " WHERE isLatest AND src!='' AND target=%Q" |
| 562 | " ORDER BY mtime DESC", |
| 563 | timeline_utc(), zTarget |
| 564 | ); |
| 565 | while( db_step(&q)==SQLITE_ROW ){ |
| 566 | const char *zDate = db_column_text(&q, 0); |
| 567 | const char *zFile = db_column_text(&q, 1); |
| @@ -582,7 +582,7 @@ | |
| 582 | } |
| 583 | if( cnt ){ |
| 584 | @ </ul> |
| 585 | } |
| 586 | db_finalize(&q); |
| 587 | |
| 588 | } |
| 589 |
+1
-1
| --- src/bisect.c | ||
| +++ src/bisect.c | ||
| @@ -390,11 +390,11 @@ | ||
| 390 | 390 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 391 | 391 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 392 | 392 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| 393 | 393 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 394 | 394 | fossil_free(z); |
| 395 | - comment_print(aBisectOption[i].zDesc, 27, -1); | |
| 395 | + comment_print(aBisectOption[i].zDesc, 0, 27, -1, g.comFmtFlags); | |
| 396 | 396 | } |
| 397 | 397 | }else if( g.argc==4 || g.argc==5 ){ |
| 398 | 398 | unsigned int i; |
| 399 | 399 | n = strlen(g.argv[3]); |
| 400 | 400 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 401 | 401 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -390,11 +390,11 @@ | |
| 390 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 391 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 392 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| 393 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 394 | fossil_free(z); |
| 395 | comment_print(aBisectOption[i].zDesc, 27, -1); |
| 396 | } |
| 397 | }else if( g.argc==4 || g.argc==5 ){ |
| 398 | unsigned int i; |
| 399 | n = strlen(g.argv[3]); |
| 400 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 401 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -390,11 +390,11 @@ | |
| 390 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 391 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 392 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| 393 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 394 | fossil_free(z); |
| 395 | comment_print(aBisectOption[i].zDesc, 0, 27, -1, g.comFmtFlags); |
| 396 | } |
| 397 | }else if( g.argc==4 || g.argc==5 ){ |
| 398 | unsigned int i; |
| 399 | n = strlen(g.argv[3]); |
| 400 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 401 |
+55
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -1004,10 +1004,65 @@ | ||
| 1004 | 1004 | else if( z[i+1]!='\n' ) z[j++] = '\n'; |
| 1005 | 1005 | } |
| 1006 | 1006 | z[j] = 0; |
| 1007 | 1007 | p->nUsed = j; |
| 1008 | 1008 | } |
| 1009 | + | |
| 1010 | +/* | |
| 1011 | +** Convert blob from cp1252 to UTF-8. As cp1252 is a superset | |
| 1012 | +** of iso8859-1, this is useful on UNIX as well. | |
| 1013 | +** | |
| 1014 | +** This table contains the character translations for 0x80..0xA0. | |
| 1015 | +*/ | |
| 1016 | + | |
| 1017 | +static const unsigned short cp1252[32] = { | |
| 1018 | + 0x20ac, 0x81, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, | |
| 1019 | + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F, | |
| 1020 | + 0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, | |
| 1021 | + 0x2DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178 | |
| 1022 | +}; | |
| 1023 | + | |
| 1024 | +void blob_cp1252_to_utf8(Blob *p){ | |
| 1025 | + unsigned char *z = (unsigned char *)p->aData; | |
| 1026 | + int j = p->nUsed; | |
| 1027 | + int i, n; | |
| 1028 | + for(i=n=0; i<j; i++){ | |
| 1029 | + if( z[i]>=0x80 ){ | |
| 1030 | + if( (z[i]<0xa0) && (cp1252[z[i]&0x1f]>=0x800) ){ | |
| 1031 | + n++; | |
| 1032 | + } | |
| 1033 | + n++; | |
| 1034 | + } | |
| 1035 | + } | |
| 1036 | + j += n; | |
| 1037 | + if( j>=p->nAlloc ){ | |
| 1038 | + blob_resize(p, j); | |
| 1039 | + z = (unsigned char *)p->aData; | |
| 1040 | + } | |
| 1041 | + p->nUsed = j; | |
| 1042 | + z[j] = 0; | |
| 1043 | + while( j>i ){ | |
| 1044 | + if( z[--i]>=0x80 ){ | |
| 1045 | + if( z[i]<0xa0 ){ | |
| 1046 | + unsigned short sym = cp1252[z[i]&0x1f]; | |
| 1047 | + if( sym>=0x800 ){ | |
| 1048 | + z[--j] = 0x80 | (sym&0x3f); | |
| 1049 | + z[--j] = 0x80 | ((sym>>6)&0x3f); | |
| 1050 | + z[--j] = 0xe0 | (sym>>12); | |
| 1051 | + }else{ | |
| 1052 | + z[--j] = 0x80 | (sym&0x3f); | |
| 1053 | + z[--j] = 0xc0 | (sym>>6); | |
| 1054 | + } | |
| 1055 | + }else{ | |
| 1056 | + z[--j] = 0x80 | (z[i]&0x3f); | |
| 1057 | + z[--j] = 0xC0 | (z[i]>>6); | |
| 1058 | + } | |
| 1059 | + }else{ | |
| 1060 | + z[--j] = z[i]; | |
| 1061 | + } | |
| 1062 | + } | |
| 1063 | +} | |
| 1009 | 1064 | |
| 1010 | 1065 | /* |
| 1011 | 1066 | ** Shell-escape the given string. Append the result to a blob. |
| 1012 | 1067 | */ |
| 1013 | 1068 | void shell_escape(Blob *pBlob, const char *zIn){ |
| 1014 | 1069 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1004,10 +1004,65 @@ | |
| 1004 | else if( z[i+1]!='\n' ) z[j++] = '\n'; |
| 1005 | } |
| 1006 | z[j] = 0; |
| 1007 | p->nUsed = j; |
| 1008 | } |
| 1009 | |
| 1010 | /* |
| 1011 | ** Shell-escape the given string. Append the result to a blob. |
| 1012 | */ |
| 1013 | void shell_escape(Blob *pBlob, const char *zIn){ |
| 1014 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1004,10 +1004,65 @@ | |
| 1004 | else if( z[i+1]!='\n' ) z[j++] = '\n'; |
| 1005 | } |
| 1006 | z[j] = 0; |
| 1007 | p->nUsed = j; |
| 1008 | } |
| 1009 | |
| 1010 | /* |
| 1011 | ** Convert blob from cp1252 to UTF-8. As cp1252 is a superset |
| 1012 | ** of iso8859-1, this is useful on UNIX as well. |
| 1013 | ** |
| 1014 | ** This table contains the character translations for 0x80..0xA0. |
| 1015 | */ |
| 1016 | |
| 1017 | static const unsigned short cp1252[32] = { |
| 1018 | 0x20ac, 0x81, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, |
| 1019 | 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F, |
| 1020 | 0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, |
| 1021 | 0x2DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178 |
| 1022 | }; |
| 1023 | |
| 1024 | void blob_cp1252_to_utf8(Blob *p){ |
| 1025 | unsigned char *z = (unsigned char *)p->aData; |
| 1026 | int j = p->nUsed; |
| 1027 | int i, n; |
| 1028 | for(i=n=0; i<j; i++){ |
| 1029 | if( z[i]>=0x80 ){ |
| 1030 | if( (z[i]<0xa0) && (cp1252[z[i]&0x1f]>=0x800) ){ |
| 1031 | n++; |
| 1032 | } |
| 1033 | n++; |
| 1034 | } |
| 1035 | } |
| 1036 | j += n; |
| 1037 | if( j>=p->nAlloc ){ |
| 1038 | blob_resize(p, j); |
| 1039 | z = (unsigned char *)p->aData; |
| 1040 | } |
| 1041 | p->nUsed = j; |
| 1042 | z[j] = 0; |
| 1043 | while( j>i ){ |
| 1044 | if( z[--i]>=0x80 ){ |
| 1045 | if( z[i]<0xa0 ){ |
| 1046 | unsigned short sym = cp1252[z[i]&0x1f]; |
| 1047 | if( sym>=0x800 ){ |
| 1048 | z[--j] = 0x80 | (sym&0x3f); |
| 1049 | z[--j] = 0x80 | ((sym>>6)&0x3f); |
| 1050 | z[--j] = 0xe0 | (sym>>12); |
| 1051 | }else{ |
| 1052 | z[--j] = 0x80 | (sym&0x3f); |
| 1053 | z[--j] = 0xc0 | (sym>>6); |
| 1054 | } |
| 1055 | }else{ |
| 1056 | z[--j] = 0x80 | (z[i]&0x3f); |
| 1057 | z[--j] = 0xC0 | (z[i]>>6); |
| 1058 | } |
| 1059 | }else{ |
| 1060 | z[--j] = z[i]; |
| 1061 | } |
| 1062 | } |
| 1063 | } |
| 1064 | |
| 1065 | /* |
| 1066 | ** Shell-escape the given string. Append the result to a blob. |
| 1067 | */ |
| 1068 | void shell_escape(Blob *pBlob, const char *zIn){ |
| 1069 |
+1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -334,11 +334,11 @@ | ||
| 334 | 334 | @ <li> A <div class="sideboxDescribed">%z(href("brlist?closed")) |
| 335 | 335 | @ closed branch</a></div> is a branch with only |
| 336 | 336 | @ <div class="sideboxDescribed">%z(href("leaves?closed")) |
| 337 | 337 | @ closed leaves</a></div>. |
| 338 | 338 | @ Closed branches are fixed and do not change (unless they are first |
| 339 | - @ reopened)</li> | |
| 339 | + @ reopened).</li> | |
| 340 | 340 | @ </ol> |
| 341 | 341 | style_sidebox_end(); |
| 342 | 342 | |
| 343 | 343 | branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); |
| 344 | 344 | cnt = 0; |
| 345 | 345 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -334,11 +334,11 @@ | |
| 334 | @ <li> A <div class="sideboxDescribed">%z(href("brlist?closed")) |
| 335 | @ closed branch</a></div> is a branch with only |
| 336 | @ <div class="sideboxDescribed">%z(href("leaves?closed")) |
| 337 | @ closed leaves</a></div>. |
| 338 | @ Closed branches are fixed and do not change (unless they are first |
| 339 | @ reopened)</li> |
| 340 | @ </ol> |
| 341 | style_sidebox_end(); |
| 342 | |
| 343 | branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); |
| 344 | cnt = 0; |
| 345 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -334,11 +334,11 @@ | |
| 334 | @ <li> A <div class="sideboxDescribed">%z(href("brlist?closed")) |
| 335 | @ closed branch</a></div> is a branch with only |
| 336 | @ <div class="sideboxDescribed">%z(href("leaves?closed")) |
| 337 | @ closed leaves</a></div>. |
| 338 | @ Closed branches are fixed and do not change (unless they are first |
| 339 | @ reopened).</li> |
| 340 | @ </ol> |
| 341 | style_sidebox_end(); |
| 342 | |
| 343 | branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); |
| 344 | cnt = 0; |
| 345 |
+1
-1
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -179,11 +179,11 @@ | ||
| 179 | 179 | if( linkTip ){ |
| 180 | 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | 182 | } |
| 183 | 183 | if( zCI ){ |
| 184 | - @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%.10s(zUuid)</a>] | |
| 184 | + @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] | |
| 185 | 185 | @ %s(blob_str(&dirname))</h2> |
| 186 | 186 | zSubdirLink = mprintf("%R/dir?ci=%s&name=%T", zUuid, zPrefix); |
| 187 | 187 | if( nD==0 ){ |
| 188 | 188 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", |
| 189 | 189 | zUuid); |
| 190 | 190 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -179,11 +179,11 @@ | |
| 179 | if( linkTip ){ |
| 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | } |
| 183 | if( zCI ){ |
| 184 | @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%.10s(zUuid)</a>] |
| 185 | @ %s(blob_str(&dirname))</h2> |
| 186 | zSubdirLink = mprintf("%R/dir?ci=%s&name=%T", zUuid, zPrefix); |
| 187 | if( nD==0 ){ |
| 188 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", |
| 189 | zUuid); |
| 190 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -179,11 +179,11 @@ | |
| 179 | if( linkTip ){ |
| 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | } |
| 183 | if( zCI ){ |
| 184 | @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] |
| 185 | @ %s(blob_str(&dirname))</h2> |
| 186 | zSubdirLink = mprintf("%R/dir?ci=%s&name=%T", zUuid, zPrefix); |
| 187 | if( nD==0 ){ |
| 188 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", |
| 189 | zUuid); |
| 190 |
+61
-22
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -159,10 +159,35 @@ | ||
| 159 | 159 | int relPathOption = find_option("rel-paths", 0, 0)!=0; |
| 160 | 160 | if( absPathOption ){ relativePaths = 0; } |
| 161 | 161 | if( relPathOption ){ relativePaths = 1; } |
| 162 | 162 | return relativePaths; |
| 163 | 163 | } |
| 164 | + | |
| 165 | +void print_changes( | |
| 166 | + int useSha1sum, /* Verify file status using SHA1 hashing rather | |
| 167 | + than relying on file mtimes. */ | |
| 168 | + int showHdr, /* Identify the repository if there are changes */ | |
| 169 | + int verboseFlag, /* Say "(none)" if there are no changes */ | |
| 170 | + int cwdRelative /* Report relative to the current working dir */ | |
| 171 | +){ | |
| 172 | + Blob report; | |
| 173 | + int vid; | |
| 174 | + blob_zero(&report); | |
| 175 | + | |
| 176 | + vid = db_lget_int("checkout", 0); | |
| 177 | + vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); | |
| 178 | + status_report(&report, "", 0, cwdRelative); | |
| 179 | + if( verboseFlag && blob_size(&report)==0 ){ | |
| 180 | + blob_append(&report, " (none)\n", -1); | |
| 181 | + } | |
| 182 | + if( showHdr && blob_size(&report)>0 ){ | |
| 183 | + fossil_print("Changes for %s at %s:\n", db_get("project-name","???"), | |
| 184 | + g.zLocalRoot); | |
| 185 | + } | |
| 186 | + blob_write_to_file(&report, "-"); | |
| 187 | + blob_reset(&report); | |
| 188 | +} | |
| 164 | 189 | |
| 165 | 190 | /* |
| 166 | 191 | ** COMMAND: changes |
| 167 | 192 | ** |
| 168 | 193 | ** Usage: %fossil changes ?OPTIONS? |
| @@ -182,31 +207,21 @@ | ||
| 182 | 207 | ** -v|--verbose Say "(none)" if there are no changes |
| 183 | 208 | ** |
| 184 | 209 | ** See also: extras, ls, status |
| 185 | 210 | */ |
| 186 | 211 | void changes_cmd(void){ |
| 187 | - Blob report; | |
| 188 | - int vid; | |
| 189 | 212 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| 190 | 213 | int showHdr = find_option("header",0,0)!=0; |
| 191 | 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 192 | 215 | int cwdRelative = 0; |
| 193 | 216 | db_must_be_within_tree(); |
| 194 | 217 | cwdRelative = determine_cwd_relative_option(); |
| 195 | - blob_zero(&report); | |
| 196 | - vid = db_lget_int("checkout", 0); | |
| 197 | - vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); | |
| 198 | - status_report(&report, "", 0, cwdRelative); | |
| 199 | - if( verboseFlag && blob_size(&report)==0 ){ | |
| 200 | - blob_append(&report, " (none)\n", -1); | |
| 201 | - } | |
| 202 | - if( showHdr && blob_size(&report)>0 ){ | |
| 203 | - fossil_print("Changes for %s at %s:\n", db_get("project-name","???"), | |
| 204 | - g.zLocalRoot); | |
| 205 | - } | |
| 206 | - blob_write_to_file(&report, "-"); | |
| 207 | - blob_reset(&report); | |
| 218 | + | |
| 219 | + /* We should be done with options.. */ | |
| 220 | + verify_all_options(); | |
| 221 | + | |
| 222 | + print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); | |
| 208 | 223 | } |
| 209 | 224 | |
| 210 | 225 | /* |
| 211 | 226 | ** COMMAND: status |
| 212 | 227 | ** |
| @@ -227,23 +242,32 @@ | ||
| 227 | 242 | ** |
| 228 | 243 | ** See also: changes, extras, ls |
| 229 | 244 | */ |
| 230 | 245 | void status_cmd(void){ |
| 231 | 246 | int vid; |
| 247 | + int useSha1sum = find_option("sha1sum", 0, 0)!=0; | |
| 248 | + int showHdr = find_option("header",0,0)!=0; | |
| 249 | + int verboseFlag = find_option("verbose","v",0)!=0; | |
| 250 | + int cwdRelative = 0; | |
| 232 | 251 | db_must_be_within_tree(); |
| 233 | 252 | /* 012345678901234 */ |
| 253 | + cwdRelative = determine_cwd_relative_option(); | |
| 254 | + | |
| 255 | + /* We should be done with options.. */ | |
| 256 | + verify_all_options(); | |
| 257 | + | |
| 234 | 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 235 | 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| 236 | 260 | if( g.zConfigDbName ){ |
| 237 | 261 | fossil_print("config-db: %s\n", g.zConfigDbName); |
| 238 | 262 | } |
| 239 | 263 | vid = db_lget_int("checkout", 0); |
| 240 | 264 | if( vid ){ |
| 241 | 265 | show_common_info(vid, "checkout:", 1, 1); |
| 242 | 266 | } |
| 243 | - db_record_repository_filename(0); | |
| 244 | - changes_cmd(); | |
| 267 | + db_record_repository_filename(0); | |
| 268 | + print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); | |
| 245 | 269 | } |
| 246 | 270 | |
| 247 | 271 | /* |
| 248 | 272 | ** COMMAND: ls |
| 249 | 273 | ** |
| @@ -454,10 +478,14 @@ | ||
| 454 | 478 | |
| 455 | 479 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 456 | 480 | capture_case_sensitive_option(); |
| 457 | 481 | db_must_be_within_tree(); |
| 458 | 482 | cwdRelative = determine_cwd_relative_option(); |
| 483 | + | |
| 484 | + /* We should be done with options.. */ | |
| 485 | + verify_all_options(); | |
| 486 | + | |
| 459 | 487 | if( zIgnoreFlag==0 ){ |
| 460 | 488 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 461 | 489 | } |
| 462 | 490 | pIgnore = glob_create(zIgnoreFlag); |
| 463 | 491 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| @@ -928,11 +956,11 @@ | ||
| 928 | 956 | " WHERE datetime(mtime)>=%Q" |
| 929 | 957 | " AND type='ci' AND objid=%d", |
| 930 | 958 | zDate, rid |
| 931 | 959 | ); |
| 932 | 960 | if( b ){ |
| 933 | - fossil_fatal("ancestor check-in [%.10s] (%s) is not older (clock skew?)" | |
| 961 | + fossil_fatal("ancestor check-in [%S] (%s) is not older (clock skew?)" | |
| 934 | 962 | " Use --allow-older to override.", zUuid, zDate); |
| 935 | 963 | } |
| 936 | 964 | #endif |
| 937 | 965 | } |
| 938 | 966 | |
| @@ -1296,11 +1324,10 @@ | ||
| 1296 | 1324 | }else if( fHasInvalidUtf8 ){ |
| 1297 | 1325 | if( encodingOk ){ |
| 1298 | 1326 | return 0; /* We don't want encoding warnings for this file. */ |
| 1299 | 1327 | } |
| 1300 | 1328 | zWarning = "invalid UTF-8"; |
| 1301 | - zConvert = ""; /* Possible conversion to UTF-8 not yet implemented. */ | |
| 1302 | 1329 | zDisable = "\"encoding-glob\" setting"; |
| 1303 | 1330 | }else if( fHasAnyCr ){ |
| 1304 | 1331 | if( crnlOk ){ |
| 1305 | 1332 | return 0; /* We don't want CR/NL warnings for this file. */ |
| 1306 | 1333 | } |
| @@ -1341,10 +1368,12 @@ | ||
| 1341 | 1368 | if( fUnicode ) { |
| 1342 | 1369 | int bomSize; |
| 1343 | 1370 | const unsigned char *bom = get_utf8_bom(&bomSize); |
| 1344 | 1371 | fwrite(bom, 1, bomSize, f); |
| 1345 | 1372 | blob_to_utf8_no_bom(p, 0); |
| 1373 | + }else if( fHasInvalidUtf8 ){ | |
| 1374 | + blob_cp1252_to_utf8(p); | |
| 1346 | 1375 | } |
| 1347 | 1376 | if( fHasAnyCr ){ |
| 1348 | 1377 | blob_to_lf_only(p); |
| 1349 | 1378 | } |
| 1350 | 1379 | fwrite(blob_buffer(p), 1, blob_size(p), f); |
| @@ -1676,15 +1705,25 @@ | ||
| 1676 | 1705 | ){ |
| 1677 | 1706 | fossil_fatal("would fork. \"update\" first or use --allow-fork."); |
| 1678 | 1707 | } |
| 1679 | 1708 | |
| 1680 | 1709 | /* |
| 1681 | - ** Do not allow a commit against a closed leaf | |
| 1710 | + ** Do not allow a commit against a closed leaf unless the commit | |
| 1711 | + ** ends up on a different branch. | |
| 1682 | 1712 | */ |
| 1683 | - if( db_exists("SELECT 1 FROM tagxref" | |
| 1713 | + if( | |
| 1714 | + /* parent checkin has the "closed" tag... */ | |
| 1715 | + db_exists("SELECT 1 FROM tagxref" | |
| 1684 | 1716 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1685 | - TAG_CLOSED, vid) ){ | |
| 1717 | + TAG_CLOSED, vid) | |
| 1718 | + /* ... and the new checkin has no --branch option or the --branch | |
| 1719 | + ** option does not actually change the branch */ | |
| 1720 | + && (sCiInfo.zBranch==0 | |
| 1721 | + || db_exists("SELECT 1 FROM tagxref" | |
| 1722 | + " WHERE tagid=%d AND rid=%d AND tagtype>0" | |
| 1723 | + " AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch)) | |
| 1724 | + ){ | |
| 1686 | 1725 | fossil_fatal("cannot commit against a closed leaf"); |
| 1687 | 1726 | } |
| 1688 | 1727 | |
| 1689 | 1728 | if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1); |
| 1690 | 1729 | if( zComment ){ |
| 1691 | 1730 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -159,10 +159,35 @@ | |
| 159 | int relPathOption = find_option("rel-paths", 0, 0)!=0; |
| 160 | if( absPathOption ){ relativePaths = 0; } |
| 161 | if( relPathOption ){ relativePaths = 1; } |
| 162 | return relativePaths; |
| 163 | } |
| 164 | |
| 165 | /* |
| 166 | ** COMMAND: changes |
| 167 | ** |
| 168 | ** Usage: %fossil changes ?OPTIONS? |
| @@ -182,31 +207,21 @@ | |
| 182 | ** -v|--verbose Say "(none)" if there are no changes |
| 183 | ** |
| 184 | ** See also: extras, ls, status |
| 185 | */ |
| 186 | void changes_cmd(void){ |
| 187 | Blob report; |
| 188 | int vid; |
| 189 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| 190 | int showHdr = find_option("header",0,0)!=0; |
| 191 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 192 | int cwdRelative = 0; |
| 193 | db_must_be_within_tree(); |
| 194 | cwdRelative = determine_cwd_relative_option(); |
| 195 | blob_zero(&report); |
| 196 | vid = db_lget_int("checkout", 0); |
| 197 | vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); |
| 198 | status_report(&report, "", 0, cwdRelative); |
| 199 | if( verboseFlag && blob_size(&report)==0 ){ |
| 200 | blob_append(&report, " (none)\n", -1); |
| 201 | } |
| 202 | if( showHdr && blob_size(&report)>0 ){ |
| 203 | fossil_print("Changes for %s at %s:\n", db_get("project-name","???"), |
| 204 | g.zLocalRoot); |
| 205 | } |
| 206 | blob_write_to_file(&report, "-"); |
| 207 | blob_reset(&report); |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | ** COMMAND: status |
| 212 | ** |
| @@ -227,23 +242,32 @@ | |
| 227 | ** |
| 228 | ** See also: changes, extras, ls |
| 229 | */ |
| 230 | void status_cmd(void){ |
| 231 | int vid; |
| 232 | db_must_be_within_tree(); |
| 233 | /* 012345678901234 */ |
| 234 | fossil_print("repository: %s\n", db_repository_filename()); |
| 235 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| 236 | if( g.zConfigDbName ){ |
| 237 | fossil_print("config-db: %s\n", g.zConfigDbName); |
| 238 | } |
| 239 | vid = db_lget_int("checkout", 0); |
| 240 | if( vid ){ |
| 241 | show_common_info(vid, "checkout:", 1, 1); |
| 242 | } |
| 243 | db_record_repository_filename(0); |
| 244 | changes_cmd(); |
| 245 | } |
| 246 | |
| 247 | /* |
| 248 | ** COMMAND: ls |
| 249 | ** |
| @@ -454,10 +478,14 @@ | |
| 454 | |
| 455 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 456 | capture_case_sensitive_option(); |
| 457 | db_must_be_within_tree(); |
| 458 | cwdRelative = determine_cwd_relative_option(); |
| 459 | if( zIgnoreFlag==0 ){ |
| 460 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 461 | } |
| 462 | pIgnore = glob_create(zIgnoreFlag); |
| 463 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| @@ -928,11 +956,11 @@ | |
| 928 | " WHERE datetime(mtime)>=%Q" |
| 929 | " AND type='ci' AND objid=%d", |
| 930 | zDate, rid |
| 931 | ); |
| 932 | if( b ){ |
| 933 | fossil_fatal("ancestor check-in [%.10s] (%s) is not older (clock skew?)" |
| 934 | " Use --allow-older to override.", zUuid, zDate); |
| 935 | } |
| 936 | #endif |
| 937 | } |
| 938 | |
| @@ -1296,11 +1324,10 @@ | |
| 1296 | }else if( fHasInvalidUtf8 ){ |
| 1297 | if( encodingOk ){ |
| 1298 | return 0; /* We don't want encoding warnings for this file. */ |
| 1299 | } |
| 1300 | zWarning = "invalid UTF-8"; |
| 1301 | zConvert = ""; /* Possible conversion to UTF-8 not yet implemented. */ |
| 1302 | zDisable = "\"encoding-glob\" setting"; |
| 1303 | }else if( fHasAnyCr ){ |
| 1304 | if( crnlOk ){ |
| 1305 | return 0; /* We don't want CR/NL warnings for this file. */ |
| 1306 | } |
| @@ -1341,10 +1368,12 @@ | |
| 1341 | if( fUnicode ) { |
| 1342 | int bomSize; |
| 1343 | const unsigned char *bom = get_utf8_bom(&bomSize); |
| 1344 | fwrite(bom, 1, bomSize, f); |
| 1345 | blob_to_utf8_no_bom(p, 0); |
| 1346 | } |
| 1347 | if( fHasAnyCr ){ |
| 1348 | blob_to_lf_only(p); |
| 1349 | } |
| 1350 | fwrite(blob_buffer(p), 1, blob_size(p), f); |
| @@ -1676,15 +1705,25 @@ | |
| 1676 | ){ |
| 1677 | fossil_fatal("would fork. \"update\" first or use --allow-fork."); |
| 1678 | } |
| 1679 | |
| 1680 | /* |
| 1681 | ** Do not allow a commit against a closed leaf |
| 1682 | */ |
| 1683 | if( db_exists("SELECT 1 FROM tagxref" |
| 1684 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1685 | TAG_CLOSED, vid) ){ |
| 1686 | fossil_fatal("cannot commit against a closed leaf"); |
| 1687 | } |
| 1688 | |
| 1689 | if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1); |
| 1690 | if( zComment ){ |
| 1691 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -159,10 +159,35 @@ | |
| 159 | int relPathOption = find_option("rel-paths", 0, 0)!=0; |
| 160 | if( absPathOption ){ relativePaths = 0; } |
| 161 | if( relPathOption ){ relativePaths = 1; } |
| 162 | return relativePaths; |
| 163 | } |
| 164 | |
| 165 | void print_changes( |
| 166 | int useSha1sum, /* Verify file status using SHA1 hashing rather |
| 167 | than relying on file mtimes. */ |
| 168 | int showHdr, /* Identify the repository if there are changes */ |
| 169 | int verboseFlag, /* Say "(none)" if there are no changes */ |
| 170 | int cwdRelative /* Report relative to the current working dir */ |
| 171 | ){ |
| 172 | Blob report; |
| 173 | int vid; |
| 174 | blob_zero(&report); |
| 175 | |
| 176 | vid = db_lget_int("checkout", 0); |
| 177 | vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); |
| 178 | status_report(&report, "", 0, cwdRelative); |
| 179 | if( verboseFlag && blob_size(&report)==0 ){ |
| 180 | blob_append(&report, " (none)\n", -1); |
| 181 | } |
| 182 | if( showHdr && blob_size(&report)>0 ){ |
| 183 | fossil_print("Changes for %s at %s:\n", db_get("project-name","???"), |
| 184 | g.zLocalRoot); |
| 185 | } |
| 186 | blob_write_to_file(&report, "-"); |
| 187 | blob_reset(&report); |
| 188 | } |
| 189 | |
| 190 | /* |
| 191 | ** COMMAND: changes |
| 192 | ** |
| 193 | ** Usage: %fossil changes ?OPTIONS? |
| @@ -182,31 +207,21 @@ | |
| 207 | ** -v|--verbose Say "(none)" if there are no changes |
| 208 | ** |
| 209 | ** See also: extras, ls, status |
| 210 | */ |
| 211 | void changes_cmd(void){ |
| 212 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | int cwdRelative = 0; |
| 216 | db_must_be_within_tree(); |
| 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | |
| 219 | /* We should be done with options.. */ |
| 220 | verify_all_options(); |
| 221 | |
| 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | } |
| 224 | |
| 225 | /* |
| 226 | ** COMMAND: status |
| 227 | ** |
| @@ -227,23 +242,32 @@ | |
| 242 | ** |
| 243 | ** See also: changes, extras, ls |
| 244 | */ |
| 245 | void status_cmd(void){ |
| 246 | int vid; |
| 247 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| 248 | int showHdr = find_option("header",0,0)!=0; |
| 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | int cwdRelative = 0; |
| 251 | db_must_be_within_tree(); |
| 252 | /* 012345678901234 */ |
| 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | |
| 255 | /* We should be done with options.. */ |
| 256 | verify_all_options(); |
| 257 | |
| 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| 260 | if( g.zConfigDbName ){ |
| 261 | fossil_print("config-db: %s\n", g.zConfigDbName); |
| 262 | } |
| 263 | vid = db_lget_int("checkout", 0); |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| 273 | ** |
| @@ -454,10 +478,14 @@ | |
| 478 | |
| 479 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 480 | capture_case_sensitive_option(); |
| 481 | db_must_be_within_tree(); |
| 482 | cwdRelative = determine_cwd_relative_option(); |
| 483 | |
| 484 | /* We should be done with options.. */ |
| 485 | verify_all_options(); |
| 486 | |
| 487 | if( zIgnoreFlag==0 ){ |
| 488 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 489 | } |
| 490 | pIgnore = glob_create(zIgnoreFlag); |
| 491 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| @@ -928,11 +956,11 @@ | |
| 956 | " WHERE datetime(mtime)>=%Q" |
| 957 | " AND type='ci' AND objid=%d", |
| 958 | zDate, rid |
| 959 | ); |
| 960 | if( b ){ |
| 961 | fossil_fatal("ancestor check-in [%S] (%s) is not older (clock skew?)" |
| 962 | " Use --allow-older to override.", zUuid, zDate); |
| 963 | } |
| 964 | #endif |
| 965 | } |
| 966 | |
| @@ -1296,11 +1324,10 @@ | |
| 1324 | }else if( fHasInvalidUtf8 ){ |
| 1325 | if( encodingOk ){ |
| 1326 | return 0; /* We don't want encoding warnings for this file. */ |
| 1327 | } |
| 1328 | zWarning = "invalid UTF-8"; |
| 1329 | zDisable = "\"encoding-glob\" setting"; |
| 1330 | }else if( fHasAnyCr ){ |
| 1331 | if( crnlOk ){ |
| 1332 | return 0; /* We don't want CR/NL warnings for this file. */ |
| 1333 | } |
| @@ -1341,10 +1368,12 @@ | |
| 1368 | if( fUnicode ) { |
| 1369 | int bomSize; |
| 1370 | const unsigned char *bom = get_utf8_bom(&bomSize); |
| 1371 | fwrite(bom, 1, bomSize, f); |
| 1372 | blob_to_utf8_no_bom(p, 0); |
| 1373 | }else if( fHasInvalidUtf8 ){ |
| 1374 | blob_cp1252_to_utf8(p); |
| 1375 | } |
| 1376 | if( fHasAnyCr ){ |
| 1377 | blob_to_lf_only(p); |
| 1378 | } |
| 1379 | fwrite(blob_buffer(p), 1, blob_size(p), f); |
| @@ -1676,15 +1705,25 @@ | |
| 1705 | ){ |
| 1706 | fossil_fatal("would fork. \"update\" first or use --allow-fork."); |
| 1707 | } |
| 1708 | |
| 1709 | /* |
| 1710 | ** Do not allow a commit against a closed leaf unless the commit |
| 1711 | ** ends up on a different branch. |
| 1712 | */ |
| 1713 | if( |
| 1714 | /* parent checkin has the "closed" tag... */ |
| 1715 | db_exists("SELECT 1 FROM tagxref" |
| 1716 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1717 | TAG_CLOSED, vid) |
| 1718 | /* ... and the new checkin has no --branch option or the --branch |
| 1719 | ** option does not actually change the branch */ |
| 1720 | && (sCiInfo.zBranch==0 |
| 1721 | || db_exists("SELECT 1 FROM tagxref" |
| 1722 | " WHERE tagid=%d AND rid=%d AND tagtype>0" |
| 1723 | " AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch)) |
| 1724 | ){ |
| 1725 | fossil_fatal("cannot commit against a closed leaf"); |
| 1726 | } |
| 1727 | |
| 1728 | if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1); |
| 1729 | if( zComment ){ |
| 1730 |
+9
-1
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -67,11 +67,11 @@ | ||
| 67 | 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | 68 | if( vid==0 ){ |
| 69 | 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | 70 | } |
| 71 | 71 | if( !is_a_version(vid) ){ |
| 72 | - fossil_fatal("object [%.10s] is not a check-in", blob_str(&uuid)); | |
| 72 | + fossil_fatal("object [%S] is not a check-in", blob_str(&uuid)); | |
| 73 | 73 | } |
| 74 | 74 | if( load_vfile_from_rid(vid) && !forceMissingFlag ){ |
| 75 | 75 | fossil_fatal("missing content, unable to checkout"); |
| 76 | 76 | }; |
| 77 | 77 | return vid; |
| @@ -201,10 +201,14 @@ | ||
| 201 | 201 | forceFlag = find_option("force","f",0)!=0; |
| 202 | 202 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 203 | 203 | keepFlag = find_option("keep",0,0)!=0; |
| 204 | 204 | latestFlag = find_option("latest",0,0)!=0; |
| 205 | 205 | promptFlag = find_option("prompt",0,0)!=0 || forceFlag==0; |
| 206 | + | |
| 207 | + /* We should be done with options.. */ | |
| 208 | + verify_all_options(); | |
| 209 | + | |
| 206 | 210 | if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){ |
| 207 | 211 | usage("VERSION|--latest ?--force? ?--keep?"); |
| 208 | 212 | } |
| 209 | 213 | if( !forceFlag && unsaved_changes(0) ){ |
| 210 | 214 | fossil_fatal("there are unsaved changes in the current checkout"); |
| @@ -292,10 +296,14 @@ | ||
| 292 | 296 | ** See also: open |
| 293 | 297 | */ |
| 294 | 298 | void close_cmd(void){ |
| 295 | 299 | int forceFlag = find_option("force","f",0)!=0; |
| 296 | 300 | db_must_be_within_tree(); |
| 301 | + | |
| 302 | + /* We should be done with options.. */ | |
| 303 | + verify_all_options(); | |
| 304 | + | |
| 297 | 305 | if( !forceFlag && unsaved_changes(0) ){ |
| 298 | 306 | fossil_fatal("there are unsaved changes in the current checkout"); |
| 299 | 307 | } |
| 300 | 308 | if( !forceFlag |
| 301 | 309 | && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'", |
| 302 | 310 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -67,11 +67,11 @@ | |
| 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | if( vid==0 ){ |
| 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | } |
| 71 | if( !is_a_version(vid) ){ |
| 72 | fossil_fatal("object [%.10s] is not a check-in", blob_str(&uuid)); |
| 73 | } |
| 74 | if( load_vfile_from_rid(vid) && !forceMissingFlag ){ |
| 75 | fossil_fatal("missing content, unable to checkout"); |
| 76 | }; |
| 77 | return vid; |
| @@ -201,10 +201,14 @@ | |
| 201 | forceFlag = find_option("force","f",0)!=0; |
| 202 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 203 | keepFlag = find_option("keep",0,0)!=0; |
| 204 | latestFlag = find_option("latest",0,0)!=0; |
| 205 | promptFlag = find_option("prompt",0,0)!=0 || forceFlag==0; |
| 206 | if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){ |
| 207 | usage("VERSION|--latest ?--force? ?--keep?"); |
| 208 | } |
| 209 | if( !forceFlag && unsaved_changes(0) ){ |
| 210 | fossil_fatal("there are unsaved changes in the current checkout"); |
| @@ -292,10 +296,14 @@ | |
| 292 | ** See also: open |
| 293 | */ |
| 294 | void close_cmd(void){ |
| 295 | int forceFlag = find_option("force","f",0)!=0; |
| 296 | db_must_be_within_tree(); |
| 297 | if( !forceFlag && unsaved_changes(0) ){ |
| 298 | fossil_fatal("there are unsaved changes in the current checkout"); |
| 299 | } |
| 300 | if( !forceFlag |
| 301 | && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'", |
| 302 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -67,11 +67,11 @@ | |
| 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | if( vid==0 ){ |
| 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | } |
| 71 | if( !is_a_version(vid) ){ |
| 72 | fossil_fatal("object [%S] is not a check-in", blob_str(&uuid)); |
| 73 | } |
| 74 | if( load_vfile_from_rid(vid) && !forceMissingFlag ){ |
| 75 | fossil_fatal("missing content, unable to checkout"); |
| 76 | }; |
| 77 | return vid; |
| @@ -201,10 +201,14 @@ | |
| 201 | forceFlag = find_option("force","f",0)!=0; |
| 202 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 203 | keepFlag = find_option("keep",0,0)!=0; |
| 204 | latestFlag = find_option("latest",0,0)!=0; |
| 205 | promptFlag = find_option("prompt",0,0)!=0 || forceFlag==0; |
| 206 | |
| 207 | /* We should be done with options.. */ |
| 208 | verify_all_options(); |
| 209 | |
| 210 | if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){ |
| 211 | usage("VERSION|--latest ?--force? ?--keep?"); |
| 212 | } |
| 213 | if( !forceFlag && unsaved_changes(0) ){ |
| 214 | fossil_fatal("there are unsaved changes in the current checkout"); |
| @@ -292,10 +296,14 @@ | |
| 296 | ** See also: open |
| 297 | */ |
| 298 | void close_cmd(void){ |
| 299 | int forceFlag = find_option("force","f",0)!=0; |
| 300 | db_must_be_within_tree(); |
| 301 | |
| 302 | /* We should be done with options.. */ |
| 303 | verify_all_options(); |
| 304 | |
| 305 | if( !forceFlag && unsaved_changes(0) ){ |
| 306 | fossil_fatal("there are unsaved changes in the current checkout"); |
| 307 | } |
| 308 | if( !forceFlag |
| 309 | && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'", |
| 310 |
+4
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -127,10 +127,14 @@ | ||
| 127 | 127 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 128 | 128 | zHttpAuth = find_option("httpauth","B",1); |
| 129 | 129 | zDefaultUser = find_option("admin-user","A",1); |
| 130 | 130 | clone_ssh_find_options(); |
| 131 | 131 | url_proxy_options(); |
| 132 | + | |
| 133 | + /* We should be done with options.. */ | |
| 134 | + verify_all_options(); | |
| 135 | + | |
| 132 | 136 | if( g.argc < 4 ){ |
| 133 | 137 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 134 | 138 | } |
| 135 | 139 | db_open_config(0); |
| 136 | 140 | if( file_size(g.argv[3])>0 ){ |
| 137 | 141 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -127,10 +127,14 @@ | |
| 127 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 128 | zHttpAuth = find_option("httpauth","B",1); |
| 129 | zDefaultUser = find_option("admin-user","A",1); |
| 130 | clone_ssh_find_options(); |
| 131 | url_proxy_options(); |
| 132 | if( g.argc < 4 ){ |
| 133 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 134 | } |
| 135 | db_open_config(0); |
| 136 | if( file_size(g.argv[3])>0 ){ |
| 137 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -127,10 +127,14 @@ | |
| 127 | if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; |
| 128 | zHttpAuth = find_option("httpauth","B",1); |
| 129 | zDefaultUser = find_option("admin-user","A",1); |
| 130 | clone_ssh_find_options(); |
| 131 | url_proxy_options(); |
| 132 | |
| 133 | /* We should be done with options.. */ |
| 134 | verify_all_options(); |
| 135 | |
| 136 | if( g.argc < 4 ){ |
| 137 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 138 | } |
| 139 | db_open_config(0); |
| 140 | if( file_size(g.argv[3])>0 ){ |
| 141 |
+403
-57
| --- src/comformat.c | ||
| +++ src/comformat.c | ||
| @@ -23,10 +23,23 @@ | ||
| 23 | 23 | #include <assert.h> |
| 24 | 24 | #ifdef _WIN32 |
| 25 | 25 | # include <windows.h> |
| 26 | 26 | #else |
| 27 | 27 | # include <termios.h> |
| 28 | +# if defined(TIOCGWINSZ) | |
| 29 | +# include <sys/ioctl.h> | |
| 30 | +# endif | |
| 31 | +#endif | |
| 32 | + | |
| 33 | +#if INTERFACE | |
| 34 | +#define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags. */ | |
| 35 | +#define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */ | |
| 36 | +#define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */ | |
| 37 | +#define COMMENT_PRINT_TRIM_SPACE ((u32)0x00000004) /* Trim leading/trailing. */ | |
| 38 | +#define COMMENT_PRINT_WORD_BREAK ((u32)0x00000008) /* Break lines on words. */ | |
| 39 | +#define COMMENT_PRINT_ORIG_BREAK ((u32)0x00000010) /* Break before original. */ | |
| 40 | +#define COMMENT_PRINT_DEFAULT (COMMENT_PRINT_LEGACY) /* Defaults. */ | |
| 28 | 41 | #endif |
| 29 | 42 | |
| 30 | 43 | /* |
| 31 | 44 | ** This is the previous value used by most external callers when they |
| 32 | 45 | ** needed to specify a default maximum line length to be used with the |
| @@ -35,57 +48,239 @@ | ||
| 35 | 48 | #ifndef COMMENT_LEGACY_LINE_LENGTH |
| 36 | 49 | # define COMMENT_LEGACY_LINE_LENGTH (78) |
| 37 | 50 | #endif |
| 38 | 51 | |
| 39 | 52 | /* |
| 40 | -** Given a comment string zText, format that string for printing | |
| 41 | -** on a TTY. Assume that the output cursors is indent spaces from | |
| 42 | -** the left margin and that a single line can contain no more than | |
| 43 | -** lineLength characters. Indent all subsequent lines by indent. | |
| 53 | +** This is the number of spaces to print when a tab character is seen. | |
| 54 | +*/ | |
| 55 | +#ifndef COMMENT_TAB_WIDTH | |
| 56 | +# define COMMENT_TAB_WIDTH (8) | |
| 57 | +#endif | |
| 58 | + | |
| 59 | +/* | |
| 60 | +** This function sets the maximum number of characters to print per line | |
| 61 | +** based on the detected terminal line width, if available; otherwise, it | |
| 62 | +** uses the legacy default terminal line width minus the amount to indent. | |
| 63 | +** | |
| 64 | +** Zero is returned to indicate any failure. One is returned to indicate | |
| 65 | +** the successful detection of the terminal line width. Negative one is | |
| 66 | +** returned to indicate the terminal line width is using the hard-coded | |
| 67 | +** legacy default value. | |
| 68 | +*/ | |
| 69 | +static int comment_set_maxchars( | |
| 70 | + int indent, | |
| 71 | + int *pMaxChars | |
| 72 | +){ | |
| 73 | +#if defined(_WIN32) | |
| 74 | + CONSOLE_SCREEN_BUFFER_INFO csbi; | |
| 75 | + memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); | |
| 76 | + if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){ | |
| 77 | + *pMaxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent; | |
| 78 | + return 1; | |
| 79 | + } | |
| 80 | + return 0; | |
| 81 | +#elif defined(TIOCGWINSZ) | |
| 82 | + struct winsize w; | |
| 83 | + memset(&w, 0, sizeof(struct winsize)); | |
| 84 | + if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){ | |
| 85 | + *pMaxChars = w.ws_col - indent; | |
| 86 | + return 1; | |
| 87 | + } | |
| 88 | + return 0; | |
| 89 | +#else | |
| 90 | + /* | |
| 91 | + ** Fallback to using more-or-less the "legacy semantics" of hard-coding | |
| 92 | + ** the maximum line length to a value reasonable for the vast majority | |
| 93 | + ** of supported systems. | |
| 94 | + */ | |
| 95 | + *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent; | |
| 96 | + return -1; | |
| 97 | +#endif | |
| 98 | +} | |
| 99 | + | |
| 100 | +/* | |
| 101 | +** This function checks the current line being printed against the original | |
| 102 | +** comment text. Upon matching, it emits a new line and updates the provided | |
| 103 | +** character and line counts, if applicable. | |
| 104 | +*/ | |
| 105 | +static int comment_check_orig( | |
| 106 | + const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */ | |
| 107 | + const char *zLine, /* [in] The comment line to print. */ | |
| 108 | + int *pCharCnt, /* [in/out] Pointer to the line character count. */ | |
| 109 | + int *pLineCnt /* [in/out] Pointer to the total line count. */ | |
| 110 | +){ | |
| 111 | + if( zOrigText && fossil_strcmp(zLine, zOrigText)==0 ){ | |
| 112 | + fossil_print("\n"); | |
| 113 | + if( pCharCnt ) *pCharCnt = 0; | |
| 114 | + if( pLineCnt ) (*pLineCnt)++; | |
| 115 | + return 1; | |
| 116 | + } | |
| 117 | + return 0; | |
| 118 | +} | |
| 119 | + | |
| 120 | +/* | |
| 121 | +** This function scans the specified comment line starting just after the | |
| 122 | +** initial index and returns the index of the next spacing character -OR- | |
| 123 | +** zero if such a character cannot be found. For the purposes of this | |
| 124 | +** algorithm, the NUL character is treated the same as a spacing character. | |
| 125 | +*/ | |
| 126 | +static int comment_next_space( | |
| 127 | + const char *zLine, /* [in] The comment line being printed. */ | |
| 128 | + int index /* [in] The current character index being handled. */ | |
| 129 | +){ | |
| 130 | + int nextIndex = index + 1; | |
| 131 | + for(;;){ | |
| 132 | + char c = zLine[nextIndex]; | |
| 133 | + if( c==0 || fossil_isspace(c) ){ | |
| 134 | + return nextIndex; | |
| 135 | + } | |
| 136 | + nextIndex++; | |
| 137 | + } | |
| 138 | + return 0; /* NOT REACHED */ | |
| 139 | +} | |
| 140 | + | |
| 141 | +/* | |
| 142 | +** This function is called when printing a logical comment line to perform | |
| 143 | +** the necessary indenting. | |
| 144 | +*/ | |
| 145 | +static void comment_print_indent( | |
| 146 | + const char *zLine, /* [in] The comment line being printed. */ | |
| 147 | + int indent, /* [in] Number of spaces to indent, zero for none. */ | |
| 148 | + int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */ | |
| 149 | + int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */ | |
| 150 | + int *piIndex /* [in/out] Pointer to first non-space character. */ | |
| 151 | +){ | |
| 152 | + if( indent>0 ){ | |
| 153 | + fossil_print("%*s", indent, ""); | |
| 154 | + } | |
| 155 | + if( zLine && piIndex ){ | |
| 156 | + int index = *piIndex; | |
| 157 | + if( trimCrLf ){ | |
| 158 | + while( zLine[index]=='\r' || zLine[index]=='\n' ){ index++; } | |
| 159 | + } | |
| 160 | + if( trimSpace ){ | |
| 161 | + while( fossil_isspace(zLine[index]) ){ index++; } | |
| 162 | + } | |
| 163 | + *piIndex = index; | |
| 164 | + } | |
| 165 | +} | |
| 166 | + | |
| 167 | +/* | |
| 168 | +** This function prints one logical line of a comment, stopping when it hits | |
| 169 | +** a new line -OR- runs out of space on the logical line. | |
| 170 | +*/ | |
| 171 | +static void comment_print_line( | |
| 172 | + const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */ | |
| 173 | + const char *zLine, /* [in] The comment line to print. */ | |
| 174 | + int origIndent, /* [in] Number of spaces to indent before the original | |
| 175 | + ** comment. */ | |
| 176 | + int indent, /* [in] Number of spaces to indent, before the line | |
| 177 | + ** to print. */ | |
| 178 | + int lineChars, /* [in] Maximum number of characters to print. */ | |
| 179 | + int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */ | |
| 180 | + int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */ | |
| 181 | + int wordBreak, /* [in] Non-zero to try breaking on word boundaries. */ | |
| 182 | + int origBreak, /* [in] Non-zero to break before original comment. */ | |
| 183 | + int *pLineCnt, /* [in/out] Pointer to the total line count. */ | |
| 184 | + const char **pzLine /* [out] Pointer to the end of the logical line. */ | |
| 185 | +){ | |
| 186 | + int index = 0, charCnt = 0, lineCnt = 0, maxChars; | |
| 187 | + if( !zLine ) return; | |
| 188 | + if( lineChars<=0 ) return; | |
| 189 | + comment_print_indent(zLine, indent, trimCrLf, trimSpace, &index); | |
| 190 | + maxChars = lineChars; | |
| 191 | + for(;;){ | |
| 192 | + int useChars = 1; | |
| 193 | + char c = zLine[index]; | |
| 194 | + if( c==0 ){ | |
| 195 | + break; | |
| 196 | + }else{ | |
| 197 | + if( origBreak && index>0 ){ | |
| 198 | + const char *zCurrent = &zLine[index]; | |
| 199 | + if( comment_check_orig(zOrigText, zCurrent, &charCnt, &lineCnt) ){ | |
| 200 | + comment_print_indent(zCurrent, origIndent, trimCrLf, trimSpace, | |
| 201 | + &index); | |
| 202 | + maxChars = lineChars; | |
| 203 | + } | |
| 204 | + } | |
| 205 | + index++; | |
| 206 | + } | |
| 207 | + if( c=='\n' ){ | |
| 208 | + lineCnt++; | |
| 209 | + charCnt = 0; | |
| 210 | + useChars = 0; | |
| 211 | + }else if( c=='\t' ){ | |
| 212 | + int nextIndex = comment_next_space(zLine, index); | |
| 213 | + if( nextIndex<=0 || (nextIndex-index)>maxChars ){ | |
| 214 | + break; | |
| 215 | + } | |
| 216 | + charCnt++; | |
| 217 | + useChars = COMMENT_TAB_WIDTH; | |
| 218 | + if( maxChars<useChars ){ | |
| 219 | + fossil_print(" "); | |
| 220 | + break; | |
| 221 | + } | |
| 222 | + }else if( wordBreak && fossil_isspace(c) ){ | |
| 223 | + int nextIndex = comment_next_space(zLine, index); | |
| 224 | + if( nextIndex<=0 || (nextIndex-index)>maxChars ){ | |
| 225 | + break; | |
| 226 | + } | |
| 227 | + charCnt++; | |
| 228 | + }else{ | |
| 229 | + charCnt++; | |
| 230 | + } | |
| 231 | + assert( c!='\n' || charCnt==0 ); | |
| 232 | + fossil_print("%c", c); | |
| 233 | + maxChars -= useChars; | |
| 234 | + if( maxChars==0 ) break; | |
| 235 | + assert( maxChars>0 ); | |
| 236 | + if( c=='\n' ) break; | |
| 237 | + } | |
| 238 | + if( charCnt>0 ){ | |
| 239 | + fossil_print("\n"); | |
| 240 | + lineCnt++; | |
| 241 | + } | |
| 242 | + if( pLineCnt ){ | |
| 243 | + *pLineCnt += lineCnt; | |
| 244 | + } | |
| 245 | + if( pzLine ){ | |
| 246 | + *pzLine = zLine + index; | |
| 247 | + } | |
| 248 | +} | |
| 249 | + | |
| 250 | +/* | |
| 251 | +** This is the legacy comment printing algorithm. It is being retained | |
| 252 | +** for backward compatibility. | |
| 253 | +** | |
| 254 | +** Given a comment string, format that string for printing on a TTY. | |
| 255 | +** Assume that the output cursors is indent spaces from the left margin | |
| 256 | +** and that a single line can contain no more than 'width' characters. | |
| 257 | +** Indent all subsequent lines by 'indent'. | |
| 44 | 258 | ** |
| 45 | -** Return the number of newlines that are output. | |
| 259 | +** Returns the number of new lines emitted. | |
| 46 | 260 | */ |
| 47 | -int comment_print(const char *zText, int indent, int lineLength){ | |
| 48 | - int tlen = lineLength - indent; | |
| 261 | +static int comment_print_legacy( | |
| 262 | + const char *zText, /* The comment text to be printed. */ | |
| 263 | + int indent, /* Number of spaces to indent each non-initial line. */ | |
| 264 | + int width /* Maximum number of characters per line. */ | |
| 265 | +){ | |
| 266 | + int maxChars = width - indent; | |
| 49 | 267 | int si, sk, i, k; |
| 50 | 268 | int doIndent = 0; |
| 51 | 269 | char *zBuf; |
| 52 | 270 | char zBuffer[400]; |
| 53 | 271 | int lineCnt = 0; |
| 54 | 272 | |
| 55 | -#if defined(_WIN32) | |
| 56 | - if( lineLength<0 ){ | |
| 57 | - CONSOLE_SCREEN_BUFFER_INFO csbi; | |
| 58 | - memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); | |
| 59 | - if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){ | |
| 60 | - tlen = csbi.srWindow.Right - csbi.srWindow.Left - indent; | |
| 61 | - } | |
| 62 | - } | |
| 63 | -#elif defined(TIOCGWINSZ) | |
| 64 | - if( lineLength<0 ){ | |
| 65 | - struct winsize w; | |
| 66 | - memset(&w, 0, sizeof(struct winsize)); | |
| 67 | - if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){ | |
| 68 | - tlen = w.ws_col - indent; | |
| 69 | - } | |
| 70 | - } | |
| 71 | -#else | |
| 72 | - if( lineLength<0 ){ | |
| 73 | - /* | |
| 74 | - ** Fallback to using more-or-less the "legacy semantics" of hard-coding | |
| 75 | - ** the maximum line length to a value reasonable for the vast majority | |
| 76 | - ** of supported systems. | |
| 77 | - */ | |
| 78 | - tlen = COMMENT_LEGACY_LINE_LENGTH - indent; | |
| 79 | - } | |
| 80 | -#endif | |
| 273 | + if( width<0 ){ | |
| 274 | + comment_set_maxchars(indent, &maxChars); | |
| 275 | + } | |
| 81 | 276 | if( zText==0 ) zText = "(NULL)"; |
| 82 | - if( tlen<=0 ){ | |
| 83 | - tlen = strlen(zText); | |
| 277 | + if( maxChars<=0 ){ | |
| 278 | + maxChars = strlen(zText); | |
| 84 | 279 | } |
| 85 | - if( tlen >= (sizeof(zBuffer)) ){ | |
| 86 | - zBuf = fossil_malloc(tlen+1); | |
| 280 | + if( maxChars >= (sizeof(zBuffer)) ){ | |
| 281 | + zBuf = fossil_malloc(maxChars+1); | |
| 87 | 282 | }else{ |
| 88 | 283 | zBuf = zBuffer; |
| 89 | 284 | } |
| 90 | 285 | for(;;){ |
| 91 | 286 | while( fossil_isspace(zText[0]) ){ zText++; } |
| @@ -95,11 +290,11 @@ | ||
| 95 | 290 | lineCnt = 1; |
| 96 | 291 | } |
| 97 | 292 | if( zBuf!=zBuffer) fossil_free(zBuf); |
| 98 | 293 | return lineCnt; |
| 99 | 294 | } |
| 100 | - for(sk=si=i=k=0; zText[i] && k<tlen; i++){ | |
| 295 | + for(sk=si=i=k=0; zText[i] && k<maxChars; i++){ | |
| 101 | 296 | char c = zText[i]; |
| 102 | 297 | if( fossil_isspace(c) ){ |
| 103 | 298 | si = i; |
| 104 | 299 | sk = k; |
| 105 | 300 | if( k==0 || zBuf[k-1]!=' ' ){ |
| @@ -127,47 +322,198 @@ | ||
| 127 | 322 | } |
| 128 | 323 | fossil_print("%s\n", zBuf); |
| 129 | 324 | lineCnt++; |
| 130 | 325 | } |
| 131 | 326 | } |
| 327 | + | |
| 328 | +/* | |
| 329 | +** This is the comment printing function. The comment printing algorithm | |
| 330 | +** contained within it attempts to preserve the formatting present within | |
| 331 | +** the comment string itself while honoring line width limitations. There | |
| 332 | +** are several flags that modify the default behavior of this function: | |
| 333 | +** | |
| 334 | +** COMMENT_PRINT_LEGACY: Forces use of the legacy comment printing | |
| 335 | +** algorithm. For backward compatibility, | |
| 336 | +** this is the default. | |
| 337 | +** | |
| 338 | +** COMMENT_PRINT_TRIM_CRLF: Trims leading and trailing carriage-returns | |
| 339 | +** and line-feeds where they do not materially | |
| 340 | +** impact pre-existing formatting (i.e. at the | |
| 341 | +** start of the comment string -AND- right | |
| 342 | +** before line indentation). This flag does | |
| 343 | +** not apply to the legacy comment printing | |
| 344 | +** algorithm. This flag may be combined with | |
| 345 | +** COMMENT_PRINT_TRIM_SPACE. | |
| 346 | +** | |
| 347 | +** COMMENT_PRINT_TRIM_SPACE: Trims leading and trailing spaces where they | |
| 348 | +** do not materially impact the pre-existing | |
| 349 | +** formatting (i.e. at the start of the comment | |
| 350 | +** string -AND- right before line indentation). | |
| 351 | +** This flag does not apply to the legacy | |
| 352 | +** comment printing algorithm. This flag may | |
| 353 | +** be combined with COMMENT_PRINT_TRIM_CRLF. | |
| 354 | +** | |
| 355 | +** COMMENT_PRINT_WORD_BREAK: Attempts to break lines on word boundaries | |
| 356 | +** while honoring the logical line length. | |
| 357 | +** If this flag is not specified, honoring the | |
| 358 | +** logical line length may result in breaking | |
| 359 | +** lines in the middle of words. This flag | |
| 360 | +** does not apply to the legacy comment | |
| 361 | +** printing algorithm. | |
| 362 | +** | |
| 363 | +** COMMENT_PRINT_ORIG_BREAK: Looks for the original comment text within | |
| 364 | +** the text being printed. Upon matching, a | |
| 365 | +** new line will be emitted, thus preserving | |
| 366 | +** more of the pre-existing formatting. | |
| 367 | +** | |
| 368 | +** Given a comment string, format that string for printing on a TTY. | |
| 369 | +** Assume that the output cursors is indent spaces from the left margin | |
| 370 | +** and that a single line can contain no more than 'width' characters. | |
| 371 | +** Indent all subsequent lines by 'indent'. | |
| 372 | +** | |
| 373 | +** Returns the number of new lines emitted. | |
| 374 | +*/ | |
| 375 | +int comment_print( | |
| 376 | + const char *zText, /* The comment text to be printed. */ | |
| 377 | + const char *zOrigText, /* Original comment text ONLY, may be NULL. */ | |
| 378 | + int indent, /* Spaces to indent each non-initial line. */ | |
| 379 | + int width, /* Maximum number of characters per line. */ | |
| 380 | + int flags /* Zero or more "COMMENT_PRINT_*" flags. */ | |
| 381 | +){ | |
| 382 | + int maxChars = width - indent; | |
| 383 | + int legacy = flags & COMMENT_PRINT_LEGACY; | |
| 384 | + int trimCrLf = flags & COMMENT_PRINT_TRIM_CRLF; | |
| 385 | + int trimSpace = flags & COMMENT_PRINT_TRIM_SPACE; | |
| 386 | + int wordBreak = flags & COMMENT_PRINT_WORD_BREAK; | |
| 387 | + int origBreak = flags & COMMENT_PRINT_ORIG_BREAK; | |
| 388 | + int lineCnt = 0; | |
| 389 | + const char *zLine; | |
| 390 | + | |
| 391 | + if( legacy ){ | |
| 392 | + return comment_print_legacy(zText, indent, width); | |
| 393 | + } | |
| 394 | + if( width<0 ){ | |
| 395 | + comment_set_maxchars(indent, &maxChars); | |
| 396 | + } | |
| 397 | + if( zText==0 ) zText = "(NULL)"; | |
| 398 | + if( maxChars<=0 ){ | |
| 399 | + maxChars = strlen(zText); | |
| 400 | + } | |
| 401 | + if( trimSpace ){ | |
| 402 | + while( fossil_isspace(zText[0]) ){ zText++; } | |
| 403 | + } | |
| 404 | + if( zText[0]==0 ){ | |
| 405 | + fossil_print("\n"); | |
| 406 | + lineCnt++; | |
| 407 | + return lineCnt; | |
| 408 | + } | |
| 409 | + zLine = zText; | |
| 410 | + for(;;){ | |
| 411 | + comment_print_line(zOrigText, zLine, indent, zLine>zText ? indent : 0, | |
| 412 | + maxChars, trimCrLf, trimSpace, wordBreak, origBreak, | |
| 413 | + &lineCnt, &zLine); | |
| 414 | + if( !zLine || !zLine[0] ) break; | |
| 415 | + } | |
| 416 | + return lineCnt; | |
| 417 | +} | |
| 132 | 418 | |
| 133 | 419 | /* |
| 134 | 420 | ** |
| 135 | 421 | ** COMMAND: test-comment-format |
| 136 | 422 | ** |
| 137 | -** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?WIDTH? | |
| 423 | +** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?ORIGTEXT? | |
| 138 | 424 | ** |
| 139 | 425 | ** Test comment formatting and printing. Use for testing only. |
| 140 | 426 | ** |
| 141 | 427 | ** Options: |
| 428 | +** --file The comment text is really just a file name to | |
| 429 | +** read it from. | |
| 142 | 430 | ** --decode Decode the text using the same method used when |
| 143 | 431 | ** handling the value of a C-card from a manifest. |
| 144 | -** --wordbreak This does nothing and is ignored. | |
| 432 | +** --legacy Use the legacy comment printing algorithm. | |
| 433 | +** --trimcrlf Enable trimming of leading/trailing CR/LF. | |
| 434 | +** --trimspace Enable trimming of leading/trailing spaces. | |
| 435 | +** --wordbreak Attempt to break lines on word boundaries. | |
| 436 | +** --origbreak Attempt to break when the original comment text | |
| 437 | +** is detected. | |
| 438 | +** --indent Number of spaces to indent (default (-1) is to | |
| 439 | +** auto-detect). Zero means no indent. | |
| 440 | +** -W|--width <num> Width of lines (default (-1) is to auto-detect). | |
| 441 | +** Zero means no limit. | |
| 145 | 442 | */ |
| 146 | 443 | void test_comment_format(void){ |
| 444 | + const char *zWidth; | |
| 445 | + const char *zIndent; | |
| 147 | 446 | const char *zPrefix; |
| 148 | 447 | char *zText; |
| 448 | + char *zOrigText; | |
| 149 | 449 | int indent, width; |
| 450 | + int fromFile = find_option("file", 0, 0)!=0; | |
| 150 | 451 | int decode = find_option("decode", 0, 0)!=0; |
| 151 | - find_option("wordbreak", 0, 0); /* NOT USED */ | |
| 152 | - if( g.argc!=4 && g.argc!=5 ){ | |
| 153 | - usage("PREFIX TEXT ?WIDTH?"); | |
| 154 | - } | |
| 155 | - zPrefix = g.argv[2]; | |
| 156 | - if( decode ){ | |
| 157 | - zText = mprintf("%s", g.argv[3]); | |
| 158 | - defossilize(zText); | |
| 159 | - }else{ | |
| 160 | - zText = g.argv[3]; | |
| 161 | - } | |
| 162 | - indent = strlen(zPrefix); | |
| 163 | - if( g.argc==5 ){ | |
| 164 | - width = atoi(g.argv[4]); | |
| 452 | + int flags = COMMENT_PRINT_NONE; | |
| 453 | + if( find_option("legacy", 0, 0) ){ | |
| 454 | + flags |= COMMENT_PRINT_LEGACY; | |
| 455 | + } | |
| 456 | + if( find_option("trimcrlf", 0, 0) ){ | |
| 457 | + flags |= COMMENT_PRINT_TRIM_CRLF; | |
| 458 | + } | |
| 459 | + if( find_option("trimspace", 0, 0) ){ | |
| 460 | + flags |= COMMENT_PRINT_TRIM_SPACE; | |
| 461 | + } | |
| 462 | + if( find_option("wordbreak", 0, 0) ){ | |
| 463 | + flags |= COMMENT_PRINT_WORD_BREAK; | |
| 464 | + } | |
| 465 | + if( find_option("origbreak", 0, 0) ){ | |
| 466 | + flags |= COMMENT_PRINT_ORIG_BREAK; | |
| 467 | + } | |
| 468 | + zWidth = find_option("width","W",1); | |
| 469 | + if( zWidth ){ | |
| 470 | + width = atoi(zWidth); | |
| 165 | 471 | }else{ |
| 166 | 472 | width = -1; /* automatic */ |
| 167 | 473 | } |
| 168 | - if( indent>0 ){ | |
| 474 | + zIndent = find_option("indent",0,1); | |
| 475 | + if( zIndent ){ | |
| 476 | + indent = atoi(zIndent); | |
| 477 | + }else{ | |
| 478 | + indent = -1; /* automatic */ | |
| 479 | + } | |
| 480 | + if( g.argc!=4 && g.argc!=5 ){ | |
| 481 | + usage("?OPTIONS? PREFIX TEXT ?ORIGTEXT?"); | |
| 482 | + } | |
| 483 | + zPrefix = g.argv[2]; | |
| 484 | + zText = g.argv[3]; | |
| 485 | + if( g.argc==5 ){ | |
| 486 | + zOrigText = g.argv[4]; | |
| 487 | + }else{ | |
| 488 | + zOrigText = 0; | |
| 489 | + } | |
| 490 | + if( fromFile ){ | |
| 491 | + Blob fileData; | |
| 492 | + blob_read_from_file(&fileData, zText); | |
| 493 | + zText = mprintf("%s", blob_str(&fileData)); | |
| 494 | + blob_reset(&fileData); | |
| 495 | + if( zOrigText ){ | |
| 496 | + blob_read_from_file(&fileData, zOrigText); | |
| 497 | + zOrigText = mprintf("%s", blob_str(&fileData)); | |
| 498 | + blob_reset(&fileData); | |
| 499 | + } | |
| 500 | + } | |
| 501 | + if( decode ){ | |
| 502 | + zText = mprintf(fromFile ? "%z" : "%s", zText); | |
| 503 | + defossilize(zText); | |
| 504 | + if( zOrigText ){ | |
| 505 | + zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText); | |
| 506 | + defossilize(zOrigText); | |
| 507 | + } | |
| 508 | + } | |
| 509 | + if( indent<0 ){ | |
| 510 | + indent = strlen(zPrefix); | |
| 511 | + } | |
| 512 | + if( zPrefix && *zPrefix ){ | |
| 169 | 513 | fossil_print("%s", zPrefix); |
| 170 | 514 | } |
| 171 | - fossil_print("(%d lines output)\n", comment_print(zText, indent, width)); | |
| 172 | - if( zText!=g.argv[3] ) fossil_free(zText); | |
| 515 | + fossil_print("(%d lines output)\n", | |
| 516 | + comment_print(zText, zOrigText, indent, width, flags)); | |
| 517 | + if( zOrigText && zOrigText!=g.argv[4] ) fossil_free(zOrigText); | |
| 518 | + if( zText && zText!=g.argv[3] ) fossil_free(zText); | |
| 173 | 519 | } |
| 174 | 520 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -23,10 +23,23 @@ | |
| 23 | #include <assert.h> |
| 24 | #ifdef _WIN32 |
| 25 | # include <windows.h> |
| 26 | #else |
| 27 | # include <termios.h> |
| 28 | #endif |
| 29 | |
| 30 | /* |
| 31 | ** This is the previous value used by most external callers when they |
| 32 | ** needed to specify a default maximum line length to be used with the |
| @@ -35,57 +48,239 @@ | |
| 35 | #ifndef COMMENT_LEGACY_LINE_LENGTH |
| 36 | # define COMMENT_LEGACY_LINE_LENGTH (78) |
| 37 | #endif |
| 38 | |
| 39 | /* |
| 40 | ** Given a comment string zText, format that string for printing |
| 41 | ** on a TTY. Assume that the output cursors is indent spaces from |
| 42 | ** the left margin and that a single line can contain no more than |
| 43 | ** lineLength characters. Indent all subsequent lines by indent. |
| 44 | ** |
| 45 | ** Return the number of newlines that are output. |
| 46 | */ |
| 47 | int comment_print(const char *zText, int indent, int lineLength){ |
| 48 | int tlen = lineLength - indent; |
| 49 | int si, sk, i, k; |
| 50 | int doIndent = 0; |
| 51 | char *zBuf; |
| 52 | char zBuffer[400]; |
| 53 | int lineCnt = 0; |
| 54 | |
| 55 | #if defined(_WIN32) |
| 56 | if( lineLength<0 ){ |
| 57 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 58 | memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); |
| 59 | if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){ |
| 60 | tlen = csbi.srWindow.Right - csbi.srWindow.Left - indent; |
| 61 | } |
| 62 | } |
| 63 | #elif defined(TIOCGWINSZ) |
| 64 | if( lineLength<0 ){ |
| 65 | struct winsize w; |
| 66 | memset(&w, 0, sizeof(struct winsize)); |
| 67 | if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){ |
| 68 | tlen = w.ws_col - indent; |
| 69 | } |
| 70 | } |
| 71 | #else |
| 72 | if( lineLength<0 ){ |
| 73 | /* |
| 74 | ** Fallback to using more-or-less the "legacy semantics" of hard-coding |
| 75 | ** the maximum line length to a value reasonable for the vast majority |
| 76 | ** of supported systems. |
| 77 | */ |
| 78 | tlen = COMMENT_LEGACY_LINE_LENGTH - indent; |
| 79 | } |
| 80 | #endif |
| 81 | if( zText==0 ) zText = "(NULL)"; |
| 82 | if( tlen<=0 ){ |
| 83 | tlen = strlen(zText); |
| 84 | } |
| 85 | if( tlen >= (sizeof(zBuffer)) ){ |
| 86 | zBuf = fossil_malloc(tlen+1); |
| 87 | }else{ |
| 88 | zBuf = zBuffer; |
| 89 | } |
| 90 | for(;;){ |
| 91 | while( fossil_isspace(zText[0]) ){ zText++; } |
| @@ -95,11 +290,11 @@ | |
| 95 | lineCnt = 1; |
| 96 | } |
| 97 | if( zBuf!=zBuffer) fossil_free(zBuf); |
| 98 | return lineCnt; |
| 99 | } |
| 100 | for(sk=si=i=k=0; zText[i] && k<tlen; i++){ |
| 101 | char c = zText[i]; |
| 102 | if( fossil_isspace(c) ){ |
| 103 | si = i; |
| 104 | sk = k; |
| 105 | if( k==0 || zBuf[k-1]!=' ' ){ |
| @@ -127,47 +322,198 @@ | |
| 127 | } |
| 128 | fossil_print("%s\n", zBuf); |
| 129 | lineCnt++; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | ** |
| 135 | ** COMMAND: test-comment-format |
| 136 | ** |
| 137 | ** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?WIDTH? |
| 138 | ** |
| 139 | ** Test comment formatting and printing. Use for testing only. |
| 140 | ** |
| 141 | ** Options: |
| 142 | ** --decode Decode the text using the same method used when |
| 143 | ** handling the value of a C-card from a manifest. |
| 144 | ** --wordbreak This does nothing and is ignored. |
| 145 | */ |
| 146 | void test_comment_format(void){ |
| 147 | const char *zPrefix; |
| 148 | char *zText; |
| 149 | int indent, width; |
| 150 | int decode = find_option("decode", 0, 0)!=0; |
| 151 | find_option("wordbreak", 0, 0); /* NOT USED */ |
| 152 | if( g.argc!=4 && g.argc!=5 ){ |
| 153 | usage("PREFIX TEXT ?WIDTH?"); |
| 154 | } |
| 155 | zPrefix = g.argv[2]; |
| 156 | if( decode ){ |
| 157 | zText = mprintf("%s", g.argv[3]); |
| 158 | defossilize(zText); |
| 159 | }else{ |
| 160 | zText = g.argv[3]; |
| 161 | } |
| 162 | indent = strlen(zPrefix); |
| 163 | if( g.argc==5 ){ |
| 164 | width = atoi(g.argv[4]); |
| 165 | }else{ |
| 166 | width = -1; /* automatic */ |
| 167 | } |
| 168 | if( indent>0 ){ |
| 169 | fossil_print("%s", zPrefix); |
| 170 | } |
| 171 | fossil_print("(%d lines output)\n", comment_print(zText, indent, width)); |
| 172 | if( zText!=g.argv[3] ) fossil_free(zText); |
| 173 | } |
| 174 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -23,10 +23,23 @@ | |
| 23 | #include <assert.h> |
| 24 | #ifdef _WIN32 |
| 25 | # include <windows.h> |
| 26 | #else |
| 27 | # include <termios.h> |
| 28 | # if defined(TIOCGWINSZ) |
| 29 | # include <sys/ioctl.h> |
| 30 | # endif |
| 31 | #endif |
| 32 | |
| 33 | #if INTERFACE |
| 34 | #define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags. */ |
| 35 | #define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */ |
| 36 | #define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */ |
| 37 | #define COMMENT_PRINT_TRIM_SPACE ((u32)0x00000004) /* Trim leading/trailing. */ |
| 38 | #define COMMENT_PRINT_WORD_BREAK ((u32)0x00000008) /* Break lines on words. */ |
| 39 | #define COMMENT_PRINT_ORIG_BREAK ((u32)0x00000010) /* Break before original. */ |
| 40 | #define COMMENT_PRINT_DEFAULT (COMMENT_PRINT_LEGACY) /* Defaults. */ |
| 41 | #endif |
| 42 | |
| 43 | /* |
| 44 | ** This is the previous value used by most external callers when they |
| 45 | ** needed to specify a default maximum line length to be used with the |
| @@ -35,57 +48,239 @@ | |
| 48 | #ifndef COMMENT_LEGACY_LINE_LENGTH |
| 49 | # define COMMENT_LEGACY_LINE_LENGTH (78) |
| 50 | #endif |
| 51 | |
| 52 | /* |
| 53 | ** This is the number of spaces to print when a tab character is seen. |
| 54 | */ |
| 55 | #ifndef COMMENT_TAB_WIDTH |
| 56 | # define COMMENT_TAB_WIDTH (8) |
| 57 | #endif |
| 58 | |
| 59 | /* |
| 60 | ** This function sets the maximum number of characters to print per line |
| 61 | ** based on the detected terminal line width, if available; otherwise, it |
| 62 | ** uses the legacy default terminal line width minus the amount to indent. |
| 63 | ** |
| 64 | ** Zero is returned to indicate any failure. One is returned to indicate |
| 65 | ** the successful detection of the terminal line width. Negative one is |
| 66 | ** returned to indicate the terminal line width is using the hard-coded |
| 67 | ** legacy default value. |
| 68 | */ |
| 69 | static int comment_set_maxchars( |
| 70 | int indent, |
| 71 | int *pMaxChars |
| 72 | ){ |
| 73 | #if defined(_WIN32) |
| 74 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 75 | memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); |
| 76 | if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){ |
| 77 | *pMaxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent; |
| 78 | return 1; |
| 79 | } |
| 80 | return 0; |
| 81 | #elif defined(TIOCGWINSZ) |
| 82 | struct winsize w; |
| 83 | memset(&w, 0, sizeof(struct winsize)); |
| 84 | if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){ |
| 85 | *pMaxChars = w.ws_col - indent; |
| 86 | return 1; |
| 87 | } |
| 88 | return 0; |
| 89 | #else |
| 90 | /* |
| 91 | ** Fallback to using more-or-less the "legacy semantics" of hard-coding |
| 92 | ** the maximum line length to a value reasonable for the vast majority |
| 93 | ** of supported systems. |
| 94 | */ |
| 95 | *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent; |
| 96 | return -1; |
| 97 | #endif |
| 98 | } |
| 99 | |
| 100 | /* |
| 101 | ** This function checks the current line being printed against the original |
| 102 | ** comment text. Upon matching, it emits a new line and updates the provided |
| 103 | ** character and line counts, if applicable. |
| 104 | */ |
| 105 | static int comment_check_orig( |
| 106 | const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */ |
| 107 | const char *zLine, /* [in] The comment line to print. */ |
| 108 | int *pCharCnt, /* [in/out] Pointer to the line character count. */ |
| 109 | int *pLineCnt /* [in/out] Pointer to the total line count. */ |
| 110 | ){ |
| 111 | if( zOrigText && fossil_strcmp(zLine, zOrigText)==0 ){ |
| 112 | fossil_print("\n"); |
| 113 | if( pCharCnt ) *pCharCnt = 0; |
| 114 | if( pLineCnt ) (*pLineCnt)++; |
| 115 | return 1; |
| 116 | } |
| 117 | return 0; |
| 118 | } |
| 119 | |
| 120 | /* |
| 121 | ** This function scans the specified comment line starting just after the |
| 122 | ** initial index and returns the index of the next spacing character -OR- |
| 123 | ** zero if such a character cannot be found. For the purposes of this |
| 124 | ** algorithm, the NUL character is treated the same as a spacing character. |
| 125 | */ |
| 126 | static int comment_next_space( |
| 127 | const char *zLine, /* [in] The comment line being printed. */ |
| 128 | int index /* [in] The current character index being handled. */ |
| 129 | ){ |
| 130 | int nextIndex = index + 1; |
| 131 | for(;;){ |
| 132 | char c = zLine[nextIndex]; |
| 133 | if( c==0 || fossil_isspace(c) ){ |
| 134 | return nextIndex; |
| 135 | } |
| 136 | nextIndex++; |
| 137 | } |
| 138 | return 0; /* NOT REACHED */ |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** This function is called when printing a logical comment line to perform |
| 143 | ** the necessary indenting. |
| 144 | */ |
| 145 | static void comment_print_indent( |
| 146 | const char *zLine, /* [in] The comment line being printed. */ |
| 147 | int indent, /* [in] Number of spaces to indent, zero for none. */ |
| 148 | int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */ |
| 149 | int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */ |
| 150 | int *piIndex /* [in/out] Pointer to first non-space character. */ |
| 151 | ){ |
| 152 | if( indent>0 ){ |
| 153 | fossil_print("%*s", indent, ""); |
| 154 | } |
| 155 | if( zLine && piIndex ){ |
| 156 | int index = *piIndex; |
| 157 | if( trimCrLf ){ |
| 158 | while( zLine[index]=='\r' || zLine[index]=='\n' ){ index++; } |
| 159 | } |
| 160 | if( trimSpace ){ |
| 161 | while( fossil_isspace(zLine[index]) ){ index++; } |
| 162 | } |
| 163 | *piIndex = index; |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | ** This function prints one logical line of a comment, stopping when it hits |
| 169 | ** a new line -OR- runs out of space on the logical line. |
| 170 | */ |
| 171 | static void comment_print_line( |
| 172 | const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */ |
| 173 | const char *zLine, /* [in] The comment line to print. */ |
| 174 | int origIndent, /* [in] Number of spaces to indent before the original |
| 175 | ** comment. */ |
| 176 | int indent, /* [in] Number of spaces to indent, before the line |
| 177 | ** to print. */ |
| 178 | int lineChars, /* [in] Maximum number of characters to print. */ |
| 179 | int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */ |
| 180 | int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */ |
| 181 | int wordBreak, /* [in] Non-zero to try breaking on word boundaries. */ |
| 182 | int origBreak, /* [in] Non-zero to break before original comment. */ |
| 183 | int *pLineCnt, /* [in/out] Pointer to the total line count. */ |
| 184 | const char **pzLine /* [out] Pointer to the end of the logical line. */ |
| 185 | ){ |
| 186 | int index = 0, charCnt = 0, lineCnt = 0, maxChars; |
| 187 | if( !zLine ) return; |
| 188 | if( lineChars<=0 ) return; |
| 189 | comment_print_indent(zLine, indent, trimCrLf, trimSpace, &index); |
| 190 | maxChars = lineChars; |
| 191 | for(;;){ |
| 192 | int useChars = 1; |
| 193 | char c = zLine[index]; |
| 194 | if( c==0 ){ |
| 195 | break; |
| 196 | }else{ |
| 197 | if( origBreak && index>0 ){ |
| 198 | const char *zCurrent = &zLine[index]; |
| 199 | if( comment_check_orig(zOrigText, zCurrent, &charCnt, &lineCnt) ){ |
| 200 | comment_print_indent(zCurrent, origIndent, trimCrLf, trimSpace, |
| 201 | &index); |
| 202 | maxChars = lineChars; |
| 203 | } |
| 204 | } |
| 205 | index++; |
| 206 | } |
| 207 | if( c=='\n' ){ |
| 208 | lineCnt++; |
| 209 | charCnt = 0; |
| 210 | useChars = 0; |
| 211 | }else if( c=='\t' ){ |
| 212 | int nextIndex = comment_next_space(zLine, index); |
| 213 | if( nextIndex<=0 || (nextIndex-index)>maxChars ){ |
| 214 | break; |
| 215 | } |
| 216 | charCnt++; |
| 217 | useChars = COMMENT_TAB_WIDTH; |
| 218 | if( maxChars<useChars ){ |
| 219 | fossil_print(" "); |
| 220 | break; |
| 221 | } |
| 222 | }else if( wordBreak && fossil_isspace(c) ){ |
| 223 | int nextIndex = comment_next_space(zLine, index); |
| 224 | if( nextIndex<=0 || (nextIndex-index)>maxChars ){ |
| 225 | break; |
| 226 | } |
| 227 | charCnt++; |
| 228 | }else{ |
| 229 | charCnt++; |
| 230 | } |
| 231 | assert( c!='\n' || charCnt==0 ); |
| 232 | fossil_print("%c", c); |
| 233 | maxChars -= useChars; |
| 234 | if( maxChars==0 ) break; |
| 235 | assert( maxChars>0 ); |
| 236 | if( c=='\n' ) break; |
| 237 | } |
| 238 | if( charCnt>0 ){ |
| 239 | fossil_print("\n"); |
| 240 | lineCnt++; |
| 241 | } |
| 242 | if( pLineCnt ){ |
| 243 | *pLineCnt += lineCnt; |
| 244 | } |
| 245 | if( pzLine ){ |
| 246 | *pzLine = zLine + index; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | /* |
| 251 | ** This is the legacy comment printing algorithm. It is being retained |
| 252 | ** for backward compatibility. |
| 253 | ** |
| 254 | ** Given a comment string, format that string for printing on a TTY. |
| 255 | ** Assume that the output cursors is indent spaces from the left margin |
| 256 | ** and that a single line can contain no more than 'width' characters. |
| 257 | ** Indent all subsequent lines by 'indent'. |
| 258 | ** |
| 259 | ** Returns the number of new lines emitted. |
| 260 | */ |
| 261 | static int comment_print_legacy( |
| 262 | const char *zText, /* The comment text to be printed. */ |
| 263 | int indent, /* Number of spaces to indent each non-initial line. */ |
| 264 | int width /* Maximum number of characters per line. */ |
| 265 | ){ |
| 266 | int maxChars = width - indent; |
| 267 | int si, sk, i, k; |
| 268 | int doIndent = 0; |
| 269 | char *zBuf; |
| 270 | char zBuffer[400]; |
| 271 | int lineCnt = 0; |
| 272 | |
| 273 | if( width<0 ){ |
| 274 | comment_set_maxchars(indent, &maxChars); |
| 275 | } |
| 276 | if( zText==0 ) zText = "(NULL)"; |
| 277 | if( maxChars<=0 ){ |
| 278 | maxChars = strlen(zText); |
| 279 | } |
| 280 | if( maxChars >= (sizeof(zBuffer)) ){ |
| 281 | zBuf = fossil_malloc(maxChars+1); |
| 282 | }else{ |
| 283 | zBuf = zBuffer; |
| 284 | } |
| 285 | for(;;){ |
| 286 | while( fossil_isspace(zText[0]) ){ zText++; } |
| @@ -95,11 +290,11 @@ | |
| 290 | lineCnt = 1; |
| 291 | } |
| 292 | if( zBuf!=zBuffer) fossil_free(zBuf); |
| 293 | return lineCnt; |
| 294 | } |
| 295 | for(sk=si=i=k=0; zText[i] && k<maxChars; i++){ |
| 296 | char c = zText[i]; |
| 297 | if( fossil_isspace(c) ){ |
| 298 | si = i; |
| 299 | sk = k; |
| 300 | if( k==0 || zBuf[k-1]!=' ' ){ |
| @@ -127,47 +322,198 @@ | |
| 322 | } |
| 323 | fossil_print("%s\n", zBuf); |
| 324 | lineCnt++; |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | /* |
| 329 | ** This is the comment printing function. The comment printing algorithm |
| 330 | ** contained within it attempts to preserve the formatting present within |
| 331 | ** the comment string itself while honoring line width limitations. There |
| 332 | ** are several flags that modify the default behavior of this function: |
| 333 | ** |
| 334 | ** COMMENT_PRINT_LEGACY: Forces use of the legacy comment printing |
| 335 | ** algorithm. For backward compatibility, |
| 336 | ** this is the default. |
| 337 | ** |
| 338 | ** COMMENT_PRINT_TRIM_CRLF: Trims leading and trailing carriage-returns |
| 339 | ** and line-feeds where they do not materially |
| 340 | ** impact pre-existing formatting (i.e. at the |
| 341 | ** start of the comment string -AND- right |
| 342 | ** before line indentation). This flag does |
| 343 | ** not apply to the legacy comment printing |
| 344 | ** algorithm. This flag may be combined with |
| 345 | ** COMMENT_PRINT_TRIM_SPACE. |
| 346 | ** |
| 347 | ** COMMENT_PRINT_TRIM_SPACE: Trims leading and trailing spaces where they |
| 348 | ** do not materially impact the pre-existing |
| 349 | ** formatting (i.e. at the start of the comment |
| 350 | ** string -AND- right before line indentation). |
| 351 | ** This flag does not apply to the legacy |
| 352 | ** comment printing algorithm. This flag may |
| 353 | ** be combined with COMMENT_PRINT_TRIM_CRLF. |
| 354 | ** |
| 355 | ** COMMENT_PRINT_WORD_BREAK: Attempts to break lines on word boundaries |
| 356 | ** while honoring the logical line length. |
| 357 | ** If this flag is not specified, honoring the |
| 358 | ** logical line length may result in breaking |
| 359 | ** lines in the middle of words. This flag |
| 360 | ** does not apply to the legacy comment |
| 361 | ** printing algorithm. |
| 362 | ** |
| 363 | ** COMMENT_PRINT_ORIG_BREAK: Looks for the original comment text within |
| 364 | ** the text being printed. Upon matching, a |
| 365 | ** new line will be emitted, thus preserving |
| 366 | ** more of the pre-existing formatting. |
| 367 | ** |
| 368 | ** Given a comment string, format that string for printing on a TTY. |
| 369 | ** Assume that the output cursors is indent spaces from the left margin |
| 370 | ** and that a single line can contain no more than 'width' characters. |
| 371 | ** Indent all subsequent lines by 'indent'. |
| 372 | ** |
| 373 | ** Returns the number of new lines emitted. |
| 374 | */ |
| 375 | int comment_print( |
| 376 | const char *zText, /* The comment text to be printed. */ |
| 377 | const char *zOrigText, /* Original comment text ONLY, may be NULL. */ |
| 378 | int indent, /* Spaces to indent each non-initial line. */ |
| 379 | int width, /* Maximum number of characters per line. */ |
| 380 | int flags /* Zero or more "COMMENT_PRINT_*" flags. */ |
| 381 | ){ |
| 382 | int maxChars = width - indent; |
| 383 | int legacy = flags & COMMENT_PRINT_LEGACY; |
| 384 | int trimCrLf = flags & COMMENT_PRINT_TRIM_CRLF; |
| 385 | int trimSpace = flags & COMMENT_PRINT_TRIM_SPACE; |
| 386 | int wordBreak = flags & COMMENT_PRINT_WORD_BREAK; |
| 387 | int origBreak = flags & COMMENT_PRINT_ORIG_BREAK; |
| 388 | int lineCnt = 0; |
| 389 | const char *zLine; |
| 390 | |
| 391 | if( legacy ){ |
| 392 | return comment_print_legacy(zText, indent, width); |
| 393 | } |
| 394 | if( width<0 ){ |
| 395 | comment_set_maxchars(indent, &maxChars); |
| 396 | } |
| 397 | if( zText==0 ) zText = "(NULL)"; |
| 398 | if( maxChars<=0 ){ |
| 399 | maxChars = strlen(zText); |
| 400 | } |
| 401 | if( trimSpace ){ |
| 402 | while( fossil_isspace(zText[0]) ){ zText++; } |
| 403 | } |
| 404 | if( zText[0]==0 ){ |
| 405 | fossil_print("\n"); |
| 406 | lineCnt++; |
| 407 | return lineCnt; |
| 408 | } |
| 409 | zLine = zText; |
| 410 | for(;;){ |
| 411 | comment_print_line(zOrigText, zLine, indent, zLine>zText ? indent : 0, |
| 412 | maxChars, trimCrLf, trimSpace, wordBreak, origBreak, |
| 413 | &lineCnt, &zLine); |
| 414 | if( !zLine || !zLine[0] ) break; |
| 415 | } |
| 416 | return lineCnt; |
| 417 | } |
| 418 | |
| 419 | /* |
| 420 | ** |
| 421 | ** COMMAND: test-comment-format |
| 422 | ** |
| 423 | ** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?ORIGTEXT? |
| 424 | ** |
| 425 | ** Test comment formatting and printing. Use for testing only. |
| 426 | ** |
| 427 | ** Options: |
| 428 | ** --file The comment text is really just a file name to |
| 429 | ** read it from. |
| 430 | ** --decode Decode the text using the same method used when |
| 431 | ** handling the value of a C-card from a manifest. |
| 432 | ** --legacy Use the legacy comment printing algorithm. |
| 433 | ** --trimcrlf Enable trimming of leading/trailing CR/LF. |
| 434 | ** --trimspace Enable trimming of leading/trailing spaces. |
| 435 | ** --wordbreak Attempt to break lines on word boundaries. |
| 436 | ** --origbreak Attempt to break when the original comment text |
| 437 | ** is detected. |
| 438 | ** --indent Number of spaces to indent (default (-1) is to |
| 439 | ** auto-detect). Zero means no indent. |
| 440 | ** -W|--width <num> Width of lines (default (-1) is to auto-detect). |
| 441 | ** Zero means no limit. |
| 442 | */ |
| 443 | void test_comment_format(void){ |
| 444 | const char *zWidth; |
| 445 | const char *zIndent; |
| 446 | const char *zPrefix; |
| 447 | char *zText; |
| 448 | char *zOrigText; |
| 449 | int indent, width; |
| 450 | int fromFile = find_option("file", 0, 0)!=0; |
| 451 | int decode = find_option("decode", 0, 0)!=0; |
| 452 | int flags = COMMENT_PRINT_NONE; |
| 453 | if( find_option("legacy", 0, 0) ){ |
| 454 | flags |= COMMENT_PRINT_LEGACY; |
| 455 | } |
| 456 | if( find_option("trimcrlf", 0, 0) ){ |
| 457 | flags |= COMMENT_PRINT_TRIM_CRLF; |
| 458 | } |
| 459 | if( find_option("trimspace", 0, 0) ){ |
| 460 | flags |= COMMENT_PRINT_TRIM_SPACE; |
| 461 | } |
| 462 | if( find_option("wordbreak", 0, 0) ){ |
| 463 | flags |= COMMENT_PRINT_WORD_BREAK; |
| 464 | } |
| 465 | if( find_option("origbreak", 0, 0) ){ |
| 466 | flags |= COMMENT_PRINT_ORIG_BREAK; |
| 467 | } |
| 468 | zWidth = find_option("width","W",1); |
| 469 | if( zWidth ){ |
| 470 | width = atoi(zWidth); |
| 471 | }else{ |
| 472 | width = -1; /* automatic */ |
| 473 | } |
| 474 | zIndent = find_option("indent",0,1); |
| 475 | if( zIndent ){ |
| 476 | indent = atoi(zIndent); |
| 477 | }else{ |
| 478 | indent = -1; /* automatic */ |
| 479 | } |
| 480 | if( g.argc!=4 && g.argc!=5 ){ |
| 481 | usage("?OPTIONS? PREFIX TEXT ?ORIGTEXT?"); |
| 482 | } |
| 483 | zPrefix = g.argv[2]; |
| 484 | zText = g.argv[3]; |
| 485 | if( g.argc==5 ){ |
| 486 | zOrigText = g.argv[4]; |
| 487 | }else{ |
| 488 | zOrigText = 0; |
| 489 | } |
| 490 | if( fromFile ){ |
| 491 | Blob fileData; |
| 492 | blob_read_from_file(&fileData, zText); |
| 493 | zText = mprintf("%s", blob_str(&fileData)); |
| 494 | blob_reset(&fileData); |
| 495 | if( zOrigText ){ |
| 496 | blob_read_from_file(&fileData, zOrigText); |
| 497 | zOrigText = mprintf("%s", blob_str(&fileData)); |
| 498 | blob_reset(&fileData); |
| 499 | } |
| 500 | } |
| 501 | if( decode ){ |
| 502 | zText = mprintf(fromFile ? "%z" : "%s", zText); |
| 503 | defossilize(zText); |
| 504 | if( zOrigText ){ |
| 505 | zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText); |
| 506 | defossilize(zOrigText); |
| 507 | } |
| 508 | } |
| 509 | if( indent<0 ){ |
| 510 | indent = strlen(zPrefix); |
| 511 | } |
| 512 | if( zPrefix && *zPrefix ){ |
| 513 | fossil_print("%s", zPrefix); |
| 514 | } |
| 515 | fossil_print("(%d lines output)\n", |
| 516 | comment_print(zText, zOrigText, indent, width, flags)); |
| 517 | if( zOrigText && zOrigText!=g.argv[4] ) fossil_free(zOrigText); |
| 518 | if( zText && zText!=g.argv[3] ) fossil_free(zText); |
| 519 | } |
| 520 |
+5
| --- src/config.h | ||
| +++ src/config.h | ||
| @@ -24,10 +24,15 @@ | ||
| 24 | 24 | #define _LARGE_FILE 1 |
| 25 | 25 | #ifndef _FILE_OFFSET_BITS |
| 26 | 26 | # define _FILE_OFFSET_BITS 64 |
| 27 | 27 | #endif |
| 28 | 28 | #define _LARGEFILE_SOURCE 1 |
| 29 | + | |
| 30 | +/* Needed for various definitions... */ | |
| 31 | +#ifndef _GNU_SOURCE | |
| 32 | +# define _GNU_SOURCE | |
| 33 | +#endif | |
| 29 | 34 | |
| 30 | 35 | /* Make sure that in Win32 MinGW builds, _USE_32BIT_TIME_T is always defined. */ |
| 31 | 36 | #if defined(_WIN32) && !defined(_WIN64) && !defined(_MSC_VER) && !defined(_USE_32BIT_TIME_T) |
| 32 | 37 | # define _USE_32BIT_TIME_T |
| 33 | 38 | #endif |
| 34 | 39 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -24,10 +24,15 @@ | |
| 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 | /* Make sure that in Win32 MinGW builds, _USE_32BIT_TIME_T is always defined. */ |
| 31 | #if defined(_WIN32) && !defined(_WIN64) && !defined(_MSC_VER) && !defined(_USE_32BIT_TIME_T) |
| 32 | # define _USE_32BIT_TIME_T |
| 33 | #endif |
| 34 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -24,10 +24,15 @@ | |
| 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 | /* Needed for various definitions... */ |
| 31 | #ifndef _GNU_SOURCE |
| 32 | # define _GNU_SOURCE |
| 33 | #endif |
| 34 | |
| 35 | /* Make sure that in Win32 MinGW builds, _USE_32BIT_TIME_T is always defined. */ |
| 36 | #if defined(_WIN32) && !defined(_WIN64) && !defined(_MSC_VER) && !defined(_USE_32BIT_TIME_T) |
| 37 | # define _USE_32BIT_TIME_T |
| 38 | #endif |
| 39 |
M
src/db.c
+14
-8
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1069,10 +1069,13 @@ | ||
| 1069 | 1069 | ** |
| 1070 | 1070 | ** Error out if the repository cannot be opened. |
| 1071 | 1071 | */ |
| 1072 | 1072 | void db_find_and_open_repository(int bFlags, int nArgUsed){ |
| 1073 | 1073 | const char *zRep = find_repository_option(); |
| 1074 | + if( zRep && file_isdir(zRep)==1 ){ | |
| 1075 | + goto rep_not_found; | |
| 1076 | + } | |
| 1074 | 1077 | if( zRep==0 && nArgUsed && g.argc==nArgUsed+1 ){ |
| 1075 | 1078 | zRep = g.argv[nArgUsed]; |
| 1076 | 1079 | } |
| 1077 | 1080 | if( zRep==0 ){ |
| 1078 | 1081 | if( db_open_local(0)==0 ){ |
| @@ -1465,29 +1468,28 @@ | ||
| 1465 | 1468 | ** |
| 1466 | 1469 | ** Options: |
| 1467 | 1470 | ** --template FILE copy settings from repository file |
| 1468 | 1471 | ** --admin-user|-A USERNAME select given USERNAME as admin user |
| 1469 | 1472 | ** --date-override DATETIME use DATETIME as time of the initial checkin |
| 1470 | -** (overrides --empty as well) | |
| 1471 | -** --empty Do not create an initial empty checkin. | |
| 1473 | +** (default: do not create an initial checkin) | |
| 1472 | 1474 | ** |
| 1473 | 1475 | ** See also: clone |
| 1474 | 1476 | */ |
| 1475 | 1477 | void create_repository_cmd(void){ |
| 1476 | 1478 | char *zPassword; |
| 1477 | 1479 | const char *zTemplate; /* Repository from which to copy settings */ |
| 1478 | 1480 | const char *zDate; /* Date of the initial check-in */ |
| 1479 | 1481 | const char *zDefaultUser; /* Optional name of the default user */ |
| 1480 | - char const *zCreateEmpty; /* --empty flag set? */ | |
| 1481 | 1482 | |
| 1482 | 1483 | zTemplate = find_option("template",0,1); |
| 1483 | 1484 | zDate = find_option("date-override",0,1); |
| 1484 | 1485 | zDefaultUser = find_option("admin-user","A",1); |
| 1485 | - zCreateEmpty = find_option("empty", 0, 0); | |
| 1486 | - if( !zDate && !zCreateEmpty ){ | |
| 1487 | - zDate = "now"; | |
| 1488 | - } | |
| 1486 | + find_option("empty", 0, 0); /* deprecated */ | |
| 1487 | + | |
| 1488 | + /* We should be done with options.. */ | |
| 1489 | + verify_all_options(); | |
| 1490 | + | |
| 1489 | 1491 | if( g.argc!=3 ){ |
| 1490 | 1492 | usage("REPOSITORY-NAME"); |
| 1491 | 1493 | } |
| 1492 | 1494 | db_create_repository(g.argv[2]); |
| 1493 | 1495 | db_open_repository(g.argv[2]); |
| @@ -2038,10 +2040,14 @@ | ||
| 2038 | 2040 | url_proxy_options(); |
| 2039 | 2041 | emptyFlag = find_option("empty",0,0)!=0; |
| 2040 | 2042 | keepFlag = find_option("keep",0,0)!=0; |
| 2041 | 2043 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 2042 | 2044 | allowNested = find_option("nested",0,0)!=0; |
| 2045 | + | |
| 2046 | + /* We should be done with options.. */ | |
| 2047 | + verify_all_options(); | |
| 2048 | + | |
| 2043 | 2049 | if( g.argc!=3 && g.argc!=4 ){ |
| 2044 | 2050 | usage("REPOSITORY-FILENAME ?VERSION?"); |
| 2045 | 2051 | } |
| 2046 | 2052 | if( !allowNested && db_open_local(0) ){ |
| 2047 | 2053 | fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot); |
| @@ -2153,11 +2159,11 @@ | ||
| 2153 | 2159 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2154 | 2160 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2155 | 2161 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2156 | 2162 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2157 | 2163 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2158 | - { "autosync-tries", 0, 0, 0, 0, "" }, | |
| 2164 | + { "autosync-tries", 0, 16, 0, 0, "1" }, | |
| 2159 | 2165 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2160 | 2166 | { "clearsign", 0, 0, 0, 0, "off" }, |
| 2161 | 2167 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2162 | 2168 | defined(__APPLE__) |
| 2163 | 2169 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2164 | 2170 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1069,10 +1069,13 @@ | |
| 1069 | ** |
| 1070 | ** Error out if the repository cannot be opened. |
| 1071 | */ |
| 1072 | void db_find_and_open_repository(int bFlags, int nArgUsed){ |
| 1073 | const char *zRep = find_repository_option(); |
| 1074 | if( zRep==0 && nArgUsed && g.argc==nArgUsed+1 ){ |
| 1075 | zRep = g.argv[nArgUsed]; |
| 1076 | } |
| 1077 | if( zRep==0 ){ |
| 1078 | if( db_open_local(0)==0 ){ |
| @@ -1465,29 +1468,28 @@ | |
| 1465 | ** |
| 1466 | ** Options: |
| 1467 | ** --template FILE copy settings from repository file |
| 1468 | ** --admin-user|-A USERNAME select given USERNAME as admin user |
| 1469 | ** --date-override DATETIME use DATETIME as time of the initial checkin |
| 1470 | ** (overrides --empty as well) |
| 1471 | ** --empty Do not create an initial empty checkin. |
| 1472 | ** |
| 1473 | ** See also: clone |
| 1474 | */ |
| 1475 | void create_repository_cmd(void){ |
| 1476 | char *zPassword; |
| 1477 | const char *zTemplate; /* Repository from which to copy settings */ |
| 1478 | const char *zDate; /* Date of the initial check-in */ |
| 1479 | const char *zDefaultUser; /* Optional name of the default user */ |
| 1480 | char const *zCreateEmpty; /* --empty flag set? */ |
| 1481 | |
| 1482 | zTemplate = find_option("template",0,1); |
| 1483 | zDate = find_option("date-override",0,1); |
| 1484 | zDefaultUser = find_option("admin-user","A",1); |
| 1485 | zCreateEmpty = find_option("empty", 0, 0); |
| 1486 | if( !zDate && !zCreateEmpty ){ |
| 1487 | zDate = "now"; |
| 1488 | } |
| 1489 | if( g.argc!=3 ){ |
| 1490 | usage("REPOSITORY-NAME"); |
| 1491 | } |
| 1492 | db_create_repository(g.argv[2]); |
| 1493 | db_open_repository(g.argv[2]); |
| @@ -2038,10 +2040,14 @@ | |
| 2038 | url_proxy_options(); |
| 2039 | emptyFlag = find_option("empty",0,0)!=0; |
| 2040 | keepFlag = find_option("keep",0,0)!=0; |
| 2041 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 2042 | allowNested = find_option("nested",0,0)!=0; |
| 2043 | if( g.argc!=3 && g.argc!=4 ){ |
| 2044 | usage("REPOSITORY-FILENAME ?VERSION?"); |
| 2045 | } |
| 2046 | if( !allowNested && db_open_local(0) ){ |
| 2047 | fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot); |
| @@ -2153,11 +2159,11 @@ | |
| 2153 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2154 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2155 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2156 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2157 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2158 | { "autosync-tries", 0, 0, 0, 0, "" }, |
| 2159 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2160 | { "clearsign", 0, 0, 0, 0, "off" }, |
| 2161 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2162 | defined(__APPLE__) |
| 2163 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2164 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1069,10 +1069,13 @@ | |
| 1069 | ** |
| 1070 | ** Error out if the repository cannot be opened. |
| 1071 | */ |
| 1072 | void db_find_and_open_repository(int bFlags, int nArgUsed){ |
| 1073 | const char *zRep = find_repository_option(); |
| 1074 | if( zRep && file_isdir(zRep)==1 ){ |
| 1075 | goto rep_not_found; |
| 1076 | } |
| 1077 | if( zRep==0 && nArgUsed && g.argc==nArgUsed+1 ){ |
| 1078 | zRep = g.argv[nArgUsed]; |
| 1079 | } |
| 1080 | if( zRep==0 ){ |
| 1081 | if( db_open_local(0)==0 ){ |
| @@ -1465,29 +1468,28 @@ | |
| 1468 | ** |
| 1469 | ** Options: |
| 1470 | ** --template FILE copy settings from repository file |
| 1471 | ** --admin-user|-A USERNAME select given USERNAME as admin user |
| 1472 | ** --date-override DATETIME use DATETIME as time of the initial checkin |
| 1473 | ** (default: do not create an initial checkin) |
| 1474 | ** |
| 1475 | ** See also: clone |
| 1476 | */ |
| 1477 | void create_repository_cmd(void){ |
| 1478 | char *zPassword; |
| 1479 | const char *zTemplate; /* Repository from which to copy settings */ |
| 1480 | const char *zDate; /* Date of the initial check-in */ |
| 1481 | const char *zDefaultUser; /* Optional name of the default user */ |
| 1482 | |
| 1483 | zTemplate = find_option("template",0,1); |
| 1484 | zDate = find_option("date-override",0,1); |
| 1485 | zDefaultUser = find_option("admin-user","A",1); |
| 1486 | find_option("empty", 0, 0); /* deprecated */ |
| 1487 | |
| 1488 | /* We should be done with options.. */ |
| 1489 | verify_all_options(); |
| 1490 | |
| 1491 | if( g.argc!=3 ){ |
| 1492 | usage("REPOSITORY-NAME"); |
| 1493 | } |
| 1494 | db_create_repository(g.argv[2]); |
| 1495 | db_open_repository(g.argv[2]); |
| @@ -2038,10 +2040,14 @@ | |
| 2040 | url_proxy_options(); |
| 2041 | emptyFlag = find_option("empty",0,0)!=0; |
| 2042 | keepFlag = find_option("keep",0,0)!=0; |
| 2043 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 2044 | allowNested = find_option("nested",0,0)!=0; |
| 2045 | |
| 2046 | /* We should be done with options.. */ |
| 2047 | verify_all_options(); |
| 2048 | |
| 2049 | if( g.argc!=3 && g.argc!=4 ){ |
| 2050 | usage("REPOSITORY-FILENAME ?VERSION?"); |
| 2051 | } |
| 2052 | if( !allowNested && db_open_local(0) ){ |
| 2053 | fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot); |
| @@ -2153,11 +2159,11 @@ | |
| 2159 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2160 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2161 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2162 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2163 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2164 | { "autosync-tries", 0, 16, 0, 0, "1" }, |
| 2165 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2166 | { "clearsign", 0, 0, 0, 0, "off" }, |
| 2167 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2168 | defined(__APPLE__) |
| 2169 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2170 |
+15
-2
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -130,10 +130,15 @@ | ||
| 130 | 130 | db_finalize(&ins); |
| 131 | 131 | db_finalize(&isBr); |
| 132 | 132 | db_finalize(&q1); |
| 133 | 133 | bag_clear(&pending); |
| 134 | 134 | bag_clear(&seen); |
| 135 | + }else{ | |
| 136 | + db_multi_exec( | |
| 137 | + "INSERT INTO leaves" | |
| 138 | + " SELECT leaf.rid FROM leaf" | |
| 139 | + ); | |
| 135 | 140 | } |
| 136 | 141 | if( closeMode==1 ){ |
| 137 | 142 | db_multi_exec( |
| 138 | 143 | "DELETE FROM leaves WHERE rid IN" |
| 139 | 144 | " (SELECT leaves.rid FROM leaves, tagxref" |
| @@ -312,10 +317,14 @@ | ||
| 312 | 317 | fossil_fatal("-W|--width value must be >20 or 0"); |
| 313 | 318 | } |
| 314 | 319 | }else{ |
| 315 | 320 | width = -1; |
| 316 | 321 | } |
| 322 | + | |
| 323 | + /* We should be done with options.. */ | |
| 324 | + verify_all_options(); | |
| 325 | + | |
| 317 | 326 | if( g.argc==2 ){ |
| 318 | 327 | base = db_lget_int("checkout", 0); |
| 319 | 328 | }else{ |
| 320 | 329 | base = name_to_typed_rid(g.argv[2], "ci"); |
| 321 | 330 | } |
| @@ -373,10 +382,14 @@ | ||
| 373 | 382 | } |
| 374 | 383 | }else{ |
| 375 | 384 | width = -1; |
| 376 | 385 | } |
| 377 | 386 | db_find_and_open_repository(0,0); |
| 387 | + | |
| 388 | + /* We should be done with options.. */ | |
| 389 | + verify_all_options(); | |
| 390 | + | |
| 378 | 391 | if( recomputeFlag ) leaf_rebuild(); |
| 379 | 392 | blob_zero(&sql); |
| 380 | 393 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 381 | 394 | blob_appendf(&sql, " AND blob.rid IN leaf"); |
| 382 | 395 | if( showClosed ){ |
| @@ -406,12 +419,12 @@ | ||
| 406 | 419 | zLastBr = fossil_strdup(zBr); |
| 407 | 420 | } |
| 408 | 421 | n++; |
| 409 | 422 | sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n); |
| 410 | 423 | fossil_print("%6s ", zLineNo); |
| 411 | - z = mprintf("%s [%.10s] %s", zDate, zId, zCom); | |
| 412 | - comment_print(z, 7, width); | |
| 424 | + z = mprintf("%s [%S] %s", zDate, zId, zCom); | |
| 425 | + comment_print(z, zCom, 7, width, g.comFmtFlags); | |
| 413 | 426 | fossil_free(z); |
| 414 | 427 | } |
| 415 | 428 | fossil_free(zLastBr); |
| 416 | 429 | db_finalize(&q); |
| 417 | 430 | } |
| 418 | 431 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -130,10 +130,15 @@ | |
| 130 | db_finalize(&ins); |
| 131 | db_finalize(&isBr); |
| 132 | db_finalize(&q1); |
| 133 | bag_clear(&pending); |
| 134 | bag_clear(&seen); |
| 135 | } |
| 136 | if( closeMode==1 ){ |
| 137 | db_multi_exec( |
| 138 | "DELETE FROM leaves WHERE rid IN" |
| 139 | " (SELECT leaves.rid FROM leaves, tagxref" |
| @@ -312,10 +317,14 @@ | |
| 312 | fossil_fatal("-W|--width value must be >20 or 0"); |
| 313 | } |
| 314 | }else{ |
| 315 | width = -1; |
| 316 | } |
| 317 | if( g.argc==2 ){ |
| 318 | base = db_lget_int("checkout", 0); |
| 319 | }else{ |
| 320 | base = name_to_typed_rid(g.argv[2], "ci"); |
| 321 | } |
| @@ -373,10 +382,14 @@ | |
| 373 | } |
| 374 | }else{ |
| 375 | width = -1; |
| 376 | } |
| 377 | db_find_and_open_repository(0,0); |
| 378 | if( recomputeFlag ) leaf_rebuild(); |
| 379 | blob_zero(&sql); |
| 380 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 381 | blob_appendf(&sql, " AND blob.rid IN leaf"); |
| 382 | if( showClosed ){ |
| @@ -406,12 +419,12 @@ | |
| 406 | zLastBr = fossil_strdup(zBr); |
| 407 | } |
| 408 | n++; |
| 409 | sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n); |
| 410 | fossil_print("%6s ", zLineNo); |
| 411 | z = mprintf("%s [%.10s] %s", zDate, zId, zCom); |
| 412 | comment_print(z, 7, width); |
| 413 | fossil_free(z); |
| 414 | } |
| 415 | fossil_free(zLastBr); |
| 416 | db_finalize(&q); |
| 417 | } |
| 418 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -130,10 +130,15 @@ | |
| 130 | db_finalize(&ins); |
| 131 | db_finalize(&isBr); |
| 132 | db_finalize(&q1); |
| 133 | bag_clear(&pending); |
| 134 | bag_clear(&seen); |
| 135 | }else{ |
| 136 | db_multi_exec( |
| 137 | "INSERT INTO leaves" |
| 138 | " SELECT leaf.rid FROM leaf" |
| 139 | ); |
| 140 | } |
| 141 | if( closeMode==1 ){ |
| 142 | db_multi_exec( |
| 143 | "DELETE FROM leaves WHERE rid IN" |
| 144 | " (SELECT leaves.rid FROM leaves, tagxref" |
| @@ -312,10 +317,14 @@ | |
| 317 | fossil_fatal("-W|--width value must be >20 or 0"); |
| 318 | } |
| 319 | }else{ |
| 320 | width = -1; |
| 321 | } |
| 322 | |
| 323 | /* We should be done with options.. */ |
| 324 | verify_all_options(); |
| 325 | |
| 326 | if( g.argc==2 ){ |
| 327 | base = db_lget_int("checkout", 0); |
| 328 | }else{ |
| 329 | base = name_to_typed_rid(g.argv[2], "ci"); |
| 330 | } |
| @@ -373,10 +382,14 @@ | |
| 382 | } |
| 383 | }else{ |
| 384 | width = -1; |
| 385 | } |
| 386 | db_find_and_open_repository(0,0); |
| 387 | |
| 388 | /* We should be done with options.. */ |
| 389 | verify_all_options(); |
| 390 | |
| 391 | if( recomputeFlag ) leaf_rebuild(); |
| 392 | blob_zero(&sql); |
| 393 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 394 | blob_appendf(&sql, " AND blob.rid IN leaf"); |
| 395 | if( showClosed ){ |
| @@ -406,12 +419,12 @@ | |
| 419 | zLastBr = fossil_strdup(zBr); |
| 420 | } |
| 421 | n++; |
| 422 | sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n); |
| 423 | fossil_print("%6s ", zLineNo); |
| 424 | z = mprintf("%s [%S] %s", zDate, zId, zCom); |
| 425 | comment_print(z, zCom, 7, width, g.comFmtFlags); |
| 426 | fossil_free(z); |
| 427 | } |
| 428 | fossil_free(zLastBr); |
| 429 | db_finalize(&q); |
| 430 | } |
| 431 |
+9
-5
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -2312,12 +2312,12 @@ | ||
| 2312 | 2312 | char *zLink = href("%R/finfo?name=%t&ci=%s",zFilename,zCI); |
| 2313 | 2313 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2314 | 2314 | @ <ol> |
| 2315 | 2315 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2316 | 2316 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2317 | - @ check-in %z(href("%R/info/%s",p->zMUuid))%.10s(p->zMUuid)</a> | |
| 2318 | - @ artifact %z(href("%R/artifact/%s",p->zFUuid))%.10s(p->zFUuid)</a> | |
| 2317 | + @ check-in %z(href("%R/info/%s",p->zMUuid))%S(p->zMUuid)</a> | |
| 2318 | + @ artifact %z(href("%R/artifact/%s",p->zFUuid))%S(p->zFUuid)</a> | |
| 2319 | 2319 | @ </span> |
| 2320 | 2320 | #if 0 |
| 2321 | 2321 | if( i>0 ){ |
| 2322 | 2322 | char *zLink = xhref("target='infowindow'", |
| 2323 | 2323 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2434,10 +2434,14 @@ | ||
| 2434 | 2434 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2435 | 2435 | annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 2436 | 2436 | } |
| 2437 | 2437 | fileVers = find_option("filevers",0,0)!=0; |
| 2438 | 2438 | db_must_be_within_tree(); |
| 2439 | + | |
| 2440 | + /* We should be done with options.. */ | |
| 2441 | + verify_all_options(); | |
| 2442 | + | |
| 2439 | 2443 | if( g.argc<3 ) { |
| 2440 | 2444 | usage("FILENAME"); |
| 2441 | 2445 | } |
| 2442 | 2446 | file_tree_name(g.argv[2], &treename, 1); |
| 2443 | 2447 | zFilename = blob_str(&treename); |
| @@ -2465,11 +2469,11 @@ | ||
| 2465 | 2469 | annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2466 | 2470 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2467 | 2471 | if( showLog ){ |
| 2468 | 2472 | struct AnnVers *p; |
| 2469 | 2473 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2470 | - fossil_print("version %3d: %s %.10s file %.10s\n", | |
| 2474 | + fossil_print("version %3d: %s %S file %S\n", | |
| 2471 | 2475 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2472 | 2476 | } |
| 2473 | 2477 | fossil_print("---------------------------------------------------\n"); |
| 2474 | 2478 | } |
| 2475 | 2479 | for(i=0; i<ann.nOrig; i++){ |
| @@ -2479,21 +2483,21 @@ | ||
| 2479 | 2483 | struct AnnVers *p; |
| 2480 | 2484 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2481 | 2485 | p = ann.aVers + iVers; |
| 2482 | 2486 | if( bBlame ){ |
| 2483 | 2487 | if( iVers>=0 ){ |
| 2484 | - fossil_print("%.10s %s %13.13s: %.*s\n", | |
| 2488 | + fossil_print("%S %s %13.13s: %.*s\n", | |
| 2485 | 2489 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); |
| 2486 | 2490 | }else{ |
| 2487 | 2491 | fossil_print("%35s %.*s\n", "", n, z); |
| 2488 | 2492 | } |
| 2489 | 2493 | }else{ |
| 2490 | 2494 | if( iVers>=0 ){ |
| 2491 | - fossil_print("%.10s %s %5d: %.*s\n", | |
| 2495 | + fossil_print("%S %s %5d: %.*s\n", | |
| 2492 | 2496 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); |
| 2493 | 2497 | }else{ |
| 2494 | 2498 | fossil_print("%21s %5d: %.*s\n", |
| 2495 | 2499 | "", i+1, n, z); |
| 2496 | 2500 | } |
| 2497 | 2501 | } |
| 2498 | 2502 | } |
| 2499 | 2503 | } |
| 2500 | 2504 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2312,12 +2312,12 @@ | |
| 2312 | char *zLink = href("%R/finfo?name=%t&ci=%s",zFilename,zCI); |
| 2313 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2314 | @ <ol> |
| 2315 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2316 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2317 | @ check-in %z(href("%R/info/%s",p->zMUuid))%.10s(p->zMUuid)</a> |
| 2318 | @ artifact %z(href("%R/artifact/%s",p->zFUuid))%.10s(p->zFUuid)</a> |
| 2319 | @ </span> |
| 2320 | #if 0 |
| 2321 | if( i>0 ){ |
| 2322 | char *zLink = xhref("target='infowindow'", |
| 2323 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2434,10 +2434,14 @@ | |
| 2434 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2435 | annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 2436 | } |
| 2437 | fileVers = find_option("filevers",0,0)!=0; |
| 2438 | db_must_be_within_tree(); |
| 2439 | if( g.argc<3 ) { |
| 2440 | usage("FILENAME"); |
| 2441 | } |
| 2442 | file_tree_name(g.argv[2], &treename, 1); |
| 2443 | zFilename = blob_str(&treename); |
| @@ -2465,11 +2469,11 @@ | |
| 2465 | annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2466 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2467 | if( showLog ){ |
| 2468 | struct AnnVers *p; |
| 2469 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2470 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2471 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2472 | } |
| 2473 | fossil_print("---------------------------------------------------\n"); |
| 2474 | } |
| 2475 | for(i=0; i<ann.nOrig; i++){ |
| @@ -2479,21 +2483,21 @@ | |
| 2479 | struct AnnVers *p; |
| 2480 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2481 | p = ann.aVers + iVers; |
| 2482 | if( bBlame ){ |
| 2483 | if( iVers>=0 ){ |
| 2484 | fossil_print("%.10s %s %13.13s: %.*s\n", |
| 2485 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); |
| 2486 | }else{ |
| 2487 | fossil_print("%35s %.*s\n", "", n, z); |
| 2488 | } |
| 2489 | }else{ |
| 2490 | if( iVers>=0 ){ |
| 2491 | fossil_print("%.10s %s %5d: %.*s\n", |
| 2492 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); |
| 2493 | }else{ |
| 2494 | fossil_print("%21s %5d: %.*s\n", |
| 2495 | "", i+1, n, z); |
| 2496 | } |
| 2497 | } |
| 2498 | } |
| 2499 | } |
| 2500 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2312,12 +2312,12 @@ | |
| 2312 | char *zLink = href("%R/finfo?name=%t&ci=%s",zFilename,zCI); |
| 2313 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2314 | @ <ol> |
| 2315 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2316 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2317 | @ check-in %z(href("%R/info/%s",p->zMUuid))%S(p->zMUuid)</a> |
| 2318 | @ artifact %z(href("%R/artifact/%s",p->zFUuid))%S(p->zFUuid)</a> |
| 2319 | @ </span> |
| 2320 | #if 0 |
| 2321 | if( i>0 ){ |
| 2322 | char *zLink = xhref("target='infowindow'", |
| 2323 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2434,10 +2434,14 @@ | |
| 2434 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2435 | annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 2436 | } |
| 2437 | fileVers = find_option("filevers",0,0)!=0; |
| 2438 | db_must_be_within_tree(); |
| 2439 | |
| 2440 | /* We should be done with options.. */ |
| 2441 | verify_all_options(); |
| 2442 | |
| 2443 | if( g.argc<3 ) { |
| 2444 | usage("FILENAME"); |
| 2445 | } |
| 2446 | file_tree_name(g.argv[2], &treename, 1); |
| 2447 | zFilename = blob_str(&treename); |
| @@ -2465,11 +2469,11 @@ | |
| 2469 | annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2470 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2471 | if( showLog ){ |
| 2472 | struct AnnVers *p; |
| 2473 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2474 | fossil_print("version %3d: %s %S file %S\n", |
| 2475 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2476 | } |
| 2477 | fossil_print("---------------------------------------------------\n"); |
| 2478 | } |
| 2479 | for(i=0; i<ann.nOrig; i++){ |
| @@ -2479,21 +2483,21 @@ | |
| 2483 | struct AnnVers *p; |
| 2484 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2485 | p = ann.aVers + iVers; |
| 2486 | if( bBlame ){ |
| 2487 | if( iVers>=0 ){ |
| 2488 | fossil_print("%S %s %13.13s: %.*s\n", |
| 2489 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); |
| 2490 | }else{ |
| 2491 | fossil_print("%35s %.*s\n", "", n, z); |
| 2492 | } |
| 2493 | }else{ |
| 2494 | if( iVers>=0 ){ |
| 2495 | fossil_print("%S %s %5d: %.*s\n", |
| 2496 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); |
| 2497 | }else{ |
| 2498 | fossil_print("%21s %5d: %.*s\n", |
| 2499 | "", i+1, n, z); |
| 2500 | } |
| 2501 | } |
| 2502 | } |
| 2503 | } |
| 2504 |
+20
-6
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -63,10 +63,13 @@ | ||
| 63 | 63 | if( find_option("status","s",0) ){ |
| 64 | 64 | Stmt q; |
| 65 | 65 | Blob line; |
| 66 | 66 | Blob fname; |
| 67 | 67 | int vid; |
| 68 | + | |
| 69 | + /* We should be done with options.. */ | |
| 70 | + verify_all_options(); | |
| 68 | 71 | |
| 69 | 72 | if( g.argc!=3 ) usage("-s|--status FILENAME"); |
| 70 | 73 | vid = db_lget_int("checkout", 0); |
| 71 | 74 | if( vid==0 ){ |
| 72 | 75 | fossil_fatal("no checkout to finfo files in"); |
| @@ -115,10 +118,13 @@ | ||
| 115 | 118 | blob_reset(&line); |
| 116 | 119 | }else if( find_option("print","p",0) ){ |
| 117 | 120 | Blob record; |
| 118 | 121 | Blob fname; |
| 119 | 122 | const char *zRevision = find_option("revision", "r", 1); |
| 123 | + | |
| 124 | + /* We should be done with options.. */ | |
| 125 | + verify_all_options(); | |
| 120 | 126 | |
| 121 | 127 | file_tree_name(g.argv[2], &fname, 1); |
| 122 | 128 | if( zRevision ){ |
| 123 | 129 | historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0); |
| 124 | 130 | }else{ |
| @@ -158,10 +164,14 @@ | ||
| 158 | 164 | fossil_fatal("-W|--width value must be >22 or 0"); |
| 159 | 165 | } |
| 160 | 166 | }else{ |
| 161 | 167 | iWidth = -1; |
| 162 | 168 | } |
| 169 | + | |
| 170 | + /* We should be done with options.. */ | |
| 171 | + verify_all_options(); | |
| 172 | + | |
| 163 | 173 | if( g.argc!=3 ){ |
| 164 | 174 | usage("?-l|--log? ?-b|--brief? FILENAME"); |
| 165 | 175 | } |
| 166 | 176 | file_tree_name(g.argv[2], &fname, 1); |
| 167 | 177 | rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s", |
| @@ -199,23 +209,23 @@ | ||
| 199 | 209 | const char *zBr = db_column_text(&q, 5); |
| 200 | 210 | char *zOut; |
| 201 | 211 | if( zBr==0 ) zBr = "trunk"; |
| 202 | 212 | if( iBrief ){ |
| 203 | 213 | fossil_print("%s ", zDate); |
| 204 | - zOut = sqlite3_mprintf( | |
| 205 | - "[%.10s] %s (user: %s, artifact: [%.10s], branch: %s)", | |
| 214 | + zOut = mprintf( | |
| 215 | + "[%S] %s (user: %s, artifact: [%S], branch: %s)", | |
| 206 | 216 | zCiUuid, zCom, zUser, zFileUuid, zBr); |
| 207 | - comment_print(zOut, 11, iWidth); | |
| 208 | - sqlite3_free(zOut); | |
| 217 | + comment_print(zOut, zCom, 11, iWidth, g.comFmtFlags); | |
| 218 | + fossil_free(zOut); | |
| 209 | 219 | }else{ |
| 210 | 220 | blob_reset(&line); |
| 211 | 221 | blob_appendf(&line, "%.10s ", zCiUuid); |
| 212 | 222 | blob_appendf(&line, "%.10s ", zDate); |
| 213 | 223 | blob_appendf(&line, "%8.8s ", zUser); |
| 214 | 224 | blob_appendf(&line, "%8.8s ", zBr); |
| 215 | 225 | blob_appendf(&line,"%-39.39s", zCom ); |
| 216 | - comment_print(blob_str(&line), 0, iWidth); | |
| 226 | + comment_print(blob_str(&line), zCom, 0, iWidth, g.comFmtFlags); | |
| 217 | 227 | } |
| 218 | 228 | } |
| 219 | 229 | db_finalize(&q); |
| 220 | 230 | blob_reset(&fname); |
| 221 | 231 | } |
| @@ -241,10 +251,14 @@ | ||
| 241 | 251 | int rc; |
| 242 | 252 | Blob content, fname; |
| 243 | 253 | const char *zRev; |
| 244 | 254 | db_find_and_open_repository(0, 0); |
| 245 | 255 | zRev = find_option("r","r",1); |
| 256 | + | |
| 257 | + /* We should be done with options.. */ | |
| 258 | + verify_all_options(); | |
| 259 | + | |
| 246 | 260 | for(i=2; i<g.argc; i++){ |
| 247 | 261 | file_tree_name(g.argv[i], &fname, 1); |
| 248 | 262 | blob_zero(&content); |
| 249 | 263 | rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,0); |
| 250 | 264 | if( rc==0 ){ |
| @@ -382,11 +396,11 @@ | ||
| 382 | 396 | if( baseCheckin ){ |
| 383 | 397 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 384 | 398 | char *zLink = href("%R/info/%s", zUuid); |
| 385 | 399 | blob_appendf(&title, "Ancestors of file "); |
| 386 | 400 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 387 | - blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid); | |
| 401 | + blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); | |
| 388 | 402 | fossil_free(zUuid); |
| 389 | 403 | }else{ |
| 390 | 404 | blob_appendf(&title, "History of files named "); |
| 391 | 405 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 392 | 406 | } |
| 393 | 407 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -63,10 +63,13 @@ | |
| 63 | if( find_option("status","s",0) ){ |
| 64 | Stmt q; |
| 65 | Blob line; |
| 66 | Blob fname; |
| 67 | int vid; |
| 68 | |
| 69 | if( g.argc!=3 ) usage("-s|--status FILENAME"); |
| 70 | vid = db_lget_int("checkout", 0); |
| 71 | if( vid==0 ){ |
| 72 | fossil_fatal("no checkout to finfo files in"); |
| @@ -115,10 +118,13 @@ | |
| 115 | blob_reset(&line); |
| 116 | }else if( find_option("print","p",0) ){ |
| 117 | Blob record; |
| 118 | Blob fname; |
| 119 | const char *zRevision = find_option("revision", "r", 1); |
| 120 | |
| 121 | file_tree_name(g.argv[2], &fname, 1); |
| 122 | if( zRevision ){ |
| 123 | historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0); |
| 124 | }else{ |
| @@ -158,10 +164,14 @@ | |
| 158 | fossil_fatal("-W|--width value must be >22 or 0"); |
| 159 | } |
| 160 | }else{ |
| 161 | iWidth = -1; |
| 162 | } |
| 163 | if( g.argc!=3 ){ |
| 164 | usage("?-l|--log? ?-b|--brief? FILENAME"); |
| 165 | } |
| 166 | file_tree_name(g.argv[2], &fname, 1); |
| 167 | rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s", |
| @@ -199,23 +209,23 @@ | |
| 199 | const char *zBr = db_column_text(&q, 5); |
| 200 | char *zOut; |
| 201 | if( zBr==0 ) zBr = "trunk"; |
| 202 | if( iBrief ){ |
| 203 | fossil_print("%s ", zDate); |
| 204 | zOut = sqlite3_mprintf( |
| 205 | "[%.10s] %s (user: %s, artifact: [%.10s], branch: %s)", |
| 206 | zCiUuid, zCom, zUser, zFileUuid, zBr); |
| 207 | comment_print(zOut, 11, iWidth); |
| 208 | sqlite3_free(zOut); |
| 209 | }else{ |
| 210 | blob_reset(&line); |
| 211 | blob_appendf(&line, "%.10s ", zCiUuid); |
| 212 | blob_appendf(&line, "%.10s ", zDate); |
| 213 | blob_appendf(&line, "%8.8s ", zUser); |
| 214 | blob_appendf(&line, "%8.8s ", zBr); |
| 215 | blob_appendf(&line,"%-39.39s", zCom ); |
| 216 | comment_print(blob_str(&line), 0, iWidth); |
| 217 | } |
| 218 | } |
| 219 | db_finalize(&q); |
| 220 | blob_reset(&fname); |
| 221 | } |
| @@ -241,10 +251,14 @@ | |
| 241 | int rc; |
| 242 | Blob content, fname; |
| 243 | const char *zRev; |
| 244 | db_find_and_open_repository(0, 0); |
| 245 | zRev = find_option("r","r",1); |
| 246 | for(i=2; i<g.argc; i++){ |
| 247 | file_tree_name(g.argv[i], &fname, 1); |
| 248 | blob_zero(&content); |
| 249 | rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,0); |
| 250 | if( rc==0 ){ |
| @@ -382,11 +396,11 @@ | |
| 382 | if( baseCheckin ){ |
| 383 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 384 | char *zLink = href("%R/info/%s", zUuid); |
| 385 | blob_appendf(&title, "Ancestors of file "); |
| 386 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 387 | blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid); |
| 388 | fossil_free(zUuid); |
| 389 | }else{ |
| 390 | blob_appendf(&title, "History of files named "); |
| 391 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 392 | } |
| 393 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -63,10 +63,13 @@ | |
| 63 | if( find_option("status","s",0) ){ |
| 64 | Stmt q; |
| 65 | Blob line; |
| 66 | Blob fname; |
| 67 | int vid; |
| 68 | |
| 69 | /* We should be done with options.. */ |
| 70 | verify_all_options(); |
| 71 | |
| 72 | if( g.argc!=3 ) usage("-s|--status FILENAME"); |
| 73 | vid = db_lget_int("checkout", 0); |
| 74 | if( vid==0 ){ |
| 75 | fossil_fatal("no checkout to finfo files in"); |
| @@ -115,10 +118,13 @@ | |
| 118 | blob_reset(&line); |
| 119 | }else if( find_option("print","p",0) ){ |
| 120 | Blob record; |
| 121 | Blob fname; |
| 122 | const char *zRevision = find_option("revision", "r", 1); |
| 123 | |
| 124 | /* We should be done with options.. */ |
| 125 | verify_all_options(); |
| 126 | |
| 127 | file_tree_name(g.argv[2], &fname, 1); |
| 128 | if( zRevision ){ |
| 129 | historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0); |
| 130 | }else{ |
| @@ -158,10 +164,14 @@ | |
| 164 | fossil_fatal("-W|--width value must be >22 or 0"); |
| 165 | } |
| 166 | }else{ |
| 167 | iWidth = -1; |
| 168 | } |
| 169 | |
| 170 | /* We should be done with options.. */ |
| 171 | verify_all_options(); |
| 172 | |
| 173 | if( g.argc!=3 ){ |
| 174 | usage("?-l|--log? ?-b|--brief? FILENAME"); |
| 175 | } |
| 176 | file_tree_name(g.argv[2], &fname, 1); |
| 177 | rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s", |
| @@ -199,23 +209,23 @@ | |
| 209 | const char *zBr = db_column_text(&q, 5); |
| 210 | char *zOut; |
| 211 | if( zBr==0 ) zBr = "trunk"; |
| 212 | if( iBrief ){ |
| 213 | fossil_print("%s ", zDate); |
| 214 | zOut = mprintf( |
| 215 | "[%S] %s (user: %s, artifact: [%S], branch: %s)", |
| 216 | zCiUuid, zCom, zUser, zFileUuid, zBr); |
| 217 | comment_print(zOut, zCom, 11, iWidth, g.comFmtFlags); |
| 218 | fossil_free(zOut); |
| 219 | }else{ |
| 220 | blob_reset(&line); |
| 221 | blob_appendf(&line, "%.10s ", zCiUuid); |
| 222 | blob_appendf(&line, "%.10s ", zDate); |
| 223 | blob_appendf(&line, "%8.8s ", zUser); |
| 224 | blob_appendf(&line, "%8.8s ", zBr); |
| 225 | blob_appendf(&line,"%-39.39s", zCom ); |
| 226 | comment_print(blob_str(&line), zCom, 0, iWidth, g.comFmtFlags); |
| 227 | } |
| 228 | } |
| 229 | db_finalize(&q); |
| 230 | blob_reset(&fname); |
| 231 | } |
| @@ -241,10 +251,14 @@ | |
| 251 | int rc; |
| 252 | Blob content, fname; |
| 253 | const char *zRev; |
| 254 | db_find_and_open_repository(0, 0); |
| 255 | zRev = find_option("r","r",1); |
| 256 | |
| 257 | /* We should be done with options.. */ |
| 258 | verify_all_options(); |
| 259 | |
| 260 | for(i=2; i<g.argc; i++){ |
| 261 | file_tree_name(g.argv[i], &fname, 1); |
| 262 | blob_zero(&content); |
| 263 | rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,0); |
| 264 | if( rc==0 ){ |
| @@ -382,11 +396,11 @@ | |
| 396 | if( baseCheckin ){ |
| 397 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 398 | char *zLink = href("%R/info/%s", zUuid); |
| 399 | blob_appendf(&title, "Ancestors of file "); |
| 400 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 401 | blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); |
| 402 | fossil_free(zUuid); |
| 403 | }else{ |
| 404 | blob_appendf(&title, "History of files named "); |
| 405 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 406 | } |
| 407 |
+8
-2
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -132,11 +132,11 @@ | ||
| 132 | 132 | fossil_print("tags: %s\n", zTags); |
| 133 | 133 | } |
| 134 | 134 | free(zTags); |
| 135 | 135 | if( zComment ){ |
| 136 | 136 | fossil_print("comment: "); |
| 137 | - comment_print(zComment, 14, -1); | |
| 137 | + comment_print(zComment, 0, 14, -1, g.comFmtFlags); | |
| 138 | 138 | free(zComment); |
| 139 | 139 | } |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | /* |
| @@ -197,10 +197,14 @@ | ||
| 197 | 197 | i64 fsize; |
| 198 | 198 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 199 | 199 | if( !verboseFlag ){ |
| 200 | 200 | verboseFlag = find_option("detail","l",0)!=0; /* deprecated */ |
| 201 | 201 | } |
| 202 | + | |
| 203 | + /* We should be done with options.. */ | |
| 204 | + verify_all_options(); | |
| 205 | + | |
| 202 | 206 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 203 | 207 | db_open_config(0); |
| 204 | 208 | db_record_repository_filename(g.argv[2]); |
| 205 | 209 | db_open_repository(g.argv[2]); |
| 206 | 210 | fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| @@ -531,11 +535,11 @@ | ||
| 531 | 535 | timeline_utc(), timeline_utc(), rid, rid |
| 532 | 536 | ); |
| 533 | 537 | sideBySide = !is_false(PD("sbs","1")); |
| 534 | 538 | if( db_step(&q1)==SQLITE_ROW ){ |
| 535 | 539 | const char *zUuid = db_column_text(&q1, 0); |
| 536 | - char *zTitle = mprintf("Check-in [%.10s]", zUuid); | |
| 540 | + char *zTitle = mprintf("Check-in [%S]", zUuid); | |
| 537 | 541 | char *zEUser, *zEComment; |
| 538 | 542 | const char *zUser; |
| 539 | 543 | const char *zComment; |
| 540 | 544 | const char *zDate; |
| 541 | 545 | const char *zOrigDate; |
| @@ -987,10 +991,12 @@ | ||
| 987 | 991 | if(zGlob && !*zGlob){ |
| 988 | 992 | zGlob = NULL; |
| 989 | 993 | } |
| 990 | 994 | diffFlags = construct_diff_flags(verboseFlag, sideBySide); |
| 991 | 995 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 996 | + style_submenu_element("Path","path", | |
| 997 | + "%R/timeline?me=%T&you=%T", zFrom, zTo); | |
| 992 | 998 | if( sideBySide || verboseFlag ){ |
| 993 | 999 | style_submenu_element("Hide Diff", "hidediff", |
| 994 | 1000 | "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s", |
| 995 | 1001 | zFrom, zTo, |
| 996 | 1002 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 997 | 1003 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -132,11 +132,11 @@ | |
| 132 | fossil_print("tags: %s\n", zTags); |
| 133 | } |
| 134 | free(zTags); |
| 135 | if( zComment ){ |
| 136 | fossil_print("comment: "); |
| 137 | comment_print(zComment, 14, -1); |
| 138 | free(zComment); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | /* |
| @@ -197,10 +197,14 @@ | |
| 197 | i64 fsize; |
| 198 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 199 | if( !verboseFlag ){ |
| 200 | verboseFlag = find_option("detail","l",0)!=0; /* deprecated */ |
| 201 | } |
| 202 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 203 | db_open_config(0); |
| 204 | db_record_repository_filename(g.argv[2]); |
| 205 | db_open_repository(g.argv[2]); |
| 206 | fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| @@ -531,11 +535,11 @@ | |
| 531 | timeline_utc(), timeline_utc(), rid, rid |
| 532 | ); |
| 533 | sideBySide = !is_false(PD("sbs","1")); |
| 534 | if( db_step(&q1)==SQLITE_ROW ){ |
| 535 | const char *zUuid = db_column_text(&q1, 0); |
| 536 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 537 | char *zEUser, *zEComment; |
| 538 | const char *zUser; |
| 539 | const char *zComment; |
| 540 | const char *zDate; |
| 541 | const char *zOrigDate; |
| @@ -987,10 +991,12 @@ | |
| 987 | if(zGlob && !*zGlob){ |
| 988 | zGlob = NULL; |
| 989 | } |
| 990 | diffFlags = construct_diff_flags(verboseFlag, sideBySide); |
| 991 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 992 | if( sideBySide || verboseFlag ){ |
| 993 | style_submenu_element("Hide Diff", "hidediff", |
| 994 | "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s", |
| 995 | zFrom, zTo, |
| 996 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 997 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -132,11 +132,11 @@ | |
| 132 | fossil_print("tags: %s\n", zTags); |
| 133 | } |
| 134 | free(zTags); |
| 135 | if( zComment ){ |
| 136 | fossil_print("comment: "); |
| 137 | comment_print(zComment, 0, 14, -1, g.comFmtFlags); |
| 138 | free(zComment); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | /* |
| @@ -197,10 +197,14 @@ | |
| 197 | i64 fsize; |
| 198 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 199 | if( !verboseFlag ){ |
| 200 | verboseFlag = find_option("detail","l",0)!=0; /* deprecated */ |
| 201 | } |
| 202 | |
| 203 | /* We should be done with options.. */ |
| 204 | verify_all_options(); |
| 205 | |
| 206 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 207 | db_open_config(0); |
| 208 | db_record_repository_filename(g.argv[2]); |
| 209 | db_open_repository(g.argv[2]); |
| 210 | fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| @@ -531,11 +535,11 @@ | |
| 535 | timeline_utc(), timeline_utc(), rid, rid |
| 536 | ); |
| 537 | sideBySide = !is_false(PD("sbs","1")); |
| 538 | if( db_step(&q1)==SQLITE_ROW ){ |
| 539 | const char *zUuid = db_column_text(&q1, 0); |
| 540 | char *zTitle = mprintf("Check-in [%S]", zUuid); |
| 541 | char *zEUser, *zEComment; |
| 542 | const char *zUser; |
| 543 | const char *zComment; |
| 544 | const char *zDate; |
| 545 | const char *zOrigDate; |
| @@ -987,10 +991,12 @@ | |
| 991 | if(zGlob && !*zGlob){ |
| 992 | zGlob = NULL; |
| 993 | } |
| 994 | diffFlags = construct_diff_flags(verboseFlag, sideBySide); |
| 995 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 996 | style_submenu_element("Path","path", |
| 997 | "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| 998 | if( sideBySide || verboseFlag ){ |
| 999 | style_submenu_element("Hide Diff", "hidediff", |
| 1000 | "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s", |
| 1001 | zFrom, zTo, |
| 1002 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 1003 |
+40
-7
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -176,10 +176,11 @@ | ||
| 176 | 176 | ** SSL client identity */ |
| 177 | 177 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 178 | 178 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 179 | 179 | int userUid; /* Integer user id */ |
| 180 | 180 | int isHuman; /* True if access by a human, not a spider or bot */ |
| 181 | + int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags */ | |
| 181 | 182 | |
| 182 | 183 | /* Information used to populate the RCVFROM table */ |
| 183 | 184 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 184 | 185 | char *zIpAddr; /* The remote IP address */ |
| 185 | 186 | char *zNonce; /* The nonce used for login */ |
| @@ -298,15 +299,16 @@ | ||
| 298 | 299 | */ |
| 299 | 300 | static int name_search( |
| 300 | 301 | const char *zName, /* The name we are looking for */ |
| 301 | 302 | const NameMap *aMap, /* Search in this array */ |
| 302 | 303 | int nMap, /* Number of slots in aMap[] */ |
| 304 | + int iBegin, /* Lower bound on the array search */ | |
| 303 | 305 | int *pIndex /* OUT: The index in aMap[] of the match */ |
| 304 | 306 | ){ |
| 305 | 307 | int upr, lwr, cnt, m, i; |
| 306 | 308 | int n = strlen(zName); |
| 307 | - lwr = 0; | |
| 309 | + lwr = iBegin; | |
| 308 | 310 | upr = nMap-1; |
| 309 | 311 | while( lwr<=upr ){ |
| 310 | 312 | int mid, c; |
| 311 | 313 | mid = (upr+lwr)/2; |
| 312 | 314 | c = fossil_strcmp(zName, aMap[mid].zName); |
| @@ -318,11 +320,11 @@ | ||
| 318 | 320 | }else{ |
| 319 | 321 | lwr = mid + 1; |
| 320 | 322 | } |
| 321 | 323 | } |
| 322 | 324 | for(m=cnt=0, i=upr-2; cnt<2 && i<=upr+3 && i<nMap; i++){ |
| 323 | - if( i<0 ) continue; | |
| 325 | + if( i<iBegin ) continue; | |
| 324 | 326 | if( strncmp(zName, aMap[i].zName, n)==0 ){ |
| 325 | 327 | m = i; |
| 326 | 328 | cnt++; |
| 327 | 329 | } |
| 328 | 330 | } |
| @@ -533,10 +535,25 @@ | ||
| 533 | 535 | if( iCode==SQLITE_WARNING ) return; |
| 534 | 536 | #endif |
| 535 | 537 | if( iCode==SQLITE_SCHEMA ) return; |
| 536 | 538 | fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg); |
| 537 | 539 | } |
| 540 | + | |
| 541 | +/* | |
| 542 | +** This function attempts to find command line options known to contain | |
| 543 | +** bitwise flags and initializes the associated global variables. After | |
| 544 | +** this function executes, all global variables (i.e. in the "g" struct) | |
| 545 | +** containing option-settable bitwise flag fields must be initialized. | |
| 546 | +*/ | |
| 547 | +static void fossil_init_flags_from_options(void){ | |
| 548 | + const char *zValue = find_option("comfmtflags", 0, 1); | |
| 549 | + if( zValue ){ | |
| 550 | + g.comFmtFlags = atoi(zValue); | |
| 551 | + }else{ | |
| 552 | + g.comFmtFlags = COMMENT_PRINT_DEFAULT; | |
| 553 | + } | |
| 554 | +} | |
| 538 | 555 | |
| 539 | 556 | /* |
| 540 | 557 | ** This procedure runs first. |
| 541 | 558 | */ |
| 542 | 559 | #if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE) |
| @@ -632,10 +649,11 @@ | ||
| 632 | 649 | #endif |
| 633 | 650 | g.zHttpAuth = 0; |
| 634 | 651 | g.zLogin = find_option("user", "U", 1); |
| 635 | 652 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 636 | 653 | g.zErrlog = find_option("errorlog", 0, 1); |
| 654 | + fossil_init_flags_from_options(); | |
| 637 | 655 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 638 | 656 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 639 | 657 | if( zChdir && file_chdir(zChdir, 0) ){ |
| 640 | 658 | fossil_fatal("unable to change directories to %s", zChdir); |
| 641 | 659 | } |
| @@ -655,11 +673,11 @@ | ||
| 655 | 673 | } |
| 656 | 674 | #ifndef _WIN32 |
| 657 | 675 | if( !is_valid_fd(2) ) fossil_panic("file descriptor 2 not open"); |
| 658 | 676 | /* if( is_valid_fd(3) ) fossil_warning("file descriptor 3 is open"); */ |
| 659 | 677 | #endif |
| 660 | - rc = name_search(zCmdName, aCommand, count(aCommand), &idx); | |
| 678 | + rc = name_search(zCmdName, aCommand, count(aCommand), FOSSIL_FIRST_CMD, &idx); | |
| 661 | 679 | if( rc==1 ){ |
| 662 | 680 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 663 | 681 | if( !g.isHTTP && !g.fNoThHook ){ |
| 664 | 682 | rc = Th_CommandHook(zCmdName, 0); |
| 665 | 683 | }else{ |
| @@ -918,12 +936,19 @@ | ||
| 918 | 936 | ** If the verbose option is specified, additional details will |
| 919 | 937 | ** be output about what optional features this binary was compiled |
| 920 | 938 | ** with |
| 921 | 939 | */ |
| 922 | 940 | void version_cmd(void){ |
| 941 | + int verboseFlag = 0; | |
| 942 | + | |
| 923 | 943 | fossil_print("This is fossil version %s\n", get_version()); |
| 924 | - if(!find_option("verbose","v",0)){ | |
| 944 | + verboseFlag = find_option("verbose","v",0)!=0; | |
| 945 | + | |
| 946 | + /* We should be done with options.. */ | |
| 947 | + verify_all_options(); | |
| 948 | + | |
| 949 | + if(!verboseFlag){ | |
| 925 | 950 | return; |
| 926 | 951 | }else{ |
| 927 | 952 | #if defined(FOSSIL_ENABLE_TCL) |
| 928 | 953 | int rc; |
| 929 | 954 | const char *zRc; |
| @@ -1015,11 +1040,11 @@ | ||
| 1015 | 1040 | zCmdOrPagePlural = "pages"; |
| 1016 | 1041 | }else{ |
| 1017 | 1042 | zCmdOrPage = "command"; |
| 1018 | 1043 | zCmdOrPagePlural = "commands"; |
| 1019 | 1044 | } |
| 1020 | - rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); | |
| 1045 | + rc = name_search(g.argv[2], aCommand, count(aCommand), 0, &idx); | |
| 1021 | 1046 | if( rc==1 ){ |
| 1022 | 1047 | fossil_print("unknown %s: %s\nAvailable %s:\n", |
| 1023 | 1048 | zCmdOrPage, g.argv[2], zCmdOrPagePlural); |
| 1024 | 1049 | command_list(0, isPage ? CMDFLAG_WEBPAGE : (0xff & ~CMDFLAG_WEBPAGE)); |
| 1025 | 1050 | fossil_exit(1); |
| @@ -1059,11 +1084,11 @@ | ||
| 1059 | 1084 | int rc, idx; |
| 1060 | 1085 | char *z, *s, *d; |
| 1061 | 1086 | char const * zCmdOrPage = ('/'==*zCmd) ? "page" : "command"; |
| 1062 | 1087 | style_submenu_element("Command-List", "Command-List", "%s/help", g.zTop); |
| 1063 | 1088 | @ <h1>The "%s(zCmd)" %s(zCmdOrPage):</h1> |
| 1064 | - rc = name_search(zCmd, aCommand, count(aCommand), &idx); | |
| 1089 | + rc = name_search(zCmd, aCommand, count(aCommand), 0, &idx); | |
| 1065 | 1090 | if( rc==1 ){ |
| 1066 | 1091 | @ unknown command: %s(zCmd) |
| 1067 | 1092 | }else if( rc==2 ){ |
| 1068 | 1093 | @ ambiguous command prefix: %s(zCmd) |
| 1069 | 1094 | }else{ |
| @@ -1561,11 +1586,11 @@ | ||
| 1561 | 1586 | } |
| 1562 | 1587 | |
| 1563 | 1588 | /* Locate the method specified by the path and execute the function |
| 1564 | 1589 | ** that implements that method. |
| 1565 | 1590 | */ |
| 1566 | - if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) ){ | |
| 1591 | + if( name_search(g.zPath, aWebpage, count(aWebpage), 0, &idx) ){ | |
| 1567 | 1592 | #ifdef FOSSIL_ENABLE_JSON |
| 1568 | 1593 | if(g.json.isJsonMode){ |
| 1569 | 1594 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); |
| 1570 | 1595 | }else |
| 1571 | 1596 | #endif |
| @@ -1910,10 +1935,14 @@ | ||
| 1910 | 1935 | if( zAltBase ) set_base_url(zAltBase); |
| 1911 | 1936 | if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on"); |
| 1912 | 1937 | zHost = find_option("host", 0, 1); |
| 1913 | 1938 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); |
| 1914 | 1939 | g.cgiOutput = 1; |
| 1940 | + | |
| 1941 | + /* We should be done with options.. */ | |
| 1942 | + verify_all_options(); | |
| 1943 | + | |
| 1915 | 1944 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1916 | 1945 | fossil_fatal("no repository specified"); |
| 1917 | 1946 | } |
| 1918 | 1947 | g.fullHttpReply = 1; |
| 1919 | 1948 | if( g.argc==6 ){ |
| @@ -2089,10 +2118,14 @@ | ||
| 2089 | 2118 | set_base_url(zAltBase); |
| 2090 | 2119 | } |
| 2091 | 2120 | if ( find_option("localhost", 0, 0)!=0 ){ |
| 2092 | 2121 | flags |= HTTP_SERVER_LOCALHOST; |
| 2093 | 2122 | } |
| 2123 | + | |
| 2124 | + /* We should be done with options.. */ | |
| 2125 | + verify_all_options(); | |
| 2126 | + | |
| 2094 | 2127 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 2095 | 2128 | isUiCmd = g.argv[1][0]=='u'; |
| 2096 | 2129 | if( isUiCmd ){ |
| 2097 | 2130 | flags |= HTTP_SERVER_LOCALHOST; |
| 2098 | 2131 | g.useLocalauth = 1; |
| 2099 | 2132 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -176,10 +176,11 @@ | |
| 176 | ** SSL client identity */ |
| 177 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 178 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 179 | int userUid; /* Integer user id */ |
| 180 | int isHuman; /* True if access by a human, not a spider or bot */ |
| 181 | |
| 182 | /* Information used to populate the RCVFROM table */ |
| 183 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 184 | char *zIpAddr; /* The remote IP address */ |
| 185 | char *zNonce; /* The nonce used for login */ |
| @@ -298,15 +299,16 @@ | |
| 298 | */ |
| 299 | static int name_search( |
| 300 | const char *zName, /* The name we are looking for */ |
| 301 | const NameMap *aMap, /* Search in this array */ |
| 302 | int nMap, /* Number of slots in aMap[] */ |
| 303 | int *pIndex /* OUT: The index in aMap[] of the match */ |
| 304 | ){ |
| 305 | int upr, lwr, cnt, m, i; |
| 306 | int n = strlen(zName); |
| 307 | lwr = 0; |
| 308 | upr = nMap-1; |
| 309 | while( lwr<=upr ){ |
| 310 | int mid, c; |
| 311 | mid = (upr+lwr)/2; |
| 312 | c = fossil_strcmp(zName, aMap[mid].zName); |
| @@ -318,11 +320,11 @@ | |
| 318 | }else{ |
| 319 | lwr = mid + 1; |
| 320 | } |
| 321 | } |
| 322 | for(m=cnt=0, i=upr-2; cnt<2 && i<=upr+3 && i<nMap; i++){ |
| 323 | if( i<0 ) continue; |
| 324 | if( strncmp(zName, aMap[i].zName, n)==0 ){ |
| 325 | m = i; |
| 326 | cnt++; |
| 327 | } |
| 328 | } |
| @@ -533,10 +535,25 @@ | |
| 533 | if( iCode==SQLITE_WARNING ) return; |
| 534 | #endif |
| 535 | if( iCode==SQLITE_SCHEMA ) return; |
| 536 | fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg); |
| 537 | } |
| 538 | |
| 539 | /* |
| 540 | ** This procedure runs first. |
| 541 | */ |
| 542 | #if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE) |
| @@ -632,10 +649,11 @@ | |
| 632 | #endif |
| 633 | g.zHttpAuth = 0; |
| 634 | g.zLogin = find_option("user", "U", 1); |
| 635 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 636 | g.zErrlog = find_option("errorlog", 0, 1); |
| 637 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 638 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 639 | if( zChdir && file_chdir(zChdir, 0) ){ |
| 640 | fossil_fatal("unable to change directories to %s", zChdir); |
| 641 | } |
| @@ -655,11 +673,11 @@ | |
| 655 | } |
| 656 | #ifndef _WIN32 |
| 657 | if( !is_valid_fd(2) ) fossil_panic("file descriptor 2 not open"); |
| 658 | /* if( is_valid_fd(3) ) fossil_warning("file descriptor 3 is open"); */ |
| 659 | #endif |
| 660 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 661 | if( rc==1 ){ |
| 662 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 663 | if( !g.isHTTP && !g.fNoThHook ){ |
| 664 | rc = Th_CommandHook(zCmdName, 0); |
| 665 | }else{ |
| @@ -918,12 +936,19 @@ | |
| 918 | ** If the verbose option is specified, additional details will |
| 919 | ** be output about what optional features this binary was compiled |
| 920 | ** with |
| 921 | */ |
| 922 | void version_cmd(void){ |
| 923 | fossil_print("This is fossil version %s\n", get_version()); |
| 924 | if(!find_option("verbose","v",0)){ |
| 925 | return; |
| 926 | }else{ |
| 927 | #if defined(FOSSIL_ENABLE_TCL) |
| 928 | int rc; |
| 929 | const char *zRc; |
| @@ -1015,11 +1040,11 @@ | |
| 1015 | zCmdOrPagePlural = "pages"; |
| 1016 | }else{ |
| 1017 | zCmdOrPage = "command"; |
| 1018 | zCmdOrPagePlural = "commands"; |
| 1019 | } |
| 1020 | rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); |
| 1021 | if( rc==1 ){ |
| 1022 | fossil_print("unknown %s: %s\nAvailable %s:\n", |
| 1023 | zCmdOrPage, g.argv[2], zCmdOrPagePlural); |
| 1024 | command_list(0, isPage ? CMDFLAG_WEBPAGE : (0xff & ~CMDFLAG_WEBPAGE)); |
| 1025 | fossil_exit(1); |
| @@ -1059,11 +1084,11 @@ | |
| 1059 | int rc, idx; |
| 1060 | char *z, *s, *d; |
| 1061 | char const * zCmdOrPage = ('/'==*zCmd) ? "page" : "command"; |
| 1062 | style_submenu_element("Command-List", "Command-List", "%s/help", g.zTop); |
| 1063 | @ <h1>The "%s(zCmd)" %s(zCmdOrPage):</h1> |
| 1064 | rc = name_search(zCmd, aCommand, count(aCommand), &idx); |
| 1065 | if( rc==1 ){ |
| 1066 | @ unknown command: %s(zCmd) |
| 1067 | }else if( rc==2 ){ |
| 1068 | @ ambiguous command prefix: %s(zCmd) |
| 1069 | }else{ |
| @@ -1561,11 +1586,11 @@ | |
| 1561 | } |
| 1562 | |
| 1563 | /* Locate the method specified by the path and execute the function |
| 1564 | ** that implements that method. |
| 1565 | */ |
| 1566 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) ){ |
| 1567 | #ifdef FOSSIL_ENABLE_JSON |
| 1568 | if(g.json.isJsonMode){ |
| 1569 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); |
| 1570 | }else |
| 1571 | #endif |
| @@ -1910,10 +1935,14 @@ | |
| 1910 | if( zAltBase ) set_base_url(zAltBase); |
| 1911 | if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on"); |
| 1912 | zHost = find_option("host", 0, 1); |
| 1913 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); |
| 1914 | g.cgiOutput = 1; |
| 1915 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1916 | fossil_fatal("no repository specified"); |
| 1917 | } |
| 1918 | g.fullHttpReply = 1; |
| 1919 | if( g.argc==6 ){ |
| @@ -2089,10 +2118,14 @@ | |
| 2089 | set_base_url(zAltBase); |
| 2090 | } |
| 2091 | if ( find_option("localhost", 0, 0)!=0 ){ |
| 2092 | flags |= HTTP_SERVER_LOCALHOST; |
| 2093 | } |
| 2094 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 2095 | isUiCmd = g.argv[1][0]=='u'; |
| 2096 | if( isUiCmd ){ |
| 2097 | flags |= HTTP_SERVER_LOCALHOST; |
| 2098 | g.useLocalauth = 1; |
| 2099 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -176,10 +176,11 @@ | |
| 176 | ** SSL client identity */ |
| 177 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 178 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 179 | int userUid; /* Integer user id */ |
| 180 | int isHuman; /* True if access by a human, not a spider or bot */ |
| 181 | int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags */ |
| 182 | |
| 183 | /* Information used to populate the RCVFROM table */ |
| 184 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 185 | char *zIpAddr; /* The remote IP address */ |
| 186 | char *zNonce; /* The nonce used for login */ |
| @@ -298,15 +299,16 @@ | |
| 299 | */ |
| 300 | static int name_search( |
| 301 | const char *zName, /* The name we are looking for */ |
| 302 | const NameMap *aMap, /* Search in this array */ |
| 303 | int nMap, /* Number of slots in aMap[] */ |
| 304 | int iBegin, /* Lower bound on the array search */ |
| 305 | int *pIndex /* OUT: The index in aMap[] of the match */ |
| 306 | ){ |
| 307 | int upr, lwr, cnt, m, i; |
| 308 | int n = strlen(zName); |
| 309 | lwr = iBegin; |
| 310 | upr = nMap-1; |
| 311 | while( lwr<=upr ){ |
| 312 | int mid, c; |
| 313 | mid = (upr+lwr)/2; |
| 314 | c = fossil_strcmp(zName, aMap[mid].zName); |
| @@ -318,11 +320,11 @@ | |
| 320 | }else{ |
| 321 | lwr = mid + 1; |
| 322 | } |
| 323 | } |
| 324 | for(m=cnt=0, i=upr-2; cnt<2 && i<=upr+3 && i<nMap; i++){ |
| 325 | if( i<iBegin ) continue; |
| 326 | if( strncmp(zName, aMap[i].zName, n)==0 ){ |
| 327 | m = i; |
| 328 | cnt++; |
| 329 | } |
| 330 | } |
| @@ -533,10 +535,25 @@ | |
| 535 | if( iCode==SQLITE_WARNING ) return; |
| 536 | #endif |
| 537 | if( iCode==SQLITE_SCHEMA ) return; |
| 538 | fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | ** This function attempts to find command line options known to contain |
| 543 | ** bitwise flags and initializes the associated global variables. After |
| 544 | ** this function executes, all global variables (i.e. in the "g" struct) |
| 545 | ** containing option-settable bitwise flag fields must be initialized. |
| 546 | */ |
| 547 | static void fossil_init_flags_from_options(void){ |
| 548 | const char *zValue = find_option("comfmtflags", 0, 1); |
| 549 | if( zValue ){ |
| 550 | g.comFmtFlags = atoi(zValue); |
| 551 | }else{ |
| 552 | g.comFmtFlags = COMMENT_PRINT_DEFAULT; |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | /* |
| 557 | ** This procedure runs first. |
| 558 | */ |
| 559 | #if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE) |
| @@ -632,10 +649,11 @@ | |
| 649 | #endif |
| 650 | g.zHttpAuth = 0; |
| 651 | g.zLogin = find_option("user", "U", 1); |
| 652 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 653 | g.zErrlog = find_option("errorlog", 0, 1); |
| 654 | fossil_init_flags_from_options(); |
| 655 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 656 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 657 | if( zChdir && file_chdir(zChdir, 0) ){ |
| 658 | fossil_fatal("unable to change directories to %s", zChdir); |
| 659 | } |
| @@ -655,11 +673,11 @@ | |
| 673 | } |
| 674 | #ifndef _WIN32 |
| 675 | if( !is_valid_fd(2) ) fossil_panic("file descriptor 2 not open"); |
| 676 | /* if( is_valid_fd(3) ) fossil_warning("file descriptor 3 is open"); */ |
| 677 | #endif |
| 678 | rc = name_search(zCmdName, aCommand, count(aCommand), FOSSIL_FIRST_CMD, &idx); |
| 679 | if( rc==1 ){ |
| 680 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 681 | if( !g.isHTTP && !g.fNoThHook ){ |
| 682 | rc = Th_CommandHook(zCmdName, 0); |
| 683 | }else{ |
| @@ -918,12 +936,19 @@ | |
| 936 | ** If the verbose option is specified, additional details will |
| 937 | ** be output about what optional features this binary was compiled |
| 938 | ** with |
| 939 | */ |
| 940 | void version_cmd(void){ |
| 941 | int verboseFlag = 0; |
| 942 | |
| 943 | fossil_print("This is fossil version %s\n", get_version()); |
| 944 | verboseFlag = find_option("verbose","v",0)!=0; |
| 945 | |
| 946 | /* We should be done with options.. */ |
| 947 | verify_all_options(); |
| 948 | |
| 949 | if(!verboseFlag){ |
| 950 | return; |
| 951 | }else{ |
| 952 | #if defined(FOSSIL_ENABLE_TCL) |
| 953 | int rc; |
| 954 | const char *zRc; |
| @@ -1015,11 +1040,11 @@ | |
| 1040 | zCmdOrPagePlural = "pages"; |
| 1041 | }else{ |
| 1042 | zCmdOrPage = "command"; |
| 1043 | zCmdOrPagePlural = "commands"; |
| 1044 | } |
| 1045 | rc = name_search(g.argv[2], aCommand, count(aCommand), 0, &idx); |
| 1046 | if( rc==1 ){ |
| 1047 | fossil_print("unknown %s: %s\nAvailable %s:\n", |
| 1048 | zCmdOrPage, g.argv[2], zCmdOrPagePlural); |
| 1049 | command_list(0, isPage ? CMDFLAG_WEBPAGE : (0xff & ~CMDFLAG_WEBPAGE)); |
| 1050 | fossil_exit(1); |
| @@ -1059,11 +1084,11 @@ | |
| 1084 | int rc, idx; |
| 1085 | char *z, *s, *d; |
| 1086 | char const * zCmdOrPage = ('/'==*zCmd) ? "page" : "command"; |
| 1087 | style_submenu_element("Command-List", "Command-List", "%s/help", g.zTop); |
| 1088 | @ <h1>The "%s(zCmd)" %s(zCmdOrPage):</h1> |
| 1089 | rc = name_search(zCmd, aCommand, count(aCommand), 0, &idx); |
| 1090 | if( rc==1 ){ |
| 1091 | @ unknown command: %s(zCmd) |
| 1092 | }else if( rc==2 ){ |
| 1093 | @ ambiguous command prefix: %s(zCmd) |
| 1094 | }else{ |
| @@ -1561,11 +1586,11 @@ | |
| 1586 | } |
| 1587 | |
| 1588 | /* Locate the method specified by the path and execute the function |
| 1589 | ** that implements that method. |
| 1590 | */ |
| 1591 | if( name_search(g.zPath, aWebpage, count(aWebpage), 0, &idx) ){ |
| 1592 | #ifdef FOSSIL_ENABLE_JSON |
| 1593 | if(g.json.isJsonMode){ |
| 1594 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); |
| 1595 | }else |
| 1596 | #endif |
| @@ -1910,10 +1935,14 @@ | |
| 1935 | if( zAltBase ) set_base_url(zAltBase); |
| 1936 | if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on"); |
| 1937 | zHost = find_option("host", 0, 1); |
| 1938 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); |
| 1939 | g.cgiOutput = 1; |
| 1940 | |
| 1941 | /* We should be done with options.. */ |
| 1942 | verify_all_options(); |
| 1943 | |
| 1944 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1945 | fossil_fatal("no repository specified"); |
| 1946 | } |
| 1947 | g.fullHttpReply = 1; |
| 1948 | if( g.argc==6 ){ |
| @@ -2089,10 +2118,14 @@ | |
| 2118 | set_base_url(zAltBase); |
| 2119 | } |
| 2120 | if ( find_option("localhost", 0, 0)!=0 ){ |
| 2121 | flags |= HTTP_SERVER_LOCALHOST; |
| 2122 | } |
| 2123 | |
| 2124 | /* We should be done with options.. */ |
| 2125 | verify_all_options(); |
| 2126 | |
| 2127 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 2128 | isUiCmd = g.argv[1][0]=='u'; |
| 2129 | if( isUiCmd ){ |
| 2130 | flags |= HTTP_SERVER_LOCALHOST; |
| 2131 | g.useLocalauth = 1; |
| 2132 |
+2
-1
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -385,11 +385,12 @@ | ||
| 385 | 385 | |
| 386 | 386 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 387 | 387 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 388 | 388 | |
| 389 | 389 | # Setup the options used to compile the included SQLite library. |
| 390 | -SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 390 | +SQLITE_OPTIONS = -DNDEBUG=1 \ | |
| 391 | + -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 391 | 392 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 392 | 393 | -DSQLITE_THREADSAFE=0 \ |
| 393 | 394 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 394 | 395 | -DSQLITE_OMIT_DEPRECATED \ |
| 395 | 396 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 396 | 397 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -385,11 +385,12 @@ | |
| 385 | |
| 386 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 387 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 388 | |
| 389 | # Setup the options used to compile the included SQLite library. |
| 390 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 391 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 392 | -DSQLITE_THREADSAFE=0 \ |
| 393 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 394 | -DSQLITE_OMIT_DEPRECATED \ |
| 395 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 396 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -385,11 +385,12 @@ | |
| 385 | |
| 386 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 387 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 388 | |
| 389 | # Setup the options used to compile the included SQLite library. |
| 390 | SQLITE_OPTIONS = -DNDEBUG=1 \ |
| 391 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 392 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 393 | -DSQLITE_THREADSAFE=0 \ |
| 394 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 395 | -DSQLITE_OMIT_DEPRECATED \ |
| 396 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 397 |
+2
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -132,10 +132,11 @@ | ||
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | # Options used to compile the included SQLite library. |
| 135 | 135 | # |
| 136 | 136 | set SQLITE_OPTIONS { |
| 137 | + -DNDEBUG=1 | |
| 137 | 138 | -DSQLITE_OMIT_LOAD_EXTENSION=1 |
| 138 | 139 | -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 139 | 140 | -DSQLITE_THREADSAFE=0 |
| 140 | 141 | -DSQLITE_DEFAULT_FILE_FORMAT=4 |
| 141 | 142 | -DSQLITE_OMIT_DEPRECATED |
| @@ -157,10 +158,11 @@ | ||
| 157 | 158 | |
| 158 | 159 | # Options used to compile the included SQLite shell on Windows. |
| 159 | 160 | # |
| 160 | 161 | set SHELL_WIN32_OPTIONS $SHELL_OPTIONS |
| 161 | 162 | lappend SHELL_WIN32_OPTIONS -Daccess=file_access |
| 163 | +lappend SHELL_WIN32_OPTIONS -Dsystem=fossil_system | |
| 162 | 164 | lappend SHELL_WIN32_OPTIONS -Dgetenv=fossil_getenv |
| 163 | 165 | lappend SHELL_WIN32_OPTIONS -Dfopen=fossil_fopen |
| 164 | 166 | |
| 165 | 167 | # Name of the final application |
| 166 | 168 | # |
| 167 | 169 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -132,10 +132,11 @@ | |
| 132 | } |
| 133 | |
| 134 | # Options used to compile the included SQLite library. |
| 135 | # |
| 136 | set SQLITE_OPTIONS { |
| 137 | -DSQLITE_OMIT_LOAD_EXTENSION=1 |
| 138 | -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 139 | -DSQLITE_THREADSAFE=0 |
| 140 | -DSQLITE_DEFAULT_FILE_FORMAT=4 |
| 141 | -DSQLITE_OMIT_DEPRECATED |
| @@ -157,10 +158,11 @@ | |
| 157 | |
| 158 | # Options used to compile the included SQLite shell on Windows. |
| 159 | # |
| 160 | set SHELL_WIN32_OPTIONS $SHELL_OPTIONS |
| 161 | lappend SHELL_WIN32_OPTIONS -Daccess=file_access |
| 162 | lappend SHELL_WIN32_OPTIONS -Dgetenv=fossil_getenv |
| 163 | lappend SHELL_WIN32_OPTIONS -Dfopen=fossil_fopen |
| 164 | |
| 165 | # Name of the final application |
| 166 | # |
| 167 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -132,10 +132,11 @@ | |
| 132 | } |
| 133 | |
| 134 | # Options used to compile the included SQLite library. |
| 135 | # |
| 136 | set SQLITE_OPTIONS { |
| 137 | -DNDEBUG=1 |
| 138 | -DSQLITE_OMIT_LOAD_EXTENSION=1 |
| 139 | -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 140 | -DSQLITE_THREADSAFE=0 |
| 141 | -DSQLITE_DEFAULT_FILE_FORMAT=4 |
| 142 | -DSQLITE_OMIT_DEPRECATED |
| @@ -157,10 +158,11 @@ | |
| 158 | |
| 159 | # Options used to compile the included SQLite shell on Windows. |
| 160 | # |
| 161 | set SHELL_WIN32_OPTIONS $SHELL_OPTIONS |
| 162 | lappend SHELL_WIN32_OPTIONS -Daccess=file_access |
| 163 | lappend SHELL_WIN32_OPTIONS -Dsystem=fossil_system |
| 164 | lappend SHELL_WIN32_OPTIONS -Dgetenv=fossil_getenv |
| 165 | lappend SHELL_WIN32_OPTIONS -Dfopen=fossil_fopen |
| 166 | |
| 167 | # Name of the final application |
| 168 | # |
| 169 |
+31
-31
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -890,58 +890,58 @@ | ||
| 890 | 890 | SYNTAX("cluster contains a card other than M- or Z-"); |
| 891 | 891 | } |
| 892 | 892 | if( !seenZ ) SYNTAX("missing Z-card on cluster"); |
| 893 | 893 | p->type = CFTYPE_CLUSTER; |
| 894 | 894 | }else if( p->zEventId ){ |
| 895 | + if( p->zAttachName ) SYNTAX("A-card in event"); | |
| 896 | + if( p->zBaseline ) SYNTAX("B-card in event"); | |
| 895 | 897 | if( p->rDate<=0.0 ) SYNTAX("missing date on event"); |
| 896 | 898 | if( p->nFile>0 ) SYNTAX("F-card in event"); |
| 897 | - if( p->zRepoCksum ) SYNTAX("R-card in event"); | |
| 898 | - if( p->zBaseline ) SYNTAX("B-card in event"); | |
| 899 | 899 | if( p->nField>0 ) SYNTAX("J-card in event"); |
| 900 | 900 | if( p->zTicketUuid ) SYNTAX("K-card in event"); |
| 901 | 901 | if( p->zWikiTitle!=0 ) SYNTAX("L-card in event"); |
| 902 | + if( p->zRepoCksum ) SYNTAX("R-card in event"); | |
| 902 | 903 | if( p->zWiki==0 ) SYNTAX("missing W-card on event"); |
| 903 | - if( p->zAttachName ) SYNTAX("A-card in event"); | |
| 904 | 904 | if( !seenZ ) SYNTAX("missing Z-card on event"); |
| 905 | 905 | p->type = CFTYPE_EVENT; |
| 906 | - }else if( hasSelfRefTag || p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline ){ | |
| 906 | + }else if( p->zWiki!=0 || p->zWikiTitle!=0 ){ | |
| 907 | + if( p->zAttachName ) SYNTAX("A-card in wiki"); | |
| 908 | + if( p->zBaseline ) SYNTAX("B-card in wiki"); | |
| 909 | + if( p->rDate<=0.0 ) SYNTAX("missing date on wiki"); | |
| 910 | + if( p->nFile>0 ) SYNTAX("F-card in wiki"); | |
| 911 | + if( p->nField>0 ) SYNTAX("J-card in wiki"); | |
| 912 | + if( p->zTicketUuid ) SYNTAX("K-card in wiki"); | |
| 913 | + if( p->zWikiTitle==0 ) SYNTAX("missing L-card on wiki"); | |
| 914 | + if( p->zRepoCksum ) SYNTAX("R-card in wiki"); | |
| 915 | + if( p->nTag>0 ) SYNTAX("T-card in wiki"); | |
| 916 | + if( p->zWiki==0 ) SYNTAX("missing W-card on wiki"); | |
| 917 | + if( !seenZ ) SYNTAX("missing Z-card on wiki"); | |
| 918 | + p->type = CFTYPE_WIKI; | |
| 919 | + }else if( hasSelfRefTag || p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline | |
| 920 | + || p->nParent>0 ){ | |
| 921 | + if( p->zAttachName ) SYNTAX("A-card in manifest"); | |
| 907 | 922 | if( p->rDate<=0.0 ) SYNTAX("missing date on manifest"); |
| 908 | 923 | if( p->nField>0 ) SYNTAX("J-card in manifest"); |
| 909 | 924 | if( p->zTicketUuid ) SYNTAX("K-card in manifest"); |
| 910 | - if( p->zWiki ) SYNTAX("W-card in manifest"); | |
| 911 | - if( p->zWikiTitle ) SYNTAX("L-card in manifest"); | |
| 912 | - if( p->zTicketUuid ) SYNTAX("K-card in manifest"); | |
| 913 | - if( p->zAttachName ) SYNTAX("A-card in manifest"); | |
| 914 | 925 | p->type = CFTYPE_MANIFEST; |
| 915 | 926 | }else if( p->nField>0 || p->zTicketUuid!=0 ){ |
| 927 | + if( p->zAttachName ) SYNTAX("A-card in ticket"); | |
| 916 | 928 | if( p->rDate<=0.0 ) SYNTAX("missing date on ticket"); |
| 917 | - if( p->zWiki ) SYNTAX("W-card in ticket"); | |
| 918 | - if( p->zWikiTitle ) SYNTAX("L-card in ticket"); | |
| 919 | 929 | if( p->nField==0 ) SYNTAX("missing J-card on ticket"); |
| 930 | + if( p->zTicketUuid==0 ) SYNTAX("missing K-card on ticket"); | |
| 931 | + if( p->zMimetype) SYNTAX("N-card in ticket"); | |
| 920 | 932 | if( p->nTag>0 ) SYNTAX("T-card in ticket"); |
| 921 | - if( p->zTicketUuid==0 ) SYNTAX("missing K-card on ticket"); | |
| 922 | 933 | if( p->zUser==0 ) SYNTAX("missing U-card on ticket"); |
| 923 | - if( p->zAttachName ) SYNTAX("A-card in ticket"); | |
| 924 | - if( p->zMimetype) SYNTAX("N-card in ticket"); | |
| 925 | 934 | if( !seenZ ) SYNTAX("missing Z-card on ticket"); |
| 926 | 935 | p->type = CFTYPE_TICKET; |
| 927 | - }else if( p->zWiki!=0 || p->zWikiTitle!=0 ){ | |
| 928 | - if( p->rDate<=0.0 ) SYNTAX("missing date on wiki"); | |
| 929 | - if( p->nTag>0 ) SYNTAX("T-card in wiki"); | |
| 930 | - if( p->zWiki==0 ) SYNTAX("missing W-card on wiki"); | |
| 931 | - if( p->zWikiTitle==0 ) SYNTAX("missing L-card on wiki"); | |
| 932 | - if( p->zAttachName ) SYNTAX("A-card in wiki"); | |
| 933 | - if( !seenZ ) SYNTAX("missing Z-card on wiki"); | |
| 934 | - p->type = CFTYPE_WIKI; | |
| 935 | 936 | }else if( p->zAttachName ){ |
| 936 | 937 | if( p->rDate<=0.0 ) SYNTAX("missing date on attachment"); |
| 937 | 938 | if( p->nTag>0 ) SYNTAX("T-card in attachment"); |
| 938 | 939 | if( !seenZ ) SYNTAX("missing Z-card on attachment"); |
| 939 | 940 | p->type = CFTYPE_ATTACHMENT; |
| 940 | 941 | }else{ |
| 941 | 942 | if( p->rDate<=0.0 ) SYNTAX("missing date on control"); |
| 942 | - if( p->nParent>0 ) SYNTAX("P-card in control"); | |
| 943 | 943 | if( p->zMimetype ) SYNTAX("N-card in control"); |
| 944 | 944 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 945 | 945 | p->type = CFTYPE_CONTROL; |
| 946 | 946 | } |
| 947 | 947 | md5sum_init(); |
| @@ -1599,40 +1599,40 @@ | ||
| 1599 | 1599 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1600 | 1600 | zNewStatus = pManifest->aField[i].zValue; |
| 1601 | 1601 | } |
| 1602 | 1602 | } |
| 1603 | 1603 | if( zNewStatus ){ |
| 1604 | - blob_appendf(&comment, "%h ticket [%s|%.10s]: <i>%h</i>", | |
| 1604 | + blob_appendf(&comment, "%h ticket [%s|%S]: <i>%h</i>", | |
| 1605 | 1605 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1606 | 1606 | ); |
| 1607 | 1607 | if( pManifest->nField>1 ){ |
| 1608 | 1608 | blob_appendf(&comment, " plus %d other change%s", |
| 1609 | 1609 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1610 | 1610 | } |
| 1611 | - blob_appendf(&brief, "%h ticket [%s|%.10s].", | |
| 1611 | + blob_appendf(&brief, "%h ticket [%s|%S].", | |
| 1612 | 1612 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1613 | 1613 | }else{ |
| 1614 | 1614 | zNewStatus = db_text("unknown", |
| 1615 | 1615 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1616 | 1616 | zStatusColumn, pManifest->zTicketUuid |
| 1617 | 1617 | ); |
| 1618 | - blob_appendf(&comment, "Ticket [%s|%.10s] <i>%h</i> status still %h with " | |
| 1618 | + blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with " | |
| 1619 | 1619 | "%d other change%s", |
| 1620 | 1620 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| 1621 | 1621 | pManifest->nField, pManifest->nField==1 ? "" : "s" |
| 1622 | 1622 | ); |
| 1623 | 1623 | fossil_free(zNewStatus); |
| 1624 | - blob_appendf(&brief, "Ticket [%s|%.10s]: %d change%s", | |
| 1624 | + blob_appendf(&brief, "Ticket [%s|%S]: %d change%s", | |
| 1625 | 1625 | pManifest->zTicketUuid, pManifest->zTicketUuid, pManifest->nField, |
| 1626 | 1626 | pManifest->nField==1 ? "" : "s" |
| 1627 | 1627 | ); |
| 1628 | 1628 | } |
| 1629 | 1629 | }else{ |
| 1630 | - blob_appendf(&comment, "New ticket [%s|%.10s] <i>%h</i>.", | |
| 1630 | + blob_appendf(&comment, "New ticket [%s|%S] <i>%h</i>.", | |
| 1631 | 1631 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1632 | 1632 | ); |
| 1633 | - blob_appendf(&brief, "New ticket [%s|%.10s].", pManifest->zTicketUuid, | |
| 1633 | + blob_appendf(&brief, "New ticket [%s|%S].", pManifest->zTicketUuid, | |
| 1634 | 1634 | pManifest->zTicketUuid); |
| 1635 | 1635 | } |
| 1636 | 1636 | fossil_free(zTitle); |
| 1637 | 1637 | db_multi_exec( |
| 1638 | 1638 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| @@ -1951,14 +1951,14 @@ | ||
| 1951 | 1951 | p->zAttachName, p->zAttachTarget); |
| 1952 | 1952 | } |
| 1953 | 1953 | }else{ |
| 1954 | 1954 | if( isAdd ){ |
| 1955 | 1955 | zComment = mprintf( |
| 1956 | - "Add attachment [/artifact/%s|%h] to ticket [%s|%.10s]", | |
| 1956 | + "Add attachment [/artifact/%s|%h] to ticket [%s|%S]", | |
| 1957 | 1957 | p->zAttachSrc, p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1958 | 1958 | }else{ |
| 1959 | - zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%.10s]", | |
| 1959 | + zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%S]", | |
| 1960 | 1960 | p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1961 | 1961 | } |
| 1962 | 1962 | } |
| 1963 | 1963 | db_multi_exec( |
| 1964 | 1964 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| @@ -1983,11 +1983,11 @@ | ||
| 1983 | 1983 | for(i=0; i<p->nTag; i++){ |
| 1984 | 1984 | zTagUuid = p->aTag[i].zUuid; |
| 1985 | 1985 | if( !zTagUuid ) continue; |
| 1986 | 1986 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1987 | 1987 | blob_appendf(&comment, |
| 1988 | - " Edit [%s|%.10s]:", | |
| 1988 | + " Edit [%s|%S]:", | |
| 1989 | 1989 | zTagUuid, zTagUuid); |
| 1990 | 1990 | branchMove = 0; |
| 1991 | 1991 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1992 | 1992 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1993 | 1993 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1994 | 1994 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -890,58 +890,58 @@ | |
| 890 | SYNTAX("cluster contains a card other than M- or Z-"); |
| 891 | } |
| 892 | if( !seenZ ) SYNTAX("missing Z-card on cluster"); |
| 893 | p->type = CFTYPE_CLUSTER; |
| 894 | }else if( p->zEventId ){ |
| 895 | if( p->rDate<=0.0 ) SYNTAX("missing date on event"); |
| 896 | if( p->nFile>0 ) SYNTAX("F-card in event"); |
| 897 | if( p->zRepoCksum ) SYNTAX("R-card in event"); |
| 898 | if( p->zBaseline ) SYNTAX("B-card in event"); |
| 899 | if( p->nField>0 ) SYNTAX("J-card in event"); |
| 900 | if( p->zTicketUuid ) SYNTAX("K-card in event"); |
| 901 | if( p->zWikiTitle!=0 ) SYNTAX("L-card in event"); |
| 902 | if( p->zWiki==0 ) SYNTAX("missing W-card on event"); |
| 903 | if( p->zAttachName ) SYNTAX("A-card in event"); |
| 904 | if( !seenZ ) SYNTAX("missing Z-card on event"); |
| 905 | p->type = CFTYPE_EVENT; |
| 906 | }else if( hasSelfRefTag || p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline ){ |
| 907 | if( p->rDate<=0.0 ) SYNTAX("missing date on manifest"); |
| 908 | if( p->nField>0 ) SYNTAX("J-card in manifest"); |
| 909 | if( p->zTicketUuid ) SYNTAX("K-card in manifest"); |
| 910 | if( p->zWiki ) SYNTAX("W-card in manifest"); |
| 911 | if( p->zWikiTitle ) SYNTAX("L-card in manifest"); |
| 912 | if( p->zTicketUuid ) SYNTAX("K-card in manifest"); |
| 913 | if( p->zAttachName ) SYNTAX("A-card in manifest"); |
| 914 | p->type = CFTYPE_MANIFEST; |
| 915 | }else if( p->nField>0 || p->zTicketUuid!=0 ){ |
| 916 | if( p->rDate<=0.0 ) SYNTAX("missing date on ticket"); |
| 917 | if( p->zWiki ) SYNTAX("W-card in ticket"); |
| 918 | if( p->zWikiTitle ) SYNTAX("L-card in ticket"); |
| 919 | if( p->nField==0 ) SYNTAX("missing J-card on ticket"); |
| 920 | if( p->nTag>0 ) SYNTAX("T-card in ticket"); |
| 921 | if( p->zTicketUuid==0 ) SYNTAX("missing K-card on ticket"); |
| 922 | if( p->zUser==0 ) SYNTAX("missing U-card on ticket"); |
| 923 | if( p->zAttachName ) SYNTAX("A-card in ticket"); |
| 924 | if( p->zMimetype) SYNTAX("N-card in ticket"); |
| 925 | if( !seenZ ) SYNTAX("missing Z-card on ticket"); |
| 926 | p->type = CFTYPE_TICKET; |
| 927 | }else if( p->zWiki!=0 || p->zWikiTitle!=0 ){ |
| 928 | if( p->rDate<=0.0 ) SYNTAX("missing date on wiki"); |
| 929 | if( p->nTag>0 ) SYNTAX("T-card in wiki"); |
| 930 | if( p->zWiki==0 ) SYNTAX("missing W-card on wiki"); |
| 931 | if( p->zWikiTitle==0 ) SYNTAX("missing L-card on wiki"); |
| 932 | if( p->zAttachName ) SYNTAX("A-card in wiki"); |
| 933 | if( !seenZ ) SYNTAX("missing Z-card on wiki"); |
| 934 | p->type = CFTYPE_WIKI; |
| 935 | }else if( p->zAttachName ){ |
| 936 | if( p->rDate<=0.0 ) SYNTAX("missing date on attachment"); |
| 937 | if( p->nTag>0 ) SYNTAX("T-card in attachment"); |
| 938 | if( !seenZ ) SYNTAX("missing Z-card on attachment"); |
| 939 | p->type = CFTYPE_ATTACHMENT; |
| 940 | }else{ |
| 941 | if( p->rDate<=0.0 ) SYNTAX("missing date on control"); |
| 942 | if( p->nParent>0 ) SYNTAX("P-card in control"); |
| 943 | if( p->zMimetype ) SYNTAX("N-card in control"); |
| 944 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 945 | p->type = CFTYPE_CONTROL; |
| 946 | } |
| 947 | md5sum_init(); |
| @@ -1599,40 +1599,40 @@ | |
| 1599 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1600 | zNewStatus = pManifest->aField[i].zValue; |
| 1601 | } |
| 1602 | } |
| 1603 | if( zNewStatus ){ |
| 1604 | blob_appendf(&comment, "%h ticket [%s|%.10s]: <i>%h</i>", |
| 1605 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1606 | ); |
| 1607 | if( pManifest->nField>1 ){ |
| 1608 | blob_appendf(&comment, " plus %d other change%s", |
| 1609 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1610 | } |
| 1611 | blob_appendf(&brief, "%h ticket [%s|%.10s].", |
| 1612 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1613 | }else{ |
| 1614 | zNewStatus = db_text("unknown", |
| 1615 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1616 | zStatusColumn, pManifest->zTicketUuid |
| 1617 | ); |
| 1618 | blob_appendf(&comment, "Ticket [%s|%.10s] <i>%h</i> status still %h with " |
| 1619 | "%d other change%s", |
| 1620 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| 1621 | pManifest->nField, pManifest->nField==1 ? "" : "s" |
| 1622 | ); |
| 1623 | fossil_free(zNewStatus); |
| 1624 | blob_appendf(&brief, "Ticket [%s|%.10s]: %d change%s", |
| 1625 | pManifest->zTicketUuid, pManifest->zTicketUuid, pManifest->nField, |
| 1626 | pManifest->nField==1 ? "" : "s" |
| 1627 | ); |
| 1628 | } |
| 1629 | }else{ |
| 1630 | blob_appendf(&comment, "New ticket [%s|%.10s] <i>%h</i>.", |
| 1631 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1632 | ); |
| 1633 | blob_appendf(&brief, "New ticket [%s|%.10s].", pManifest->zTicketUuid, |
| 1634 | pManifest->zTicketUuid); |
| 1635 | } |
| 1636 | fossil_free(zTitle); |
| 1637 | db_multi_exec( |
| 1638 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| @@ -1951,14 +1951,14 @@ | |
| 1951 | p->zAttachName, p->zAttachTarget); |
| 1952 | } |
| 1953 | }else{ |
| 1954 | if( isAdd ){ |
| 1955 | zComment = mprintf( |
| 1956 | "Add attachment [/artifact/%s|%h] to ticket [%s|%.10s]", |
| 1957 | p->zAttachSrc, p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1958 | }else{ |
| 1959 | zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%.10s]", |
| 1960 | p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1961 | } |
| 1962 | } |
| 1963 | db_multi_exec( |
| 1964 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| @@ -1983,11 +1983,11 @@ | |
| 1983 | for(i=0; i<p->nTag; i++){ |
| 1984 | zTagUuid = p->aTag[i].zUuid; |
| 1985 | if( !zTagUuid ) continue; |
| 1986 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1987 | blob_appendf(&comment, |
| 1988 | " Edit [%s|%.10s]:", |
| 1989 | zTagUuid, zTagUuid); |
| 1990 | branchMove = 0; |
| 1991 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1992 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1993 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1994 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -890,58 +890,58 @@ | |
| 890 | SYNTAX("cluster contains a card other than M- or Z-"); |
| 891 | } |
| 892 | if( !seenZ ) SYNTAX("missing Z-card on cluster"); |
| 893 | p->type = CFTYPE_CLUSTER; |
| 894 | }else if( p->zEventId ){ |
| 895 | if( p->zAttachName ) SYNTAX("A-card in event"); |
| 896 | if( p->zBaseline ) SYNTAX("B-card in event"); |
| 897 | if( p->rDate<=0.0 ) SYNTAX("missing date on event"); |
| 898 | if( p->nFile>0 ) SYNTAX("F-card in event"); |
| 899 | if( p->nField>0 ) SYNTAX("J-card in event"); |
| 900 | if( p->zTicketUuid ) SYNTAX("K-card in event"); |
| 901 | if( p->zWikiTitle!=0 ) SYNTAX("L-card in event"); |
| 902 | if( p->zRepoCksum ) SYNTAX("R-card in event"); |
| 903 | if( p->zWiki==0 ) SYNTAX("missing W-card on event"); |
| 904 | if( !seenZ ) SYNTAX("missing Z-card on event"); |
| 905 | p->type = CFTYPE_EVENT; |
| 906 | }else if( p->zWiki!=0 || p->zWikiTitle!=0 ){ |
| 907 | if( p->zAttachName ) SYNTAX("A-card in wiki"); |
| 908 | if( p->zBaseline ) SYNTAX("B-card in wiki"); |
| 909 | if( p->rDate<=0.0 ) SYNTAX("missing date on wiki"); |
| 910 | if( p->nFile>0 ) SYNTAX("F-card in wiki"); |
| 911 | if( p->nField>0 ) SYNTAX("J-card in wiki"); |
| 912 | if( p->zTicketUuid ) SYNTAX("K-card in wiki"); |
| 913 | if( p->zWikiTitle==0 ) SYNTAX("missing L-card on wiki"); |
| 914 | if( p->zRepoCksum ) SYNTAX("R-card in wiki"); |
| 915 | if( p->nTag>0 ) SYNTAX("T-card in wiki"); |
| 916 | if( p->zWiki==0 ) SYNTAX("missing W-card on wiki"); |
| 917 | if( !seenZ ) SYNTAX("missing Z-card on wiki"); |
| 918 | p->type = CFTYPE_WIKI; |
| 919 | }else if( hasSelfRefTag || p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline |
| 920 | || p->nParent>0 ){ |
| 921 | if( p->zAttachName ) SYNTAX("A-card in manifest"); |
| 922 | if( p->rDate<=0.0 ) SYNTAX("missing date on manifest"); |
| 923 | if( p->nField>0 ) SYNTAX("J-card in manifest"); |
| 924 | if( p->zTicketUuid ) SYNTAX("K-card in manifest"); |
| 925 | p->type = CFTYPE_MANIFEST; |
| 926 | }else if( p->nField>0 || p->zTicketUuid!=0 ){ |
| 927 | if( p->zAttachName ) SYNTAX("A-card in ticket"); |
| 928 | if( p->rDate<=0.0 ) SYNTAX("missing date on ticket"); |
| 929 | if( p->nField==0 ) SYNTAX("missing J-card on ticket"); |
| 930 | if( p->zTicketUuid==0 ) SYNTAX("missing K-card on ticket"); |
| 931 | if( p->zMimetype) SYNTAX("N-card in ticket"); |
| 932 | if( p->nTag>0 ) SYNTAX("T-card in ticket"); |
| 933 | if( p->zUser==0 ) SYNTAX("missing U-card on ticket"); |
| 934 | if( !seenZ ) SYNTAX("missing Z-card on ticket"); |
| 935 | p->type = CFTYPE_TICKET; |
| 936 | }else if( p->zAttachName ){ |
| 937 | if( p->rDate<=0.0 ) SYNTAX("missing date on attachment"); |
| 938 | if( p->nTag>0 ) SYNTAX("T-card in attachment"); |
| 939 | if( !seenZ ) SYNTAX("missing Z-card on attachment"); |
| 940 | p->type = CFTYPE_ATTACHMENT; |
| 941 | }else{ |
| 942 | if( p->rDate<=0.0 ) SYNTAX("missing date on control"); |
| 943 | if( p->zMimetype ) SYNTAX("N-card in control"); |
| 944 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 945 | p->type = CFTYPE_CONTROL; |
| 946 | } |
| 947 | md5sum_init(); |
| @@ -1599,40 +1599,40 @@ | |
| 1599 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1600 | zNewStatus = pManifest->aField[i].zValue; |
| 1601 | } |
| 1602 | } |
| 1603 | if( zNewStatus ){ |
| 1604 | blob_appendf(&comment, "%h ticket [%s|%S]: <i>%h</i>", |
| 1605 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1606 | ); |
| 1607 | if( pManifest->nField>1 ){ |
| 1608 | blob_appendf(&comment, " plus %d other change%s", |
| 1609 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1610 | } |
| 1611 | blob_appendf(&brief, "%h ticket [%s|%S].", |
| 1612 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1613 | }else{ |
| 1614 | zNewStatus = db_text("unknown", |
| 1615 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1616 | zStatusColumn, pManifest->zTicketUuid |
| 1617 | ); |
| 1618 | blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with " |
| 1619 | "%d other change%s", |
| 1620 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| 1621 | pManifest->nField, pManifest->nField==1 ? "" : "s" |
| 1622 | ); |
| 1623 | fossil_free(zNewStatus); |
| 1624 | blob_appendf(&brief, "Ticket [%s|%S]: %d change%s", |
| 1625 | pManifest->zTicketUuid, pManifest->zTicketUuid, pManifest->nField, |
| 1626 | pManifest->nField==1 ? "" : "s" |
| 1627 | ); |
| 1628 | } |
| 1629 | }else{ |
| 1630 | blob_appendf(&comment, "New ticket [%s|%S] <i>%h</i>.", |
| 1631 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1632 | ); |
| 1633 | blob_appendf(&brief, "New ticket [%s|%S].", pManifest->zTicketUuid, |
| 1634 | pManifest->zTicketUuid); |
| 1635 | } |
| 1636 | fossil_free(zTitle); |
| 1637 | db_multi_exec( |
| 1638 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| @@ -1951,14 +1951,14 @@ | |
| 1951 | p->zAttachName, p->zAttachTarget); |
| 1952 | } |
| 1953 | }else{ |
| 1954 | if( isAdd ){ |
| 1955 | zComment = mprintf( |
| 1956 | "Add attachment [/artifact/%s|%h] to ticket [%s|%S]", |
| 1957 | p->zAttachSrc, p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1958 | }else{ |
| 1959 | zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%S]", |
| 1960 | p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1961 | } |
| 1962 | } |
| 1963 | db_multi_exec( |
| 1964 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| @@ -1983,11 +1983,11 @@ | |
| 1983 | for(i=0; i<p->nTag; i++){ |
| 1984 | zTagUuid = p->aTag[i].zUuid; |
| 1985 | if( !zTagUuid ) continue; |
| 1986 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1987 | blob_appendf(&comment, |
| 1988 | " Edit [%s|%S]:", |
| 1989 | zTagUuid, zTagUuid); |
| 1990 | branchMove = 0; |
| 1991 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1992 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1993 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1994 |
+2
-2
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -47,11 +47,11 @@ | ||
| 47 | 47 | indent-1, zLabel, |
| 48 | 48 | db_column_text(&q, 3), |
| 49 | 49 | db_column_text(&q, 1), |
| 50 | 50 | db_column_text(&q, 0), |
| 51 | 51 | indent, ""); |
| 52 | - comment_print(zCom, indent, -1); | |
| 52 | + comment_print(zCom, db_column_text(&q,2), indent, -1, g.comFmtFlags); | |
| 53 | 53 | fossil_free(zCom); |
| 54 | 54 | } |
| 55 | 55 | db_finalize(&q); |
| 56 | 56 | } |
| 57 | 57 | |
| @@ -210,11 +210,11 @@ | ||
| 210 | 210 | ); |
| 211 | 211 | if( db_step(&q)==SQLITE_ROW ){ |
| 212 | 212 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 213 | 213 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 214 | 214 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 215 | - comment_print(zCom, 0, -1); | |
| 215 | + comment_print(zCom, db_column_text(&q,2), 0, -1, g.comFmtFlags); | |
| 216 | 216 | fossil_free(zCom); |
| 217 | 217 | } |
| 218 | 218 | db_finalize(&q); |
| 219 | 219 | }else{ |
| 220 | 220 | usage("?OPTIONS? ?VERSION?"); |
| 221 | 221 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -47,11 +47,11 @@ | |
| 47 | indent-1, zLabel, |
| 48 | db_column_text(&q, 3), |
| 49 | db_column_text(&q, 1), |
| 50 | db_column_text(&q, 0), |
| 51 | indent, ""); |
| 52 | comment_print(zCom, indent, -1); |
| 53 | fossil_free(zCom); |
| 54 | } |
| 55 | db_finalize(&q); |
| 56 | } |
| 57 | |
| @@ -210,11 +210,11 @@ | |
| 210 | ); |
| 211 | if( db_step(&q)==SQLITE_ROW ){ |
| 212 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 213 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 214 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 215 | comment_print(zCom, 0, -1); |
| 216 | fossil_free(zCom); |
| 217 | } |
| 218 | db_finalize(&q); |
| 219 | }else{ |
| 220 | usage("?OPTIONS? ?VERSION?"); |
| 221 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -47,11 +47,11 @@ | |
| 47 | indent-1, zLabel, |
| 48 | db_column_text(&q, 3), |
| 49 | db_column_text(&q, 1), |
| 50 | db_column_text(&q, 0), |
| 51 | indent, ""); |
| 52 | comment_print(zCom, db_column_text(&q,2), indent, -1, g.comFmtFlags); |
| 53 | fossil_free(zCom); |
| 54 | } |
| 55 | db_finalize(&q); |
| 56 | } |
| 57 | |
| @@ -210,11 +210,11 @@ | |
| 210 | ); |
| 211 | if( db_step(&q)==SQLITE_ROW ){ |
| 212 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 213 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 214 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 215 | comment_print(zCom, db_column_text(&q,2), 0, -1, g.comFmtFlags); |
| 216 | fossil_free(zCom); |
| 217 | } |
| 218 | db_finalize(&q); |
| 219 | }else{ |
| 220 | usage("?OPTIONS? ?VERSION?"); |
| 221 |
+4
| --- src/merge3.c | ||
| +++ src/merge3.c | ||
| @@ -368,10 +368,14 @@ | ||
| 368 | 368 | ** fossil commit |
| 369 | 369 | ** |
| 370 | 370 | */ |
| 371 | 371 | void delta_3waymerge_cmd(void){ |
| 372 | 372 | Blob pivot, v1, v2, merged; |
| 373 | + | |
| 374 | + /* We should be done with options.. */ | |
| 375 | + verify_all_options(); | |
| 376 | + | |
| 373 | 377 | if( g.argc!=6 ){ |
| 374 | 378 | usage("PIVOT V1 V2 MERGED"); |
| 375 | 379 | } |
| 376 | 380 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 377 | 381 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 378 | 382 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -368,10 +368,14 @@ | |
| 368 | ** fossil commit |
| 369 | ** |
| 370 | */ |
| 371 | void delta_3waymerge_cmd(void){ |
| 372 | Blob pivot, v1, v2, merged; |
| 373 | if( g.argc!=6 ){ |
| 374 | usage("PIVOT V1 V2 MERGED"); |
| 375 | } |
| 376 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 377 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 378 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -368,10 +368,14 @@ | |
| 368 | ** fossil commit |
| 369 | ** |
| 370 | */ |
| 371 | void delta_3waymerge_cmd(void){ |
| 372 | Blob pivot, v1, v2, merged; |
| 373 | |
| 374 | /* We should be done with options.. */ |
| 375 | verify_all_options(); |
| 376 | |
| 377 | if( g.argc!=6 ){ |
| 378 | usage("PIVOT V1 V2 MERGED"); |
| 379 | } |
| 380 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 381 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 382 |
+2
-1
| --- src/mkindex.c | ||
| +++ src/mkindex.c | ||
| @@ -283,11 +283,11 @@ | ||
| 283 | 283 | ); |
| 284 | 284 | for(i=0; i<nFixed /*&& aEntry[i].eType==1*/; i++){ |
| 285 | 285 | const char *z = aEntry[i].zPath; |
| 286 | 286 | int n = strlen(z); |
| 287 | 287 | int cmdFlags = (1==aEntry[i].eType) ? 0x01 : 0x08; |
| 288 | - if(0x01==cmdFlags){ | |
| 288 | + if( 0x01==cmdFlags ){ | |
| 289 | 289 | if( z[n-1]=='*' ){ |
| 290 | 290 | n--; |
| 291 | 291 | cmdFlags = 0x02; |
| 292 | 292 | }else if( memcmp(z, "test-", 5)==0 ){ |
| 293 | 293 | cmdFlags = 0x04; |
| @@ -303,10 +303,11 @@ | ||
| 303 | 303 | cmdFlags |
| 304 | 304 | ); |
| 305 | 305 | if( aEntry[i].zIf ) printf("#endif\n"); |
| 306 | 306 | } |
| 307 | 307 | printf("};\n"); |
| 308 | + printf("#define FOSSIL_FIRST_CMD (sizeof(aWebpage)/sizeof(aWebpage[0]))\n"); | |
| 308 | 309 | for(i=0; i<nFixed; i++){ |
| 309 | 310 | char *z = aEntry[i].zHelp; |
| 310 | 311 | if( z && z[0] ){ |
| 311 | 312 | if( aEntry[i].zIf ) printf("%s", aEntry[i].zIf); |
| 312 | 313 | printf("static const char zHelp_%s[] = \n", aEntry[i].zFunc); |
| 313 | 314 |
| --- src/mkindex.c | |
| +++ src/mkindex.c | |
| @@ -283,11 +283,11 @@ | |
| 283 | ); |
| 284 | for(i=0; i<nFixed /*&& aEntry[i].eType==1*/; i++){ |
| 285 | const char *z = aEntry[i].zPath; |
| 286 | int n = strlen(z); |
| 287 | int cmdFlags = (1==aEntry[i].eType) ? 0x01 : 0x08; |
| 288 | if(0x01==cmdFlags){ |
| 289 | if( z[n-1]=='*' ){ |
| 290 | n--; |
| 291 | cmdFlags = 0x02; |
| 292 | }else if( memcmp(z, "test-", 5)==0 ){ |
| 293 | cmdFlags = 0x04; |
| @@ -303,10 +303,11 @@ | |
| 303 | cmdFlags |
| 304 | ); |
| 305 | if( aEntry[i].zIf ) printf("#endif\n"); |
| 306 | } |
| 307 | printf("};\n"); |
| 308 | for(i=0; i<nFixed; i++){ |
| 309 | char *z = aEntry[i].zHelp; |
| 310 | if( z && z[0] ){ |
| 311 | if( aEntry[i].zIf ) printf("%s", aEntry[i].zIf); |
| 312 | printf("static const char zHelp_%s[] = \n", aEntry[i].zFunc); |
| 313 |
| --- src/mkindex.c | |
| +++ src/mkindex.c | |
| @@ -283,11 +283,11 @@ | |
| 283 | ); |
| 284 | for(i=0; i<nFixed /*&& aEntry[i].eType==1*/; i++){ |
| 285 | const char *z = aEntry[i].zPath; |
| 286 | int n = strlen(z); |
| 287 | int cmdFlags = (1==aEntry[i].eType) ? 0x01 : 0x08; |
| 288 | if( 0x01==cmdFlags ){ |
| 289 | if( z[n-1]=='*' ){ |
| 290 | n--; |
| 291 | cmdFlags = 0x02; |
| 292 | }else if( memcmp(z, "test-", 5)==0 ){ |
| 293 | cmdFlags = 0x04; |
| @@ -303,10 +303,11 @@ | |
| 303 | cmdFlags |
| 304 | ); |
| 305 | if( aEntry[i].zIf ) printf("#endif\n"); |
| 306 | } |
| 307 | printf("};\n"); |
| 308 | printf("#define FOSSIL_FIRST_CMD (sizeof(aWebpage)/sizeof(aWebpage[0]))\n"); |
| 309 | for(i=0; i<nFixed; i++){ |
| 310 | char *z = aEntry[i].zHelp; |
| 311 | if( z && z[0] ){ |
| 312 | if( aEntry[i].zIf ) printf("%s", aEntry[i].zIf); |
| 313 | printf("static const char zHelp_%s[] = \n", aEntry[i].zFunc); |
| 314 |
+10
-6
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -444,11 +444,11 @@ | ||
| 444 | 444 | " WHERE ticket.tkt_id = ticketchng.tkt_id" |
| 445 | 445 | " AND tkt_uuid GLOB '%q*'" |
| 446 | 446 | " GROUP BY tkt_uuid" |
| 447 | 447 | " ORDER BY tkt_ctime DESC", z); |
| 448 | 448 | while( db_step(&q)==SQLITE_ROW ){ |
| 449 | - int rid = db_column_int(&q, 0); | |
| 449 | + int rid = db_column_int(&q, 0); | |
| 450 | 450 | const char *zUuid = db_column_text(&q, 1); |
| 451 | 451 | const char *zTitle = db_column_text(&q, 2); |
| 452 | 452 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 453 | 453 | @ %s(zUuid)</a> - |
| 454 | 454 | @ <ul></ul> |
| @@ -465,11 +465,11 @@ | ||
| 465 | 465 | "SELECT rid, uuid FROM" |
| 466 | 466 | " (SELECT tagxref.rid AS rid, substr(tagname, 7) AS uuid" |
| 467 | 467 | " FROM tagxref, tag WHERE tagxref.tagid = tag.tagid" |
| 468 | 468 | " AND tagname GLOB 'event-%q*') GROUP BY uuid", z); |
| 469 | 469 | while( db_step(&q)==SQLITE_ROW ){ |
| 470 | - int rid = db_column_int(&q, 0); | |
| 470 | + int rid = db_column_int(&q, 0); | |
| 471 | 471 | const char* zUuid = db_column_text(&q, 1); |
| 472 | 472 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 473 | 473 | @ %s(zUuid)</a> - |
| 474 | 474 | @ <ul><li> |
| 475 | 475 | object_description(rid, 0, 0); |
| @@ -582,11 +582,11 @@ | ||
| 582 | 582 | default: zType = "Unknown"; break; |
| 583 | 583 | } |
| 584 | 584 | fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 585 | 585 | db_column_text(&q, 1)); |
| 586 | 586 | fossil_print("comment: "); |
| 587 | - comment_print(db_column_text(&q,3), 12, -1); | |
| 587 | + comment_print(db_column_text(&q,3), 0, 12, -1, g.comFmtFlags); | |
| 588 | 588 | } |
| 589 | 589 | db_finalize(&q); |
| 590 | 590 | |
| 591 | 591 | /* Check to see if this object is used as a file in a check-in */ |
| 592 | 592 | db_prepare(&q, |
| @@ -599,16 +599,16 @@ | ||
| 599 | 599 | " AND blob.rid=mlink.mid" |
| 600 | 600 | " ORDER BY event.mtime DESC /*sort*/", |
| 601 | 601 | timeline_utc(), rid); |
| 602 | 602 | while( db_step(&q)==SQLITE_ROW ){ |
| 603 | 603 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 604 | - fossil_print(" part of [%.10s] by %s on %s\n", | |
| 604 | + fossil_print(" part of [%S] by %s on %s\n", | |
| 605 | 605 | db_column_text(&q, 1), |
| 606 | 606 | db_column_text(&q, 3), |
| 607 | 607 | db_column_text(&q, 2)); |
| 608 | 608 | fossil_print(" "); |
| 609 | - comment_print(db_column_text(&q,4), 12, -1); | |
| 609 | + comment_print(db_column_text(&q,4), 0, 12, -1, g.comFmtFlags); | |
| 610 | 610 | } |
| 611 | 611 | db_finalize(&q); |
| 612 | 612 | |
| 613 | 613 | /* Check to see if this object is used as an attachment */ |
| 614 | 614 | db_prepare(&q, |
| @@ -639,11 +639,11 @@ | ||
| 639 | 639 | db_column_text(&q,7)); |
| 640 | 640 | } |
| 641 | 641 | fossil_print(" by user %s on %s\n", |
| 642 | 642 | db_column_text(&q,2), db_column_text(&q,3)); |
| 643 | 643 | fossil_print(" "); |
| 644 | - comment_print(db_column_text(&q,1), 12, -1); | |
| 644 | + comment_print(db_column_text(&q,1), 0, 12, -1, g.comFmtFlags); | |
| 645 | 645 | } |
| 646 | 646 | db_finalize(&q); |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | 649 | /* |
| @@ -659,10 +659,14 @@ | ||
| 659 | 659 | const char *zName; |
| 660 | 660 | int verboseFlag; |
| 661 | 661 | int i; |
| 662 | 662 | db_find_and_open_repository(0,0); |
| 663 | 663 | verboseFlag = find_option("verbose","v",0)!=0; |
| 664 | + | |
| 665 | + /* We should be done with options.. */ | |
| 666 | + verify_all_options(); | |
| 667 | + | |
| 664 | 668 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 665 | 669 | for(i=2; i<g.argc; i++){ |
| 666 | 670 | zName = g.argv[i]; |
| 667 | 671 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 668 | 672 | rid = symbolic_name_to_rid(zName, 0); |
| 669 | 673 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -444,11 +444,11 @@ | |
| 444 | " WHERE ticket.tkt_id = ticketchng.tkt_id" |
| 445 | " AND tkt_uuid GLOB '%q*'" |
| 446 | " GROUP BY tkt_uuid" |
| 447 | " ORDER BY tkt_ctime DESC", z); |
| 448 | while( db_step(&q)==SQLITE_ROW ){ |
| 449 | int rid = db_column_int(&q, 0); |
| 450 | const char *zUuid = db_column_text(&q, 1); |
| 451 | const char *zTitle = db_column_text(&q, 2); |
| 452 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 453 | @ %s(zUuid)</a> - |
| 454 | @ <ul></ul> |
| @@ -465,11 +465,11 @@ | |
| 465 | "SELECT rid, uuid FROM" |
| 466 | " (SELECT tagxref.rid AS rid, substr(tagname, 7) AS uuid" |
| 467 | " FROM tagxref, tag WHERE tagxref.tagid = tag.tagid" |
| 468 | " AND tagname GLOB 'event-%q*') GROUP BY uuid", z); |
| 469 | while( db_step(&q)==SQLITE_ROW ){ |
| 470 | int rid = db_column_int(&q, 0); |
| 471 | const char* zUuid = db_column_text(&q, 1); |
| 472 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 473 | @ %s(zUuid)</a> - |
| 474 | @ <ul><li> |
| 475 | object_description(rid, 0, 0); |
| @@ -582,11 +582,11 @@ | |
| 582 | default: zType = "Unknown"; break; |
| 583 | } |
| 584 | fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 585 | db_column_text(&q, 1)); |
| 586 | fossil_print("comment: "); |
| 587 | comment_print(db_column_text(&q,3), 12, -1); |
| 588 | } |
| 589 | db_finalize(&q); |
| 590 | |
| 591 | /* Check to see if this object is used as a file in a check-in */ |
| 592 | db_prepare(&q, |
| @@ -599,16 +599,16 @@ | |
| 599 | " AND blob.rid=mlink.mid" |
| 600 | " ORDER BY event.mtime DESC /*sort*/", |
| 601 | timeline_utc(), rid); |
| 602 | while( db_step(&q)==SQLITE_ROW ){ |
| 603 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 604 | fossil_print(" part of [%.10s] by %s on %s\n", |
| 605 | db_column_text(&q, 1), |
| 606 | db_column_text(&q, 3), |
| 607 | db_column_text(&q, 2)); |
| 608 | fossil_print(" "); |
| 609 | comment_print(db_column_text(&q,4), 12, -1); |
| 610 | } |
| 611 | db_finalize(&q); |
| 612 | |
| 613 | /* Check to see if this object is used as an attachment */ |
| 614 | db_prepare(&q, |
| @@ -639,11 +639,11 @@ | |
| 639 | db_column_text(&q,7)); |
| 640 | } |
| 641 | fossil_print(" by user %s on %s\n", |
| 642 | db_column_text(&q,2), db_column_text(&q,3)); |
| 643 | fossil_print(" "); |
| 644 | comment_print(db_column_text(&q,1), 12, -1); |
| 645 | } |
| 646 | db_finalize(&q); |
| 647 | } |
| 648 | |
| 649 | /* |
| @@ -659,10 +659,14 @@ | |
| 659 | const char *zName; |
| 660 | int verboseFlag; |
| 661 | int i; |
| 662 | db_find_and_open_repository(0,0); |
| 663 | verboseFlag = find_option("verbose","v",0)!=0; |
| 664 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 665 | for(i=2; i<g.argc; i++){ |
| 666 | zName = g.argv[i]; |
| 667 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 668 | rid = symbolic_name_to_rid(zName, 0); |
| 669 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -444,11 +444,11 @@ | |
| 444 | " WHERE ticket.tkt_id = ticketchng.tkt_id" |
| 445 | " AND tkt_uuid GLOB '%q*'" |
| 446 | " GROUP BY tkt_uuid" |
| 447 | " ORDER BY tkt_ctime DESC", z); |
| 448 | while( db_step(&q)==SQLITE_ROW ){ |
| 449 | int rid = db_column_int(&q, 0); |
| 450 | const char *zUuid = db_column_text(&q, 1); |
| 451 | const char *zTitle = db_column_text(&q, 2); |
| 452 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 453 | @ %s(zUuid)</a> - |
| 454 | @ <ul></ul> |
| @@ -465,11 +465,11 @@ | |
| 465 | "SELECT rid, uuid FROM" |
| 466 | " (SELECT tagxref.rid AS rid, substr(tagname, 7) AS uuid" |
| 467 | " FROM tagxref, tag WHERE tagxref.tagid = tag.tagid" |
| 468 | " AND tagname GLOB 'event-%q*') GROUP BY uuid", z); |
| 469 | while( db_step(&q)==SQLITE_ROW ){ |
| 470 | int rid = db_column_int(&q, 0); |
| 471 | const char* zUuid = db_column_text(&q, 1); |
| 472 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 473 | @ %s(zUuid)</a> - |
| 474 | @ <ul><li> |
| 475 | object_description(rid, 0, 0); |
| @@ -582,11 +582,11 @@ | |
| 582 | default: zType = "Unknown"; break; |
| 583 | } |
| 584 | fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 585 | db_column_text(&q, 1)); |
| 586 | fossil_print("comment: "); |
| 587 | comment_print(db_column_text(&q,3), 0, 12, -1, g.comFmtFlags); |
| 588 | } |
| 589 | db_finalize(&q); |
| 590 | |
| 591 | /* Check to see if this object is used as a file in a check-in */ |
| 592 | db_prepare(&q, |
| @@ -599,16 +599,16 @@ | |
| 599 | " AND blob.rid=mlink.mid" |
| 600 | " ORDER BY event.mtime DESC /*sort*/", |
| 601 | timeline_utc(), rid); |
| 602 | while( db_step(&q)==SQLITE_ROW ){ |
| 603 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 604 | fossil_print(" part of [%S] by %s on %s\n", |
| 605 | db_column_text(&q, 1), |
| 606 | db_column_text(&q, 3), |
| 607 | db_column_text(&q, 2)); |
| 608 | fossil_print(" "); |
| 609 | comment_print(db_column_text(&q,4), 0, 12, -1, g.comFmtFlags); |
| 610 | } |
| 611 | db_finalize(&q); |
| 612 | |
| 613 | /* Check to see if this object is used as an attachment */ |
| 614 | db_prepare(&q, |
| @@ -639,11 +639,11 @@ | |
| 639 | db_column_text(&q,7)); |
| 640 | } |
| 641 | fossil_print(" by user %s on %s\n", |
| 642 | db_column_text(&q,2), db_column_text(&q,3)); |
| 643 | fossil_print(" "); |
| 644 | comment_print(db_column_text(&q,1), 0, 12, -1, g.comFmtFlags); |
| 645 | } |
| 646 | db_finalize(&q); |
| 647 | } |
| 648 | |
| 649 | /* |
| @@ -659,10 +659,14 @@ | |
| 659 | const char *zName; |
| 660 | int verboseFlag; |
| 661 | int i; |
| 662 | db_find_and_open_repository(0,0); |
| 663 | verboseFlag = find_option("verbose","v",0)!=0; |
| 664 | |
| 665 | /* We should be done with options.. */ |
| 666 | verify_all_options(); |
| 667 | |
| 668 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 669 | for(i=2; i<g.argc; i++){ |
| 670 | zName = g.argv[i]; |
| 671 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 672 | rid = symbolic_name_to_rid(zName, 0); |
| 673 |
+14
-6
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -608,22 +608,26 @@ | ||
| 608 | 608 | case etROOT: { |
| 609 | 609 | bufpt = g.zTop ? g.zTop : ""; |
| 610 | 610 | length = (int)strlen(bufpt); |
| 611 | 611 | break; |
| 612 | 612 | } |
| 613 | - case etSTRINGID: { | |
| 614 | - precision = 16; | |
| 615 | - /* Fall through */ | |
| 616 | - } | |
| 613 | + case etSTRINGID: | |
| 617 | 614 | case etSTRING: |
| 618 | 615 | case etDYNSTRING: { |
| 619 | 616 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 620 | 617 | bufpt = va_arg(ap,char*); |
| 621 | 618 | if( bufpt==0 ){ |
| 622 | 619 | bufpt = ""; |
| 623 | 620 | }else if( xtype==etDYNSTRING ){ |
| 624 | 621 | zExtra = bufpt; |
| 622 | + }else if( xtype==etSTRINGID ){ | |
| 623 | + precision = 0; | |
| 624 | + while( bufpt[precision]>='0' && bufpt[precision]<='9' ){ | |
| 625 | + precision++; | |
| 626 | + } | |
| 627 | + if( bufpt[precision]!=0 ) precision++; | |
| 628 | + if( precision<10 ) precision=10; | |
| 625 | 629 | } |
| 626 | 630 | length = StrNLen32(bufpt, limit); |
| 627 | 631 | if( precision>=0 && precision<length ) length = precision; |
| 628 | 632 | break; |
| 629 | 633 | } |
| @@ -862,12 +866,16 @@ | ||
| 862 | 866 | |
| 863 | 867 | /* |
| 864 | 868 | ** Force the standard output cursor to move to the beginning |
| 865 | 869 | ** of a line, if it is not there already. |
| 866 | 870 | */ |
| 867 | -void fossil_force_newline(void){ | |
| 868 | - if( g.cgiOutput==0 && stdoutAtBOL==0 ) fossil_puts("\n", 0); | |
| 871 | +int fossil_force_newline(void){ | |
| 872 | + if( g.cgiOutput==0 && stdoutAtBOL==0 ){ | |
| 873 | + fossil_puts("\n", 0); | |
| 874 | + return 1; | |
| 875 | + } | |
| 876 | + return 0; | |
| 869 | 877 | } |
| 870 | 878 | |
| 871 | 879 | /* |
| 872 | 880 | ** Indicate that the cursor has moved to the start of a line by means |
| 873 | 881 | ** other than writing to standard output. |
| 874 | 882 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -608,22 +608,26 @@ | |
| 608 | case etROOT: { |
| 609 | bufpt = g.zTop ? g.zTop : ""; |
| 610 | length = (int)strlen(bufpt); |
| 611 | break; |
| 612 | } |
| 613 | case etSTRINGID: { |
| 614 | precision = 16; |
| 615 | /* Fall through */ |
| 616 | } |
| 617 | case etSTRING: |
| 618 | case etDYNSTRING: { |
| 619 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 620 | bufpt = va_arg(ap,char*); |
| 621 | if( bufpt==0 ){ |
| 622 | bufpt = ""; |
| 623 | }else if( xtype==etDYNSTRING ){ |
| 624 | zExtra = bufpt; |
| 625 | } |
| 626 | length = StrNLen32(bufpt, limit); |
| 627 | if( precision>=0 && precision<length ) length = precision; |
| 628 | break; |
| 629 | } |
| @@ -862,12 +866,16 @@ | |
| 862 | |
| 863 | /* |
| 864 | ** Force the standard output cursor to move to the beginning |
| 865 | ** of a line, if it is not there already. |
| 866 | */ |
| 867 | void fossil_force_newline(void){ |
| 868 | if( g.cgiOutput==0 && stdoutAtBOL==0 ) fossil_puts("\n", 0); |
| 869 | } |
| 870 | |
| 871 | /* |
| 872 | ** Indicate that the cursor has moved to the start of a line by means |
| 873 | ** other than writing to standard output. |
| 874 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -608,22 +608,26 @@ | |
| 608 | case etROOT: { |
| 609 | bufpt = g.zTop ? g.zTop : ""; |
| 610 | length = (int)strlen(bufpt); |
| 611 | break; |
| 612 | } |
| 613 | case etSTRINGID: |
| 614 | case etSTRING: |
| 615 | case etDYNSTRING: { |
| 616 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 617 | bufpt = va_arg(ap,char*); |
| 618 | if( bufpt==0 ){ |
| 619 | bufpt = ""; |
| 620 | }else if( xtype==etDYNSTRING ){ |
| 621 | zExtra = bufpt; |
| 622 | }else if( xtype==etSTRINGID ){ |
| 623 | precision = 0; |
| 624 | while( bufpt[precision]>='0' && bufpt[precision]<='9' ){ |
| 625 | precision++; |
| 626 | } |
| 627 | if( bufpt[precision]!=0 ) precision++; |
| 628 | if( precision<10 ) precision=10; |
| 629 | } |
| 630 | length = StrNLen32(bufpt, limit); |
| 631 | if( precision>=0 && precision<length ) length = precision; |
| 632 | break; |
| 633 | } |
| @@ -862,12 +866,16 @@ | |
| 866 | |
| 867 | /* |
| 868 | ** Force the standard output cursor to move to the beginning |
| 869 | ** of a line, if it is not there already. |
| 870 | */ |
| 871 | int fossil_force_newline(void){ |
| 872 | if( g.cgiOutput==0 && stdoutAtBOL==0 ){ |
| 873 | fossil_puts("\n", 0); |
| 874 | return 1; |
| 875 | } |
| 876 | return 0; |
| 877 | } |
| 878 | |
| 879 | /* |
| 880 | ** Indicate that the cursor has moved to the start of a line by means |
| 881 | ** other than writing to standard output. |
| 882 |
+12
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -578,10 +578,14 @@ | ||
| 578 | 578 | usage("?REPOSITORY-FILENAME?"); |
| 579 | 579 | } |
| 580 | 580 | db_close(1); |
| 581 | 581 | db_open_repository(g.zRepositoryName); |
| 582 | 582 | } |
| 583 | + | |
| 584 | + /* We should be done with options.. */ | |
| 585 | + verify_all_options(); | |
| 586 | + | |
| 583 | 587 | db_begin_transaction(); |
| 584 | 588 | ttyOutput = 1; |
| 585 | 589 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 586 | 590 | reconstruct_private_table(); |
| 587 | 591 | db_multi_exec( |
| @@ -793,10 +797,14 @@ | ||
| 793 | 797 | int privateOnly = find_option("private",0,0)!=0; |
| 794 | 798 | int bNeedRebuild = 0; |
| 795 | 799 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 2); |
| 796 | 800 | db_close(1); |
| 797 | 801 | db_open_repository(g.zRepositoryName); |
| 802 | + | |
| 803 | + /* We should be done with options.. */ | |
| 804 | + verify_all_options(); | |
| 805 | + | |
| 798 | 806 | if( !bForce ){ |
| 799 | 807 | Blob ans; |
| 800 | 808 | char cReply; |
| 801 | 809 | prompt_user( |
| 802 | 810 | "Scrubbing the repository will permanently delete information.\n" |
| @@ -915,10 +923,14 @@ | ||
| 915 | 923 | fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); |
| 916 | 924 | usage("FILENAME DIRECTORY"); |
| 917 | 925 | } |
| 918 | 926 | db_create_repository(g.argv[2]); |
| 919 | 927 | db_open_repository(g.argv[2]); |
| 928 | + | |
| 929 | + /* We should be done with options.. */ | |
| 930 | + verify_all_options(); | |
| 931 | + | |
| 920 | 932 | db_open_config(0); |
| 921 | 933 | db_begin_transaction(); |
| 922 | 934 | db_initial_setup(0, 0, 0, 1); |
| 923 | 935 | |
| 924 | 936 | fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); |
| 925 | 937 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -578,10 +578,14 @@ | |
| 578 | usage("?REPOSITORY-FILENAME?"); |
| 579 | } |
| 580 | db_close(1); |
| 581 | db_open_repository(g.zRepositoryName); |
| 582 | } |
| 583 | db_begin_transaction(); |
| 584 | ttyOutput = 1; |
| 585 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 586 | reconstruct_private_table(); |
| 587 | db_multi_exec( |
| @@ -793,10 +797,14 @@ | |
| 793 | int privateOnly = find_option("private",0,0)!=0; |
| 794 | int bNeedRebuild = 0; |
| 795 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 2); |
| 796 | db_close(1); |
| 797 | db_open_repository(g.zRepositoryName); |
| 798 | if( !bForce ){ |
| 799 | Blob ans; |
| 800 | char cReply; |
| 801 | prompt_user( |
| 802 | "Scrubbing the repository will permanently delete information.\n" |
| @@ -915,10 +923,14 @@ | |
| 915 | fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); |
| 916 | usage("FILENAME DIRECTORY"); |
| 917 | } |
| 918 | db_create_repository(g.argv[2]); |
| 919 | db_open_repository(g.argv[2]); |
| 920 | db_open_config(0); |
| 921 | db_begin_transaction(); |
| 922 | db_initial_setup(0, 0, 0, 1); |
| 923 | |
| 924 | fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); |
| 925 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -578,10 +578,14 @@ | |
| 578 | usage("?REPOSITORY-FILENAME?"); |
| 579 | } |
| 580 | db_close(1); |
| 581 | db_open_repository(g.zRepositoryName); |
| 582 | } |
| 583 | |
| 584 | /* We should be done with options.. */ |
| 585 | verify_all_options(); |
| 586 | |
| 587 | db_begin_transaction(); |
| 588 | ttyOutput = 1; |
| 589 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 590 | reconstruct_private_table(); |
| 591 | db_multi_exec( |
| @@ -793,10 +797,14 @@ | |
| 797 | int privateOnly = find_option("private",0,0)!=0; |
| 798 | int bNeedRebuild = 0; |
| 799 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 2); |
| 800 | db_close(1); |
| 801 | db_open_repository(g.zRepositoryName); |
| 802 | |
| 803 | /* We should be done with options.. */ |
| 804 | verify_all_options(); |
| 805 | |
| 806 | if( !bForce ){ |
| 807 | Blob ans; |
| 808 | char cReply; |
| 809 | prompt_user( |
| 810 | "Scrubbing the repository will permanently delete information.\n" |
| @@ -915,10 +923,14 @@ | |
| 923 | fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); |
| 924 | usage("FILENAME DIRECTORY"); |
| 925 | } |
| 926 | db_create_repository(g.argv[2]); |
| 927 | db_open_repository(g.argv[2]); |
| 928 | |
| 929 | /* We should be done with options.. */ |
| 930 | verify_all_options(); |
| 931 | |
| 932 | db_open_config(0); |
| 933 | db_begin_transaction(); |
| 934 | db_initial_setup(0, 0, 0, 1); |
| 935 | |
| 936 | fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); |
| 937 |
-1
| --- src/regexp.c | ||
| +++ src/regexp.c | ||
| @@ -768,11 +768,10 @@ | ||
| 768 | 768 | */ |
| 769 | 769 | void re_test_grep(void){ |
| 770 | 770 | ReCompiled *pRe; |
| 771 | 771 | const char *zErr; |
| 772 | 772 | int ignoreCase = find_option("ignore-case","i",0)!=0; |
| 773 | - | |
| 774 | 773 | if( g.argc<3 ){ |
| 775 | 774 | usage("REGEXP [FILE...]"); |
| 776 | 775 | } |
| 777 | 776 | zErr = re_compile(&pRe, g.argv[2], ignoreCase); |
| 778 | 777 | if( zErr ) fossil_fatal("%s", zErr); |
| 779 | 778 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -768,11 +768,10 @@ | |
| 768 | */ |
| 769 | void re_test_grep(void){ |
| 770 | ReCompiled *pRe; |
| 771 | const char *zErr; |
| 772 | int ignoreCase = find_option("ignore-case","i",0)!=0; |
| 773 | |
| 774 | if( g.argc<3 ){ |
| 775 | usage("REGEXP [FILE...]"); |
| 776 | } |
| 777 | zErr = re_compile(&pRe, g.argv[2], ignoreCase); |
| 778 | if( zErr ) fossil_fatal("%s", zErr); |
| 779 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -768,11 +768,10 @@ | |
| 768 | */ |
| 769 | void re_test_grep(void){ |
| 770 | ReCompiled *pRe; |
| 771 | const char *zErr; |
| 772 | int ignoreCase = find_option("ignore-case","i",0)!=0; |
| 773 | if( g.argc<3 ){ |
| 774 | usage("REGEXP [FILE...]"); |
| 775 | } |
| 776 | zErr = re_compile(&pRe, g.argv[2], ignoreCase); |
| 777 | if( zErr ) fossil_fatal("%s", zErr); |
| 778 |
+10
-2
| --- src/rss.c | ||
| +++ src/rss.c | ||
| @@ -27,11 +27,13 @@ | ||
| 27 | 27 | ** URL: /timeline.rss?y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&wiki=NAME&name=FILENAME |
| 28 | 28 | ** |
| 29 | 29 | ** Produce an RSS feed of the timeline. |
| 30 | 30 | ** |
| 31 | 31 | ** TYPE may be: all, ci (show checkins only), t (show tickets only), |
| 32 | -** w (show wiki only). LIMIT is the number of items to show. | |
| 32 | +** w (show wiki only). | |
| 33 | +** | |
| 34 | +** LIMIT is the number of items to show. | |
| 33 | 35 | ** |
| 34 | 36 | ** tkt=UUID filters for only those events for the specified ticket. tag=TAG |
| 35 | 37 | ** filters for a tag, and wiki=NAME for a wiki page. Only one may be used. |
| 36 | 38 | ** |
| 37 | 39 | ** In addition, name=FILENAME filters for a specific file. This may be |
| @@ -212,11 +214,14 @@ | ||
| 212 | 214 | ** The CLI variant of the /timeline.rss page, this produces an RSS |
| 213 | 215 | ** feed of the timeline to stdout. Options: |
| 214 | 216 | ** |
| 215 | 217 | ** -type|y FLAG |
| 216 | 218 | ** may be: all (default), ci (show checkins only), t (show tickets only), |
| 217 | -** w (show wiki only). LIMIT is the number of items to show. | |
| 219 | +** w (show wiki only). | |
| 220 | +** | |
| 221 | +** -limit|n LIMIT | |
| 222 | +** The maximum number of items to show. | |
| 218 | 223 | ** |
| 219 | 224 | ** -tkt UUID |
| 220 | 225 | ** Filters for only those events for the specified ticket. |
| 221 | 226 | ** |
| 222 | 227 | ** -tag TAG |
| @@ -267,10 +272,13 @@ | ||
| 267 | 272 | if(!zBaseURL || !*zBaseURL){ |
| 268 | 273 | zBaseURL = "URL-PLACEHOLDER"; |
| 269 | 274 | } |
| 270 | 275 | |
| 271 | 276 | db_find_and_open_repository(0, 0); |
| 277 | + | |
| 278 | + /* We should be done with options.. */ | |
| 279 | + verify_all_options(); | |
| 272 | 280 | |
| 273 | 281 | blob_zero(&bSQL); |
| 274 | 282 | blob_append( &bSQL, zSQL1, -1 ); |
| 275 | 283 | |
| 276 | 284 | if( zType[0]!='a' ){ |
| 277 | 285 |
| --- src/rss.c | |
| +++ src/rss.c | |
| @@ -27,11 +27,13 @@ | |
| 27 | ** URL: /timeline.rss?y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&wiki=NAME&name=FILENAME |
| 28 | ** |
| 29 | ** Produce an RSS feed of the timeline. |
| 30 | ** |
| 31 | ** TYPE may be: all, ci (show checkins only), t (show tickets only), |
| 32 | ** w (show wiki only). LIMIT is the number of items to show. |
| 33 | ** |
| 34 | ** tkt=UUID filters for only those events for the specified ticket. tag=TAG |
| 35 | ** filters for a tag, and wiki=NAME for a wiki page. Only one may be used. |
| 36 | ** |
| 37 | ** In addition, name=FILENAME filters for a specific file. This may be |
| @@ -212,11 +214,14 @@ | |
| 212 | ** The CLI variant of the /timeline.rss page, this produces an RSS |
| 213 | ** feed of the timeline to stdout. Options: |
| 214 | ** |
| 215 | ** -type|y FLAG |
| 216 | ** may be: all (default), ci (show checkins only), t (show tickets only), |
| 217 | ** w (show wiki only). LIMIT is the number of items to show. |
| 218 | ** |
| 219 | ** -tkt UUID |
| 220 | ** Filters for only those events for the specified ticket. |
| 221 | ** |
| 222 | ** -tag TAG |
| @@ -267,10 +272,13 @@ | |
| 267 | if(!zBaseURL || !*zBaseURL){ |
| 268 | zBaseURL = "URL-PLACEHOLDER"; |
| 269 | } |
| 270 | |
| 271 | db_find_and_open_repository(0, 0); |
| 272 | |
| 273 | blob_zero(&bSQL); |
| 274 | blob_append( &bSQL, zSQL1, -1 ); |
| 275 | |
| 276 | if( zType[0]!='a' ){ |
| 277 |
| --- src/rss.c | |
| +++ src/rss.c | |
| @@ -27,11 +27,13 @@ | |
| 27 | ** URL: /timeline.rss?y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&wiki=NAME&name=FILENAME |
| 28 | ** |
| 29 | ** Produce an RSS feed of the timeline. |
| 30 | ** |
| 31 | ** TYPE may be: all, ci (show checkins only), t (show tickets only), |
| 32 | ** w (show wiki only). |
| 33 | ** |
| 34 | ** LIMIT is the number of items to show. |
| 35 | ** |
| 36 | ** tkt=UUID filters for only those events for the specified ticket. tag=TAG |
| 37 | ** filters for a tag, and wiki=NAME for a wiki page. Only one may be used. |
| 38 | ** |
| 39 | ** In addition, name=FILENAME filters for a specific file. This may be |
| @@ -212,11 +214,14 @@ | |
| 214 | ** The CLI variant of the /timeline.rss page, this produces an RSS |
| 215 | ** feed of the timeline to stdout. Options: |
| 216 | ** |
| 217 | ** -type|y FLAG |
| 218 | ** may be: all (default), ci (show checkins only), t (show tickets only), |
| 219 | ** w (show wiki only). |
| 220 | ** |
| 221 | ** -limit|n LIMIT |
| 222 | ** The maximum number of items to show. |
| 223 | ** |
| 224 | ** -tkt UUID |
| 225 | ** Filters for only those events for the specified ticket. |
| 226 | ** |
| 227 | ** -tag TAG |
| @@ -267,10 +272,13 @@ | |
| 272 | if(!zBaseURL || !*zBaseURL){ |
| 273 | zBaseURL = "URL-PLACEHOLDER"; |
| 274 | } |
| 275 | |
| 276 | db_find_and_open_repository(0, 0); |
| 277 | |
| 278 | /* We should be done with options.. */ |
| 279 | verify_all_options(); |
| 280 | |
| 281 | blob_zero(&bSQL); |
| 282 | blob_append( &bSQL, zSQL1, -1 ); |
| 283 | |
| 284 | if( zType[0]!='a' ){ |
| 285 |
+132
-27
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -62,10 +62,11 @@ | ||
| 62 | 62 | # define stifle_history(X) |
| 63 | 63 | #endif |
| 64 | 64 | |
| 65 | 65 | #if defined(_WIN32) || defined(WIN32) |
| 66 | 66 | # include <io.h> |
| 67 | +# include <fcntl.h> | |
| 67 | 68 | #define isatty(h) _isatty(h) |
| 68 | 69 | #ifndef access |
| 69 | 70 | # define access(f,m) _access((f),(m)) |
| 70 | 71 | #endif |
| 71 | 72 | #undef popen |
| @@ -456,10 +457,11 @@ | ||
| 456 | 457 | int mode; /* An output mode setting */ |
| 457 | 458 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 458 | 459 | int showHeader; /* True to show column names in List or Column mode */ |
| 459 | 460 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 460 | 461 | char separator[20]; /* Separator character for MODE_List */ |
| 462 | + char newline[20]; /* Record separator in MODE_Csv */ | |
| 461 | 463 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 462 | 464 | int actualWidth[100]; /* Actual width of each column */ |
| 463 | 465 | char nullvalue[20]; /* The text to print when a NULL comes back from |
| 464 | 466 | ** the database */ |
| 465 | 467 | struct previous_mode_data explainPrev; |
| @@ -657,11 +659,12 @@ | ||
| 657 | 659 | }; |
| 658 | 660 | |
| 659 | 661 | /* |
| 660 | 662 | ** Output a single term of CSV. Actually, p->separator is used for |
| 661 | 663 | ** the separator, which may or may not be a comma. p->nullvalue is |
| 662 | -** the null value. Strings are quoted if necessary. | |
| 664 | +** the null value. Strings are quoted if necessary. The separator | |
| 665 | +** is only issued if bSep is true. | |
| 663 | 666 | */ |
| 664 | 667 | static void output_csv(struct callback_data *p, const char *z, int bSep){ |
| 665 | 668 | FILE *out = p->out; |
| 666 | 669 | if( z==0 ){ |
| 667 | 670 | fprintf(out,"%s",p->nullvalue); |
| @@ -853,21 +856,30 @@ | ||
| 853 | 856 | } |
| 854 | 857 | fprintf(p->out,"\n"); |
| 855 | 858 | break; |
| 856 | 859 | } |
| 857 | 860 | case MODE_Csv: { |
| 861 | +#if defined(WIN32) || defined(_WIN32) | |
| 862 | + fflush(p->out); | |
| 863 | + _setmode(_fileno(p->out), _O_BINARY); | |
| 864 | +#endif | |
| 858 | 865 | if( p->cnt++==0 && p->showHeader ){ |
| 859 | 866 | for(i=0; i<nArg; i++){ |
| 860 | 867 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 861 | 868 | } |
| 862 | - fprintf(p->out,"\n"); | |
| 869 | + fprintf(p->out,"%s",p->newline); | |
| 863 | 870 | } |
| 864 | - if( azArg==0 ) break; | |
| 865 | - for(i=0; i<nArg; i++){ | |
| 866 | - output_csv(p, azArg[i], i<nArg-1); | |
| 871 | + if( azArg>0 ){ | |
| 872 | + for(i=0; i<nArg; i++){ | |
| 873 | + output_csv(p, azArg[i], i<nArg-1); | |
| 874 | + } | |
| 875 | + fprintf(p->out,"%s",p->newline); | |
| 867 | 876 | } |
| 868 | - fprintf(p->out,"\n"); | |
| 877 | +#if defined(WIN32) || defined(_WIN32) | |
| 878 | + fflush(p->out); | |
| 879 | + _setmode(_fileno(p->out), _O_TEXT); | |
| 880 | +#endif | |
| 869 | 881 | break; |
| 870 | 882 | } |
| 871 | 883 | case MODE_Insert: { |
| 872 | 884 | p->cnt++; |
| 873 | 885 | if( azArg==0 ) break; |
| @@ -1617,11 +1629,12 @@ | ||
| 1617 | 1629 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" |
| 1618 | 1630 | ".save FILE Write in-memory database into FILE\n" |
| 1619 | 1631 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1620 | 1632 | " If TABLE specified, only show tables matching\n" |
| 1621 | 1633 | " LIKE pattern TABLE.\n" |
| 1622 | - ".separator STRING Change separator used by output mode and .import\n" | |
| 1634 | + ".separator STRING ?NL? Change separator used by output mode and .import\n" | |
| 1635 | + " NL is the end-of-line mark for CSV\n" | |
| 1623 | 1636 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1624 | 1637 | ".show Show the current values for various settings\n" |
| 1625 | 1638 | ".stats on|off Turn stats on or off\n" |
| 1626 | 1639 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1627 | 1640 | ".tables ?TABLE? List names of tables\n" |
| @@ -1635,10 +1648,73 @@ | ||
| 1635 | 1648 | " Negative values right-justify\n" |
| 1636 | 1649 | ; |
| 1637 | 1650 | |
| 1638 | 1651 | /* Forward reference */ |
| 1639 | 1652 | static int process_input(struct callback_data *p, FILE *in); |
| 1653 | +/* | |
| 1654 | +** Implementation of the "readfile(X)" SQL function. The entire content | |
| 1655 | +** of the file named X is read and returned as a BLOB. NULL is returned | |
| 1656 | +** if the file does not exist or is unreadable. | |
| 1657 | +*/ | |
| 1658 | +static void readfileFunc( | |
| 1659 | + sqlite3_context *context, | |
| 1660 | + int argc, | |
| 1661 | + sqlite3_value **argv | |
| 1662 | +){ | |
| 1663 | + const char *zName; | |
| 1664 | + FILE *in; | |
| 1665 | + long nIn; | |
| 1666 | + void *pBuf; | |
| 1667 | + | |
| 1668 | + zName = (const char*)sqlite3_value_text(argv[0]); | |
| 1669 | + if( zName==0 ) return; | |
| 1670 | + in = fopen(zName, "rb"); | |
| 1671 | + if( in==0 ) return; | |
| 1672 | + fseek(in, 0, SEEK_END); | |
| 1673 | + nIn = ftell(in); | |
| 1674 | + rewind(in); | |
| 1675 | + pBuf = sqlite3_malloc( nIn ); | |
| 1676 | + if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ | |
| 1677 | + sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); | |
| 1678 | + }else{ | |
| 1679 | + sqlite3_free(pBuf); | |
| 1680 | + } | |
| 1681 | + fclose(in); | |
| 1682 | +} | |
| 1683 | + | |
| 1684 | +/* | |
| 1685 | +** Implementation of the "writefile(X,Y)" SQL function. The argument Y | |
| 1686 | +** is written into file X. The number of bytes written is returned. Or | |
| 1687 | +** NULL is returned if something goes wrong, such as being unable to open | |
| 1688 | +** file X for writing. | |
| 1689 | +*/ | |
| 1690 | +static void writefileFunc( | |
| 1691 | + sqlite3_context *context, | |
| 1692 | + int argc, | |
| 1693 | + sqlite3_value **argv | |
| 1694 | +){ | |
| 1695 | + FILE *out; | |
| 1696 | + const char *z; | |
| 1697 | + int n; | |
| 1698 | + sqlite3_int64 rc; | |
| 1699 | + const char *zFile; | |
| 1700 | + | |
| 1701 | + zFile = (const char*)sqlite3_value_text(argv[0]); | |
| 1702 | + if( zFile==0 ) return; | |
| 1703 | + out = fopen(zFile, "wb"); | |
| 1704 | + if( out==0 ) return; | |
| 1705 | + z = (const char*)sqlite3_value_blob(argv[1]); | |
| 1706 | + if( z==0 ){ | |
| 1707 | + n = 0; | |
| 1708 | + rc = 0; | |
| 1709 | + }else{ | |
| 1710 | + n = sqlite3_value_bytes(argv[1]); | |
| 1711 | + rc = fwrite(z, 1, n, out); | |
| 1712 | + } | |
| 1713 | + fclose(out); | |
| 1714 | + sqlite3_result_int64(context, rc); | |
| 1715 | +} | |
| 1640 | 1716 | |
| 1641 | 1717 | /* |
| 1642 | 1718 | ** Make sure the database is open. If it is not, then open it. If |
| 1643 | 1719 | ** the database fails to open, print an error message and exit. |
| 1644 | 1720 | */ |
| @@ -1658,10 +1734,14 @@ | ||
| 1658 | 1734 | exit(1); |
| 1659 | 1735 | } |
| 1660 | 1736 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1661 | 1737 | sqlite3_enable_load_extension(p->db, 1); |
| 1662 | 1738 | #endif |
| 1739 | + sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, | |
| 1740 | + readfileFunc, 0, 0); | |
| 1741 | + sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, | |
| 1742 | + writefileFunc, 0, 0); | |
| 1663 | 1743 | } |
| 1664 | 1744 | } |
| 1665 | 1745 | |
| 1666 | 1746 | /* |
| 1667 | 1747 | ** Do C-language style dequoting. |
| @@ -2414,10 +2494,11 @@ | ||
| 2414 | 2494 | }else |
| 2415 | 2495 | |
| 2416 | 2496 | if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ |
| 2417 | 2497 | struct callback_data data; |
| 2418 | 2498 | char *zErrMsg = 0; |
| 2499 | + int doStats = 0; | |
| 2419 | 2500 | if( nArg!=1 ){ |
| 2420 | 2501 | fprintf(stderr, "Usage: .fullschema\n"); |
| 2421 | 2502 | rc = 1; |
| 2422 | 2503 | goto meta_command_exit; |
| 2423 | 2504 | } |
| @@ -2432,25 +2513,37 @@ | ||
| 2432 | 2513 | " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
| 2433 | 2514 | "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |
| 2434 | 2515 | "ORDER BY rowid", |
| 2435 | 2516 | callback, &data, &zErrMsg |
| 2436 | 2517 | ); |
| 2437 | - sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", | |
| 2438 | - callback, &data, &zErrMsg); | |
| 2439 | - data.mode = MODE_Insert; | |
| 2440 | - data.zDestTable = "sqlite_stat1"; | |
| 2441 | - shell_exec(p->db, "SELECT * FROM sqlite_stat1", | |
| 2442 | - shell_callback, &data,&zErrMsg); | |
| 2443 | - data.zDestTable = "sqlite_stat3"; | |
| 2444 | - shell_exec(p->db, "SELECT * FROM sqlite_stat3", | |
| 2445 | - shell_callback, &data,&zErrMsg); | |
| 2446 | - data.zDestTable = "sqlite_stat4"; | |
| 2447 | - shell_exec(p->db, "SELECT * FROM sqlite_stat4", | |
| 2448 | - shell_callback, &data, &zErrMsg); | |
| 2449 | - data.mode = MODE_Semi; | |
| 2450 | - shell_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", | |
| 2451 | - shell_callback, &data, &zErrMsg); | |
| 2518 | + if( rc==SQLITE_OK ){ | |
| 2519 | + sqlite3_stmt *pStmt; | |
| 2520 | + rc = sqlite3_prepare_v2(p->db, | |
| 2521 | + "SELECT rowid FROM sqlite_master" | |
| 2522 | + " WHERE name GLOB 'sqlite_stat[134]'", | |
| 2523 | + -1, &pStmt, 0); | |
| 2524 | + doStats = sqlite3_step(pStmt)==SQLITE_ROW; | |
| 2525 | + sqlite3_finalize(pStmt); | |
| 2526 | + } | |
| 2527 | + if( doStats==0 ){ | |
| 2528 | + fprintf(p->out, "/* No STAT tables available */\n"); | |
| 2529 | + }else{ | |
| 2530 | + fprintf(p->out, "ANALYZE sqlite_master;\n"); | |
| 2531 | + sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", | |
| 2532 | + callback, &data, &zErrMsg); | |
| 2533 | + data.mode = MODE_Insert; | |
| 2534 | + data.zDestTable = "sqlite_stat1"; | |
| 2535 | + shell_exec(p->db, "SELECT * FROM sqlite_stat1", | |
| 2536 | + shell_callback, &data,&zErrMsg); | |
| 2537 | + data.zDestTable = "sqlite_stat3"; | |
| 2538 | + shell_exec(p->db, "SELECT * FROM sqlite_stat3", | |
| 2539 | + shell_callback, &data,&zErrMsg); | |
| 2540 | + data.zDestTable = "sqlite_stat4"; | |
| 2541 | + shell_exec(p->db, "SELECT * FROM sqlite_stat4", | |
| 2542 | + shell_callback, &data, &zErrMsg); | |
| 2543 | + fprintf(p->out, "ANALYZE sqlite_master;\n"); | |
| 2544 | + } | |
| 2452 | 2545 | }else |
| 2453 | 2546 | |
| 2454 | 2547 | if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ |
| 2455 | 2548 | if( nArg==2 ){ |
| 2456 | 2549 | p->showHeader = booleanValue(azArg[1]); |
| @@ -2736,10 +2829,11 @@ | ||
| 2736 | 2829 | p->mode = MODE_Tcl; |
| 2737 | 2830 | sqlite3_snprintf(sizeof(p->separator), p->separator, " "); |
| 2738 | 2831 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2739 | 2832 | p->mode = MODE_Csv; |
| 2740 | 2833 | sqlite3_snprintf(sizeof(p->separator), p->separator, ","); |
| 2834 | + sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n"); | |
| 2741 | 2835 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2742 | 2836 | p->mode = MODE_List; |
| 2743 | 2837 | sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); |
| 2744 | 2838 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2745 | 2839 | p->mode = MODE_Insert; |
| @@ -3014,17 +3108,20 @@ | ||
| 3014 | 3108 | } |
| 3015 | 3109 | }else |
| 3016 | 3110 | #endif |
| 3017 | 3111 | |
| 3018 | 3112 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3019 | - if( nArg==2 ){ | |
| 3020 | - sqlite3_snprintf(sizeof(p->separator), p->separator, | |
| 3021 | - "%.*s", (int)sizeof(p->separator)-1, azArg[1]); | |
| 3022 | - }else{ | |
| 3023 | - fprintf(stderr, "Usage: .separator STRING\n"); | |
| 3113 | + if( nArg<2 || nArg>3 ){ | |
| 3114 | + fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n"); | |
| 3024 | 3115 | rc = 1; |
| 3025 | 3116 | } |
| 3117 | + if( nArg>=2 ){ | |
| 3118 | + sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]); | |
| 3119 | + } | |
| 3120 | + if( nArg>=3 ){ | |
| 3121 | + sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]); | |
| 3122 | + } | |
| 3026 | 3123 | }else |
| 3027 | 3124 | |
| 3028 | 3125 | if( c=='s' |
| 3029 | 3126 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| 3030 | 3127 | ){ |
| @@ -3061,10 +3158,12 @@ | ||
| 3061 | 3158 | fprintf(p->out, "\n"); |
| 3062 | 3159 | fprintf(p->out,"%9.9s: %s\n","output", |
| 3063 | 3160 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3064 | 3161 | fprintf(p->out,"%9.9s: ", "separator"); |
| 3065 | 3162 | output_c_string(p->out, p->separator); |
| 3163 | + fprintf(p->out," "); | |
| 3164 | + output_c_string(p->out, p->newline); | |
| 3066 | 3165 | fprintf(p->out, "\n"); |
| 3067 | 3166 | fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3068 | 3167 | fprintf(p->out,"%9.9s: ","width"); |
| 3069 | 3168 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3070 | 3169 | fprintf(p->out,"%d ",p->colWidth[i]); |
| @@ -3677,10 +3776,11 @@ | ||
| 3677 | 3776 | " -list set output mode to 'list'\n" |
| 3678 | 3777 | " -mmap N default mmap size set to N\n" |
| 3679 | 3778 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3680 | 3779 | " -multiplex enable the multiplexor VFS\n" |
| 3681 | 3780 | #endif |
| 3781 | + " -newline SEP set newline character(s) for CSV\n" | |
| 3682 | 3782 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3683 | 3783 | " -separator SEP set output field separator. Default: '|'\n" |
| 3684 | 3784 | " -stats print memory stats before each finalize\n" |
| 3685 | 3785 | " -version show SQLite version\n" |
| 3686 | 3786 | " -vfs NAME use NAME as the default VFS\n" |
| @@ -3706,10 +3806,11 @@ | ||
| 3706 | 3806 | */ |
| 3707 | 3807 | static void main_init(struct callback_data *data) { |
| 3708 | 3808 | memset(data, 0, sizeof(*data)); |
| 3709 | 3809 | data->mode = MODE_List; |
| 3710 | 3810 | memcpy(data->separator,"|", 2); |
| 3811 | + memcpy(data->newline,"\r\n", 3); | |
| 3711 | 3812 | data->showHeader = 0; |
| 3712 | 3813 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3713 | 3814 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3714 | 3815 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 3715 | 3816 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| @@ -3798,10 +3899,11 @@ | ||
| 3798 | 3899 | return 1; |
| 3799 | 3900 | } |
| 3800 | 3901 | if( z[1]=='-' ) z++; |
| 3801 | 3902 | if( strcmp(z,"-separator")==0 |
| 3802 | 3903 | || strcmp(z,"-nullvalue")==0 |
| 3904 | + || strcmp(z,"-newline")==0 | |
| 3803 | 3905 | || strcmp(z,"-cmd")==0 |
| 3804 | 3906 | ){ |
| 3805 | 3907 | (void)cmdline_option_value(argc, argv, ++i); |
| 3806 | 3908 | }else if( strcmp(z,"-init")==0 ){ |
| 3807 | 3909 | zInitFile = cmdline_option_value(argc, argv, ++i); |
| @@ -3907,10 +4009,13 @@ | ||
| 3907 | 4009 | data.mode = MODE_Csv; |
| 3908 | 4010 | memcpy(data.separator,",",2); |
| 3909 | 4011 | }else if( strcmp(z,"-separator")==0 ){ |
| 3910 | 4012 | sqlite3_snprintf(sizeof(data.separator), data.separator, |
| 3911 | 4013 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4014 | + }else if( strcmp(z,"-newline")==0 ){ | |
| 4015 | + sqlite3_snprintf(sizeof(data.newline), data.newline, | |
| 4016 | + "%s",cmdline_option_value(argc,argv,++i)); | |
| 3912 | 4017 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 3913 | 4018 | sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, |
| 3914 | 4019 | "%s",cmdline_option_value(argc,argv,++i)); |
| 3915 | 4020 | }else if( strcmp(z,"-header")==0 ){ |
| 3916 | 4021 | data.showHeader = 1; |
| 3917 | 4022 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -62,10 +62,11 @@ | |
| 62 | # define stifle_history(X) |
| 63 | #endif |
| 64 | |
| 65 | #if defined(_WIN32) || defined(WIN32) |
| 66 | # include <io.h> |
| 67 | #define isatty(h) _isatty(h) |
| 68 | #ifndef access |
| 69 | # define access(f,m) _access((f),(m)) |
| 70 | #endif |
| 71 | #undef popen |
| @@ -456,10 +457,11 @@ | |
| 456 | int mode; /* An output mode setting */ |
| 457 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 458 | int showHeader; /* True to show column names in List or Column mode */ |
| 459 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 460 | char separator[20]; /* Separator character for MODE_List */ |
| 461 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 462 | int actualWidth[100]; /* Actual width of each column */ |
| 463 | char nullvalue[20]; /* The text to print when a NULL comes back from |
| 464 | ** the database */ |
| 465 | struct previous_mode_data explainPrev; |
| @@ -657,11 +659,12 @@ | |
| 657 | }; |
| 658 | |
| 659 | /* |
| 660 | ** Output a single term of CSV. Actually, p->separator is used for |
| 661 | ** the separator, which may or may not be a comma. p->nullvalue is |
| 662 | ** the null value. Strings are quoted if necessary. |
| 663 | */ |
| 664 | static void output_csv(struct callback_data *p, const char *z, int bSep){ |
| 665 | FILE *out = p->out; |
| 666 | if( z==0 ){ |
| 667 | fprintf(out,"%s",p->nullvalue); |
| @@ -853,21 +856,30 @@ | |
| 853 | } |
| 854 | fprintf(p->out,"\n"); |
| 855 | break; |
| 856 | } |
| 857 | case MODE_Csv: { |
| 858 | if( p->cnt++==0 && p->showHeader ){ |
| 859 | for(i=0; i<nArg; i++){ |
| 860 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 861 | } |
| 862 | fprintf(p->out,"\n"); |
| 863 | } |
| 864 | if( azArg==0 ) break; |
| 865 | for(i=0; i<nArg; i++){ |
| 866 | output_csv(p, azArg[i], i<nArg-1); |
| 867 | } |
| 868 | fprintf(p->out,"\n"); |
| 869 | break; |
| 870 | } |
| 871 | case MODE_Insert: { |
| 872 | p->cnt++; |
| 873 | if( azArg==0 ) break; |
| @@ -1617,11 +1629,12 @@ | |
| 1617 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" |
| 1618 | ".save FILE Write in-memory database into FILE\n" |
| 1619 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1620 | " If TABLE specified, only show tables matching\n" |
| 1621 | " LIKE pattern TABLE.\n" |
| 1622 | ".separator STRING Change separator used by output mode and .import\n" |
| 1623 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1624 | ".show Show the current values for various settings\n" |
| 1625 | ".stats on|off Turn stats on or off\n" |
| 1626 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1627 | ".tables ?TABLE? List names of tables\n" |
| @@ -1635,10 +1648,73 @@ | |
| 1635 | " Negative values right-justify\n" |
| 1636 | ; |
| 1637 | |
| 1638 | /* Forward reference */ |
| 1639 | static int process_input(struct callback_data *p, FILE *in); |
| 1640 | |
| 1641 | /* |
| 1642 | ** Make sure the database is open. If it is not, then open it. If |
| 1643 | ** the database fails to open, print an error message and exit. |
| 1644 | */ |
| @@ -1658,10 +1734,14 @@ | |
| 1658 | exit(1); |
| 1659 | } |
| 1660 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1661 | sqlite3_enable_load_extension(p->db, 1); |
| 1662 | #endif |
| 1663 | } |
| 1664 | } |
| 1665 | |
| 1666 | /* |
| 1667 | ** Do C-language style dequoting. |
| @@ -2414,10 +2494,11 @@ | |
| 2414 | }else |
| 2415 | |
| 2416 | if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ |
| 2417 | struct callback_data data; |
| 2418 | char *zErrMsg = 0; |
| 2419 | if( nArg!=1 ){ |
| 2420 | fprintf(stderr, "Usage: .fullschema\n"); |
| 2421 | rc = 1; |
| 2422 | goto meta_command_exit; |
| 2423 | } |
| @@ -2432,25 +2513,37 @@ | |
| 2432 | " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
| 2433 | "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |
| 2434 | "ORDER BY rowid", |
| 2435 | callback, &data, &zErrMsg |
| 2436 | ); |
| 2437 | sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", |
| 2438 | callback, &data, &zErrMsg); |
| 2439 | data.mode = MODE_Insert; |
| 2440 | data.zDestTable = "sqlite_stat1"; |
| 2441 | shell_exec(p->db, "SELECT * FROM sqlite_stat1", |
| 2442 | shell_callback, &data,&zErrMsg); |
| 2443 | data.zDestTable = "sqlite_stat3"; |
| 2444 | shell_exec(p->db, "SELECT * FROM sqlite_stat3", |
| 2445 | shell_callback, &data,&zErrMsg); |
| 2446 | data.zDestTable = "sqlite_stat4"; |
| 2447 | shell_exec(p->db, "SELECT * FROM sqlite_stat4", |
| 2448 | shell_callback, &data, &zErrMsg); |
| 2449 | data.mode = MODE_Semi; |
| 2450 | shell_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", |
| 2451 | shell_callback, &data, &zErrMsg); |
| 2452 | }else |
| 2453 | |
| 2454 | if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ |
| 2455 | if( nArg==2 ){ |
| 2456 | p->showHeader = booleanValue(azArg[1]); |
| @@ -2736,10 +2829,11 @@ | |
| 2736 | p->mode = MODE_Tcl; |
| 2737 | sqlite3_snprintf(sizeof(p->separator), p->separator, " "); |
| 2738 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2739 | p->mode = MODE_Csv; |
| 2740 | sqlite3_snprintf(sizeof(p->separator), p->separator, ","); |
| 2741 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2742 | p->mode = MODE_List; |
| 2743 | sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); |
| 2744 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2745 | p->mode = MODE_Insert; |
| @@ -3014,17 +3108,20 @@ | |
| 3014 | } |
| 3015 | }else |
| 3016 | #endif |
| 3017 | |
| 3018 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3019 | if( nArg==2 ){ |
| 3020 | sqlite3_snprintf(sizeof(p->separator), p->separator, |
| 3021 | "%.*s", (int)sizeof(p->separator)-1, azArg[1]); |
| 3022 | }else{ |
| 3023 | fprintf(stderr, "Usage: .separator STRING\n"); |
| 3024 | rc = 1; |
| 3025 | } |
| 3026 | }else |
| 3027 | |
| 3028 | if( c=='s' |
| 3029 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| 3030 | ){ |
| @@ -3061,10 +3158,12 @@ | |
| 3061 | fprintf(p->out, "\n"); |
| 3062 | fprintf(p->out,"%9.9s: %s\n","output", |
| 3063 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3064 | fprintf(p->out,"%9.9s: ", "separator"); |
| 3065 | output_c_string(p->out, p->separator); |
| 3066 | fprintf(p->out, "\n"); |
| 3067 | fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3068 | fprintf(p->out,"%9.9s: ","width"); |
| 3069 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3070 | fprintf(p->out,"%d ",p->colWidth[i]); |
| @@ -3677,10 +3776,11 @@ | |
| 3677 | " -list set output mode to 'list'\n" |
| 3678 | " -mmap N default mmap size set to N\n" |
| 3679 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3680 | " -multiplex enable the multiplexor VFS\n" |
| 3681 | #endif |
| 3682 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3683 | " -separator SEP set output field separator. Default: '|'\n" |
| 3684 | " -stats print memory stats before each finalize\n" |
| 3685 | " -version show SQLite version\n" |
| 3686 | " -vfs NAME use NAME as the default VFS\n" |
| @@ -3706,10 +3806,11 @@ | |
| 3706 | */ |
| 3707 | static void main_init(struct callback_data *data) { |
| 3708 | memset(data, 0, sizeof(*data)); |
| 3709 | data->mode = MODE_List; |
| 3710 | memcpy(data->separator,"|", 2); |
| 3711 | data->showHeader = 0; |
| 3712 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3713 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3714 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 3715 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| @@ -3798,10 +3899,11 @@ | |
| 3798 | return 1; |
| 3799 | } |
| 3800 | if( z[1]=='-' ) z++; |
| 3801 | if( strcmp(z,"-separator")==0 |
| 3802 | || strcmp(z,"-nullvalue")==0 |
| 3803 | || strcmp(z,"-cmd")==0 |
| 3804 | ){ |
| 3805 | (void)cmdline_option_value(argc, argv, ++i); |
| 3806 | }else if( strcmp(z,"-init")==0 ){ |
| 3807 | zInitFile = cmdline_option_value(argc, argv, ++i); |
| @@ -3907,10 +4009,13 @@ | |
| 3907 | data.mode = MODE_Csv; |
| 3908 | memcpy(data.separator,",",2); |
| 3909 | }else if( strcmp(z,"-separator")==0 ){ |
| 3910 | sqlite3_snprintf(sizeof(data.separator), data.separator, |
| 3911 | "%s",cmdline_option_value(argc,argv,++i)); |
| 3912 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 3913 | sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, |
| 3914 | "%s",cmdline_option_value(argc,argv,++i)); |
| 3915 | }else if( strcmp(z,"-header")==0 ){ |
| 3916 | data.showHeader = 1; |
| 3917 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -62,10 +62,11 @@ | |
| 62 | # define stifle_history(X) |
| 63 | #endif |
| 64 | |
| 65 | #if defined(_WIN32) || defined(WIN32) |
| 66 | # include <io.h> |
| 67 | # include <fcntl.h> |
| 68 | #define isatty(h) _isatty(h) |
| 69 | #ifndef access |
| 70 | # define access(f,m) _access((f),(m)) |
| 71 | #endif |
| 72 | #undef popen |
| @@ -456,10 +457,11 @@ | |
| 457 | int mode; /* An output mode setting */ |
| 458 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 459 | int showHeader; /* True to show column names in List or Column mode */ |
| 460 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 461 | char separator[20]; /* Separator character for MODE_List */ |
| 462 | char newline[20]; /* Record separator in MODE_Csv */ |
| 463 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 464 | int actualWidth[100]; /* Actual width of each column */ |
| 465 | char nullvalue[20]; /* The text to print when a NULL comes back from |
| 466 | ** the database */ |
| 467 | struct previous_mode_data explainPrev; |
| @@ -657,11 +659,12 @@ | |
| 659 | }; |
| 660 | |
| 661 | /* |
| 662 | ** Output a single term of CSV. Actually, p->separator is used for |
| 663 | ** the separator, which may or may not be a comma. p->nullvalue is |
| 664 | ** the null value. Strings are quoted if necessary. The separator |
| 665 | ** is only issued if bSep is true. |
| 666 | */ |
| 667 | static void output_csv(struct callback_data *p, const char *z, int bSep){ |
| 668 | FILE *out = p->out; |
| 669 | if( z==0 ){ |
| 670 | fprintf(out,"%s",p->nullvalue); |
| @@ -853,21 +856,30 @@ | |
| 856 | } |
| 857 | fprintf(p->out,"\n"); |
| 858 | break; |
| 859 | } |
| 860 | case MODE_Csv: { |
| 861 | #if defined(WIN32) || defined(_WIN32) |
| 862 | fflush(p->out); |
| 863 | _setmode(_fileno(p->out), _O_BINARY); |
| 864 | #endif |
| 865 | if( p->cnt++==0 && p->showHeader ){ |
| 866 | for(i=0; i<nArg; i++){ |
| 867 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 868 | } |
| 869 | fprintf(p->out,"%s",p->newline); |
| 870 | } |
| 871 | if( azArg>0 ){ |
| 872 | for(i=0; i<nArg; i++){ |
| 873 | output_csv(p, azArg[i], i<nArg-1); |
| 874 | } |
| 875 | fprintf(p->out,"%s",p->newline); |
| 876 | } |
| 877 | #if defined(WIN32) || defined(_WIN32) |
| 878 | fflush(p->out); |
| 879 | _setmode(_fileno(p->out), _O_TEXT); |
| 880 | #endif |
| 881 | break; |
| 882 | } |
| 883 | case MODE_Insert: { |
| 884 | p->cnt++; |
| 885 | if( azArg==0 ) break; |
| @@ -1617,11 +1629,12 @@ | |
| 1629 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" |
| 1630 | ".save FILE Write in-memory database into FILE\n" |
| 1631 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1632 | " If TABLE specified, only show tables matching\n" |
| 1633 | " LIKE pattern TABLE.\n" |
| 1634 | ".separator STRING ?NL? Change separator used by output mode and .import\n" |
| 1635 | " NL is the end-of-line mark for CSV\n" |
| 1636 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1637 | ".show Show the current values for various settings\n" |
| 1638 | ".stats on|off Turn stats on or off\n" |
| 1639 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1640 | ".tables ?TABLE? List names of tables\n" |
| @@ -1635,10 +1648,73 @@ | |
| 1648 | " Negative values right-justify\n" |
| 1649 | ; |
| 1650 | |
| 1651 | /* Forward reference */ |
| 1652 | static int process_input(struct callback_data *p, FILE *in); |
| 1653 | /* |
| 1654 | ** Implementation of the "readfile(X)" SQL function. The entire content |
| 1655 | ** of the file named X is read and returned as a BLOB. NULL is returned |
| 1656 | ** if the file does not exist or is unreadable. |
| 1657 | */ |
| 1658 | static void readfileFunc( |
| 1659 | sqlite3_context *context, |
| 1660 | int argc, |
| 1661 | sqlite3_value **argv |
| 1662 | ){ |
| 1663 | const char *zName; |
| 1664 | FILE *in; |
| 1665 | long nIn; |
| 1666 | void *pBuf; |
| 1667 | |
| 1668 | zName = (const char*)sqlite3_value_text(argv[0]); |
| 1669 | if( zName==0 ) return; |
| 1670 | in = fopen(zName, "rb"); |
| 1671 | if( in==0 ) return; |
| 1672 | fseek(in, 0, SEEK_END); |
| 1673 | nIn = ftell(in); |
| 1674 | rewind(in); |
| 1675 | pBuf = sqlite3_malloc( nIn ); |
| 1676 | if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ |
| 1677 | sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); |
| 1678 | }else{ |
| 1679 | sqlite3_free(pBuf); |
| 1680 | } |
| 1681 | fclose(in); |
| 1682 | } |
| 1683 | |
| 1684 | /* |
| 1685 | ** Implementation of the "writefile(X,Y)" SQL function. The argument Y |
| 1686 | ** is written into file X. The number of bytes written is returned. Or |
| 1687 | ** NULL is returned if something goes wrong, such as being unable to open |
| 1688 | ** file X for writing. |
| 1689 | */ |
| 1690 | static void writefileFunc( |
| 1691 | sqlite3_context *context, |
| 1692 | int argc, |
| 1693 | sqlite3_value **argv |
| 1694 | ){ |
| 1695 | FILE *out; |
| 1696 | const char *z; |
| 1697 | int n; |
| 1698 | sqlite3_int64 rc; |
| 1699 | const char *zFile; |
| 1700 | |
| 1701 | zFile = (const char*)sqlite3_value_text(argv[0]); |
| 1702 | if( zFile==0 ) return; |
| 1703 | out = fopen(zFile, "wb"); |
| 1704 | if( out==0 ) return; |
| 1705 | z = (const char*)sqlite3_value_blob(argv[1]); |
| 1706 | if( z==0 ){ |
| 1707 | n = 0; |
| 1708 | rc = 0; |
| 1709 | }else{ |
| 1710 | n = sqlite3_value_bytes(argv[1]); |
| 1711 | rc = fwrite(z, 1, n, out); |
| 1712 | } |
| 1713 | fclose(out); |
| 1714 | sqlite3_result_int64(context, rc); |
| 1715 | } |
| 1716 | |
| 1717 | /* |
| 1718 | ** Make sure the database is open. If it is not, then open it. If |
| 1719 | ** the database fails to open, print an error message and exit. |
| 1720 | */ |
| @@ -1658,10 +1734,14 @@ | |
| 1734 | exit(1); |
| 1735 | } |
| 1736 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1737 | sqlite3_enable_load_extension(p->db, 1); |
| 1738 | #endif |
| 1739 | sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, |
| 1740 | readfileFunc, 0, 0); |
| 1741 | sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, |
| 1742 | writefileFunc, 0, 0); |
| 1743 | } |
| 1744 | } |
| 1745 | |
| 1746 | /* |
| 1747 | ** Do C-language style dequoting. |
| @@ -2414,10 +2494,11 @@ | |
| 2494 | }else |
| 2495 | |
| 2496 | if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ |
| 2497 | struct callback_data data; |
| 2498 | char *zErrMsg = 0; |
| 2499 | int doStats = 0; |
| 2500 | if( nArg!=1 ){ |
| 2501 | fprintf(stderr, "Usage: .fullschema\n"); |
| 2502 | rc = 1; |
| 2503 | goto meta_command_exit; |
| 2504 | } |
| @@ -2432,25 +2513,37 @@ | |
| 2513 | " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
| 2514 | "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |
| 2515 | "ORDER BY rowid", |
| 2516 | callback, &data, &zErrMsg |
| 2517 | ); |
| 2518 | if( rc==SQLITE_OK ){ |
| 2519 | sqlite3_stmt *pStmt; |
| 2520 | rc = sqlite3_prepare_v2(p->db, |
| 2521 | "SELECT rowid FROM sqlite_master" |
| 2522 | " WHERE name GLOB 'sqlite_stat[134]'", |
| 2523 | -1, &pStmt, 0); |
| 2524 | doStats = sqlite3_step(pStmt)==SQLITE_ROW; |
| 2525 | sqlite3_finalize(pStmt); |
| 2526 | } |
| 2527 | if( doStats==0 ){ |
| 2528 | fprintf(p->out, "/* No STAT tables available */\n"); |
| 2529 | }else{ |
| 2530 | fprintf(p->out, "ANALYZE sqlite_master;\n"); |
| 2531 | sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", |
| 2532 | callback, &data, &zErrMsg); |
| 2533 | data.mode = MODE_Insert; |
| 2534 | data.zDestTable = "sqlite_stat1"; |
| 2535 | shell_exec(p->db, "SELECT * FROM sqlite_stat1", |
| 2536 | shell_callback, &data,&zErrMsg); |
| 2537 | data.zDestTable = "sqlite_stat3"; |
| 2538 | shell_exec(p->db, "SELECT * FROM sqlite_stat3", |
| 2539 | shell_callback, &data,&zErrMsg); |
| 2540 | data.zDestTable = "sqlite_stat4"; |
| 2541 | shell_exec(p->db, "SELECT * FROM sqlite_stat4", |
| 2542 | shell_callback, &data, &zErrMsg); |
| 2543 | fprintf(p->out, "ANALYZE sqlite_master;\n"); |
| 2544 | } |
| 2545 | }else |
| 2546 | |
| 2547 | if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ |
| 2548 | if( nArg==2 ){ |
| 2549 | p->showHeader = booleanValue(azArg[1]); |
| @@ -2736,10 +2829,11 @@ | |
| 2829 | p->mode = MODE_Tcl; |
| 2830 | sqlite3_snprintf(sizeof(p->separator), p->separator, " "); |
| 2831 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2832 | p->mode = MODE_Csv; |
| 2833 | sqlite3_snprintf(sizeof(p->separator), p->separator, ","); |
| 2834 | sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n"); |
| 2835 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2836 | p->mode = MODE_List; |
| 2837 | sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); |
| 2838 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2839 | p->mode = MODE_Insert; |
| @@ -3014,17 +3108,20 @@ | |
| 3108 | } |
| 3109 | }else |
| 3110 | #endif |
| 3111 | |
| 3112 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3113 | if( nArg<2 || nArg>3 ){ |
| 3114 | fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n"); |
| 3115 | rc = 1; |
| 3116 | } |
| 3117 | if( nArg>=2 ){ |
| 3118 | sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]); |
| 3119 | } |
| 3120 | if( nArg>=3 ){ |
| 3121 | sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]); |
| 3122 | } |
| 3123 | }else |
| 3124 | |
| 3125 | if( c=='s' |
| 3126 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| 3127 | ){ |
| @@ -3061,10 +3158,12 @@ | |
| 3158 | fprintf(p->out, "\n"); |
| 3159 | fprintf(p->out,"%9.9s: %s\n","output", |
| 3160 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3161 | fprintf(p->out,"%9.9s: ", "separator"); |
| 3162 | output_c_string(p->out, p->separator); |
| 3163 | fprintf(p->out," "); |
| 3164 | output_c_string(p->out, p->newline); |
| 3165 | fprintf(p->out, "\n"); |
| 3166 | fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3167 | fprintf(p->out,"%9.9s: ","width"); |
| 3168 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3169 | fprintf(p->out,"%d ",p->colWidth[i]); |
| @@ -3677,10 +3776,11 @@ | |
| 3776 | " -list set output mode to 'list'\n" |
| 3777 | " -mmap N default mmap size set to N\n" |
| 3778 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3779 | " -multiplex enable the multiplexor VFS\n" |
| 3780 | #endif |
| 3781 | " -newline SEP set newline character(s) for CSV\n" |
| 3782 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3783 | " -separator SEP set output field separator. Default: '|'\n" |
| 3784 | " -stats print memory stats before each finalize\n" |
| 3785 | " -version show SQLite version\n" |
| 3786 | " -vfs NAME use NAME as the default VFS\n" |
| @@ -3706,10 +3806,11 @@ | |
| 3806 | */ |
| 3807 | static void main_init(struct callback_data *data) { |
| 3808 | memset(data, 0, sizeof(*data)); |
| 3809 | data->mode = MODE_List; |
| 3810 | memcpy(data->separator,"|", 2); |
| 3811 | memcpy(data->newline,"\r\n", 3); |
| 3812 | data->showHeader = 0; |
| 3813 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3814 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3815 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 3816 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| @@ -3798,10 +3899,11 @@ | |
| 3899 | return 1; |
| 3900 | } |
| 3901 | if( z[1]=='-' ) z++; |
| 3902 | if( strcmp(z,"-separator")==0 |
| 3903 | || strcmp(z,"-nullvalue")==0 |
| 3904 | || strcmp(z,"-newline")==0 |
| 3905 | || strcmp(z,"-cmd")==0 |
| 3906 | ){ |
| 3907 | (void)cmdline_option_value(argc, argv, ++i); |
| 3908 | }else if( strcmp(z,"-init")==0 ){ |
| 3909 | zInitFile = cmdline_option_value(argc, argv, ++i); |
| @@ -3907,10 +4009,13 @@ | |
| 4009 | data.mode = MODE_Csv; |
| 4010 | memcpy(data.separator,",",2); |
| 4011 | }else if( strcmp(z,"-separator")==0 ){ |
| 4012 | sqlite3_snprintf(sizeof(data.separator), data.separator, |
| 4013 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4014 | }else if( strcmp(z,"-newline")==0 ){ |
| 4015 | sqlite3_snprintf(sizeof(data.newline), data.newline, |
| 4016 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4017 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4018 | sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, |
| 4019 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4020 | }else if( strcmp(z,"-header")==0 ){ |
| 4021 | data.showHeader = 1; |
| 4022 |
+1063
-476
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -222,11 +222,11 @@ | ||
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | -#define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -2150,31 +2150,37 @@ | ||
| 2150 | 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | 2151 | |
| 2152 | 2152 | /* |
| 2153 | 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | 2154 | ** |
| 2155 | -** ^This routine sets a callback function that might be invoked whenever | |
| 2156 | -** an attempt is made to open a database table that another thread | |
| 2157 | -** or process has locked. | |
| 2155 | +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X | |
| 2156 | +** that might be invoked with argument P whenever | |
| 2157 | +** an attempt is made to access a database table associated with | |
| 2158 | +** [database connection] D when another thread | |
| 2159 | +** or process has the table locked. | |
| 2160 | +** The sqlite3_busy_handler() interface is used to implement | |
| 2161 | +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. | |
| 2158 | 2162 | ** |
| 2159 | 2163 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2160 | 2164 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2161 | 2165 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2162 | 2166 | ** |
| 2163 | 2167 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2164 | 2168 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2165 | 2169 | ** the busy handler callback is the number of times that the busy handler has |
| 2166 | -** been invoked for this locking event. ^If the | |
| 2170 | +** been invoked for the same locking event. ^If the | |
| 2167 | 2171 | ** busy callback returns 0, then no additional attempts are made to |
| 2168 | -** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. | |
| 2172 | +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned | |
| 2173 | +** to the application. | |
| 2169 | 2174 | ** ^If the callback returns non-zero, then another attempt |
| 2170 | -** is made to open the database for reading and the cycle repeats. | |
| 2175 | +** is made to access the database and the cycle repeats. | |
| 2171 | 2176 | ** |
| 2172 | 2177 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2173 | 2178 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2174 | 2179 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2175 | -** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. | |
| 2180 | +** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the | |
| 2181 | +** busy handler. | |
| 2176 | 2182 | ** Consider a scenario where one process is holding a read lock that |
| 2177 | 2183 | ** it is trying to promote to a reserved lock and |
| 2178 | 2184 | ** a second process is holding a reserved lock that it is trying |
| 2179 | 2185 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2180 | 2186 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | ||
| 2202 | 2208 | ** this is important. |
| 2203 | 2209 | ** |
| 2204 | 2210 | ** ^(There can only be a single busy handler defined for each |
| 2205 | 2211 | ** [database connection]. Setting a new busy handler clears any |
| 2206 | 2212 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2207 | -** will also set or clear the busy handler. | |
| 2213 | +** or evaluating [PRAGMA busy_timeout=N] will change the | |
| 2214 | +** busy handler and thus clear any previously set busy handler. | |
| 2208 | 2215 | ** |
| 2209 | 2216 | ** The busy callback should not take any actions which modify the |
| 2210 | -** database connection that invoked the busy handler. Any such actions | |
| 2217 | +** database connection that invoked the busy handler. In other words, | |
| 2218 | +** the busy handler is not reentrant. Any such actions | |
| 2211 | 2219 | ** result in undefined behavior. |
| 2212 | 2220 | ** |
| 2213 | 2221 | ** A busy handler must not close the database connection |
| 2214 | 2222 | ** or [prepared statement] that invoked the busy handler. |
| 2215 | 2223 | */ |
| @@ -2230,10 +2238,12 @@ | ||
| 2230 | 2238 | ** |
| 2231 | 2239 | ** ^(There can only be a single busy handler for a particular |
| 2232 | 2240 | ** [database connection] any any given moment. If another busy handler |
| 2233 | 2241 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2234 | 2242 | ** this routine, that other busy handler is cleared.)^ |
| 2243 | +** | |
| 2244 | +** See also: [PRAGMA busy_timeout] | |
| 2235 | 2245 | */ |
| 2236 | 2246 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2237 | 2247 | |
| 2238 | 2248 | /* |
| 2239 | 2249 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | ||
| 4818 | 4828 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4819 | 4829 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4820 | 4830 | ** will be placed in that directory.)^ ^If this variable |
| 4821 | 4831 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4822 | 4832 | ** temporary file directory. |
| 4833 | +** | |
| 4834 | +** Applications are strongly discouraged from using this global variable. | |
| 4835 | +** It is required to set a temporary folder on Windows Runtime (WinRT). | |
| 4836 | +** But for all other platforms, it is highly recommended that applications | |
| 4837 | +** neither read nor write this variable. This global variable is a relic | |
| 4838 | +** that exists for backwards compatibility of legacy applications and should | |
| 4839 | +** be avoided in new projects. | |
| 4823 | 4840 | ** |
| 4824 | 4841 | ** It is not safe to read or modify this variable in more than one |
| 4825 | 4842 | ** thread at a time. It is not safe to read or modify this variable |
| 4826 | 4843 | ** if a [database connection] is being used at the same time in a separate |
| 4827 | 4844 | ** thread. |
| @@ -4837,10 +4854,15 @@ | ||
| 4837 | 4854 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4838 | 4855 | ** using [sqlite3_free]. |
| 4839 | 4856 | ** Hence, if this variable is modified directly, either it should be |
| 4840 | 4857 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4841 | 4858 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4859 | +** Except when requested by the [temp_store_directory pragma], SQLite | |
| 4860 | +** does not free the memory that sqlite3_temp_directory points to. If | |
| 4861 | +** the application wants that memory to be freed, it must do | |
| 4862 | +** so itself, taking care to only do so after all [database connection] | |
| 4863 | +** objects have been destroyed. | |
| 4842 | 4864 | ** |
| 4843 | 4865 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4844 | 4866 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4845 | 4867 | ** features that require the use of temporary files may fail. Here is an |
| 4846 | 4868 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | ||
| 5971 | 5993 | ** <ul> |
| 5972 | 5994 | ** <li> SQLITE_MUTEX_FAST |
| 5973 | 5995 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5974 | 5996 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5975 | 5997 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5976 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 5998 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 5977 | 5999 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5978 | 6000 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5979 | -** <li> SQLITE_MUTEX_STATIC_LRU2 | |
| 6001 | +** <li> SQLITE_MUTEX_STATIC_PMEM | |
| 6002 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 6003 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 5980 | 6004 | ** </ul>)^ |
| 5981 | 6005 | ** |
| 5982 | 6006 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5983 | 6007 | ** cause sqlite3_mutex_alloc() to create |
| 5984 | 6008 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | ||
| 6178 | 6202 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6179 | 6203 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6180 | 6204 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6181 | 6205 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6182 | 6206 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6207 | +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ | |
| 6208 | +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ | |
| 6209 | +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ | |
| 6183 | 6210 | |
| 6184 | 6211 | /* |
| 6185 | 6212 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6186 | 6213 | ** |
| 6187 | 6214 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | ||
| 6273 | 6300 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6274 | 6301 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6275 | 6302 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6276 | 6303 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6277 | 6304 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6278 | -#define SQLITE_TESTCTRL_LAST 22 | |
| 6305 | +#define SQLITE_TESTCTRL_ISINIT 23 | |
| 6306 | +#define SQLITE_TESTCTRL_LAST 23 | |
| 6279 | 6307 | |
| 6280 | 6308 | /* |
| 6281 | 6309 | ** CAPI3REF: SQLite Runtime Status |
| 6282 | 6310 | ** |
| 6283 | 6311 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | ||
| 7256 | 7284 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7257 | 7285 | ** configured by this function. |
| 7258 | 7286 | ** |
| 7259 | 7287 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7260 | 7288 | ** from SQL. |
| 7289 | +** | |
| 7290 | +** ^Checkpoints initiated by this mechanism are | |
| 7291 | +** [sqlite3_wal_checkpoint_v2|PASSIVE]. | |
| 7261 | 7292 | ** |
| 7262 | 7293 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7263 | 7294 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7264 | 7295 | ** pages. The use of this interface |
| 7265 | 7296 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | ||
| 7273 | 7304 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7274 | 7305 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7275 | 7306 | ** empty string, then a checkpoint is run on all databases of |
| 7276 | 7307 | ** connection D. ^If the database connection D is not in |
| 7277 | 7308 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7309 | +** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a | |
| 7310 | +** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. | |
| 7311 | +** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL | |
| 7312 | +** or RESET checkpoint. | |
| 7278 | 7313 | ** |
| 7279 | 7314 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7280 | 7315 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7281 | 7316 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7282 | 7317 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | ||
| 7295 | 7330 | ** <dl> |
| 7296 | 7331 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7297 | 7332 | ** Checkpoint as many frames as possible without waiting for any database |
| 7298 | 7333 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7299 | 7334 | ** are checkpointed. This mode is the same as calling |
| 7300 | -** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. | |
| 7335 | +** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] | |
| 7336 | +** is never invoked. | |
| 7301 | 7337 | ** |
| 7302 | 7338 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7303 | -** This mode blocks (calls the busy-handler callback) until there is no | |
| 7339 | +** This mode blocks (it invokes the | |
| 7340 | +** [sqlite3_busy_handler|busy-handler callback]) until there is no | |
| 7304 | 7341 | ** database writer and all readers are reading from the most recent database |
| 7305 | 7342 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7306 | 7343 | ** database file. This call blocks database writers while it is running, |
| 7307 | 7344 | ** but not database readers. |
| 7308 | 7345 | ** |
| 7309 | 7346 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7310 | 7347 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7311 | -** checkpointing the log file it blocks (calls the busy-handler callback) | |
| 7348 | +** checkpointing the log file it blocks (calls the | |
| 7349 | +** [sqlite3_busy_handler|busy-handler callback]) | |
| 7312 | 7350 | ** until all readers are reading from the database file only. This ensures |
| 7313 | 7351 | ** that the next client to write to the database file restarts the log file |
| 7314 | 7352 | ** from the beginning. This call blocks database writers while it is running, |
| 7315 | 7353 | ** but not database readers. |
| 7316 | 7354 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | ||
| 9285 | 9323 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9286 | 9324 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9287 | 9325 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9288 | 9326 | #define OP_ReadCookie 50 |
| 9289 | 9327 | #define OP_SetCookie 51 |
| 9290 | -#define OP_OpenRead 52 /* synopsis: root=P2 iDb=P3 */ | |
| 9291 | -#define OP_OpenWrite 53 /* synopsis: root=P2 iDb=P3 */ | |
| 9292 | -#define OP_OpenAutoindex 54 /* synopsis: nColumn=P2 */ | |
| 9293 | -#define OP_OpenEphemeral 55 /* synopsis: nColumn=P2 */ | |
| 9294 | -#define OP_SorterOpen 56 | |
| 9295 | -#define OP_OpenPseudo 57 /* synopsis: P3 columns in r[P2] */ | |
| 9296 | -#define OP_Close 58 | |
| 9297 | -#define OP_SeekLT 59 | |
| 9298 | -#define OP_SeekLE 60 | |
| 9299 | -#define OP_SeekGE 61 | |
| 9300 | -#define OP_SeekGT 62 | |
| 9301 | -#define OP_Seek 63 /* synopsis: intkey=r[P2] */ | |
| 9302 | -#define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ | |
| 9303 | -#define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ | |
| 9304 | -#define OP_Found 66 /* synopsis: key=r[P3@P4] */ | |
| 9305 | -#define OP_NotExists 67 /* synopsis: intkey=r[P3] */ | |
| 9306 | -#define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ | |
| 9307 | -#define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ | |
| 9308 | -#define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ | |
| 9328 | +#define OP_ReopenIdx 52 /* synopsis: root=P2 iDb=P3 */ | |
| 9329 | +#define OP_OpenRead 53 /* synopsis: root=P2 iDb=P3 */ | |
| 9330 | +#define OP_OpenWrite 54 /* synopsis: root=P2 iDb=P3 */ | |
| 9331 | +#define OP_OpenAutoindex 55 /* synopsis: nColumn=P2 */ | |
| 9332 | +#define OP_OpenEphemeral 56 /* synopsis: nColumn=P2 */ | |
| 9333 | +#define OP_SorterOpen 57 | |
| 9334 | +#define OP_OpenPseudo 58 /* synopsis: P3 columns in r[P2] */ | |
| 9335 | +#define OP_Close 59 | |
| 9336 | +#define OP_SeekLT 60 /* synopsis: key=r[P3@P4] */ | |
| 9337 | +#define OP_SeekLE 61 /* synopsis: key=r[P3@P4] */ | |
| 9338 | +#define OP_SeekGE 62 /* synopsis: key=r[P3@P4] */ | |
| 9339 | +#define OP_SeekGT 63 /* synopsis: key=r[P3@P4] */ | |
| 9340 | +#define OP_Seek 64 /* synopsis: intkey=r[P2] */ | |
| 9341 | +#define OP_NoConflict 65 /* synopsis: key=r[P3@P4] */ | |
| 9342 | +#define OP_NotFound 66 /* synopsis: key=r[P3@P4] */ | |
| 9343 | +#define OP_Found 67 /* synopsis: key=r[P3@P4] */ | |
| 9344 | +#define OP_NotExists 68 /* synopsis: intkey=r[P3] */ | |
| 9345 | +#define OP_Sequence 69 /* synopsis: r[P2]=cursor[P1].ctr++ */ | |
| 9346 | +#define OP_NewRowid 70 /* synopsis: r[P2]=rowid */ | |
| 9309 | 9347 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9310 | 9348 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9311 | -#define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ | |
| 9312 | -#define OP_Delete 74 | |
| 9313 | -#define OP_ResetCount 75 | |
| 9349 | +#define OP_Insert 73 /* synopsis: intkey=r[P3] data=r[P2] */ | |
| 9350 | +#define OP_InsertInt 74 /* synopsis: intkey=P3 data=r[P2] */ | |
| 9351 | +#define OP_Delete 75 | |
| 9314 | 9352 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9315 | 9353 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9316 | 9354 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9317 | 9355 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9318 | 9356 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9319 | 9357 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9320 | 9358 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9321 | 9359 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9322 | -#define OP_SorterCompare 84 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ | |
| 9360 | +#define OP_ResetCount 84 | |
| 9323 | 9361 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9324 | 9362 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9325 | 9363 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9326 | 9364 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9327 | 9365 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | ||
| 9328 | 9366 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9329 | 9367 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9330 | 9368 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9331 | 9369 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9332 | 9370 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9333 | -#define OP_SorterData 95 /* synopsis: r[P2]=data */ | |
| 9371 | +#define OP_SorterCompare 95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ | |
| 9334 | 9372 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9335 | 9373 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9336 | -#define OP_RowKey 98 /* synopsis: r[P2]=key */ | |
| 9337 | -#define OP_RowData 99 /* synopsis: r[P2]=data */ | |
| 9338 | -#define OP_Rowid 100 /* synopsis: r[P2]=rowid */ | |
| 9339 | -#define OP_NullRow 101 | |
| 9340 | -#define OP_Last 102 | |
| 9341 | -#define OP_SorterSort 103 | |
| 9342 | -#define OP_Sort 104 | |
| 9343 | -#define OP_Rewind 105 | |
| 9344 | -#define OP_SorterInsert 106 | |
| 9345 | -#define OP_IdxInsert 107 /* synopsis: key=r[P2] */ | |
| 9346 | -#define OP_IdxDelete 108 /* synopsis: key=r[P2@P3] */ | |
| 9347 | -#define OP_IdxRowid 109 /* synopsis: r[P2]=rowid */ | |
| 9348 | -#define OP_IdxLE 110 /* synopsis: key=r[P3@P4] */ | |
| 9349 | -#define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ | |
| 9350 | -#define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ | |
| 9351 | -#define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ | |
| 9352 | -#define OP_Destroy 114 | |
| 9353 | -#define OP_Clear 115 | |
| 9354 | -#define OP_ResetSorter 116 | |
| 9355 | -#define OP_CreateIndex 117 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9356 | -#define OP_CreateTable 118 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9357 | -#define OP_ParseSchema 119 | |
| 9358 | -#define OP_LoadAnalysis 120 | |
| 9359 | -#define OP_DropTable 121 | |
| 9360 | -#define OP_DropIndex 122 | |
| 9361 | -#define OP_DropTrigger 123 | |
| 9362 | -#define OP_IntegrityCk 124 | |
| 9363 | -#define OP_RowSetAdd 125 /* synopsis: rowset(P1)=r[P2] */ | |
| 9364 | -#define OP_RowSetRead 126 /* synopsis: r[P3]=rowset(P1) */ | |
| 9365 | -#define OP_RowSetTest 127 /* synopsis: if r[P3] in rowset(P1) goto P2 */ | |
| 9366 | -#define OP_Program 128 | |
| 9367 | -#define OP_Param 129 | |
| 9368 | -#define OP_FkCounter 130 /* synopsis: fkctr[P1]+=P2 */ | |
| 9369 | -#define OP_FkIfZero 131 /* synopsis: if fkctr[P1]==0 goto P2 */ | |
| 9370 | -#define OP_MemMax 132 /* synopsis: r[P1]=max(r[P1],r[P2]) */ | |
| 9374 | +#define OP_SorterData 98 /* synopsis: r[P2]=data */ | |
| 9375 | +#define OP_RowKey 99 /* synopsis: r[P2]=key */ | |
| 9376 | +#define OP_RowData 100 /* synopsis: r[P2]=data */ | |
| 9377 | +#define OP_Rowid 101 /* synopsis: r[P2]=rowid */ | |
| 9378 | +#define OP_NullRow 102 | |
| 9379 | +#define OP_Last 103 | |
| 9380 | +#define OP_SorterSort 104 | |
| 9381 | +#define OP_Sort 105 | |
| 9382 | +#define OP_Rewind 106 | |
| 9383 | +#define OP_SorterInsert 107 | |
| 9384 | +#define OP_IdxInsert 108 /* synopsis: key=r[P2] */ | |
| 9385 | +#define OP_IdxDelete 109 /* synopsis: key=r[P2@P3] */ | |
| 9386 | +#define OP_IdxRowid 110 /* synopsis: r[P2]=rowid */ | |
| 9387 | +#define OP_IdxLE 111 /* synopsis: key=r[P3@P4] */ | |
| 9388 | +#define OP_IdxGT 112 /* synopsis: key=r[P3@P4] */ | |
| 9389 | +#define OP_IdxLT 113 /* synopsis: key=r[P3@P4] */ | |
| 9390 | +#define OP_IdxGE 114 /* synopsis: key=r[P3@P4] */ | |
| 9391 | +#define OP_Destroy 115 | |
| 9392 | +#define OP_Clear 116 | |
| 9393 | +#define OP_ResetSorter 117 | |
| 9394 | +#define OP_CreateIndex 118 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9395 | +#define OP_CreateTable 119 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9396 | +#define OP_ParseSchema 120 | |
| 9397 | +#define OP_LoadAnalysis 121 | |
| 9398 | +#define OP_DropTable 122 | |
| 9399 | +#define OP_DropIndex 123 | |
| 9400 | +#define OP_DropTrigger 124 | |
| 9401 | +#define OP_IntegrityCk 125 | |
| 9402 | +#define OP_RowSetAdd 126 /* synopsis: rowset(P1)=r[P2] */ | |
| 9403 | +#define OP_RowSetRead 127 /* synopsis: r[P3]=rowset(P1) */ | |
| 9404 | +#define OP_RowSetTest 128 /* synopsis: if r[P3] in rowset(P1) goto P2 */ | |
| 9405 | +#define OP_Program 129 | |
| 9406 | +#define OP_Param 130 | |
| 9407 | +#define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ | |
| 9408 | +#define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ | |
| 9371 | 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9372 | -#define OP_IfPos 134 /* synopsis: if r[P1]>0 goto P2 */ | |
| 9373 | -#define OP_IfNeg 135 /* synopsis: if r[P1]<0 goto P2 */ | |
| 9374 | -#define OP_IfZero 136 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ | |
| 9375 | -#define OP_AggFinal 137 /* synopsis: accum=r[P1] N=P2 */ | |
| 9376 | -#define OP_IncrVacuum 138 | |
| 9377 | -#define OP_Expire 139 | |
| 9378 | -#define OP_TableLock 140 /* synopsis: iDb=P1 root=P2 write=P3 */ | |
| 9379 | -#define OP_VBegin 141 | |
| 9380 | -#define OP_VCreate 142 | |
| 9410 | +#define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ | |
| 9411 | +#define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ | |
| 9412 | +#define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ | |
| 9413 | +#define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ | |
| 9414 | +#define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ | |
| 9415 | +#define OP_IncrVacuum 139 | |
| 9416 | +#define OP_Expire 140 | |
| 9417 | +#define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ | |
| 9418 | +#define OP_VBegin 142 | |
| 9381 | 9419 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9382 | 9420 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9383 | 9421 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9384 | 9422 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9385 | 9423 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9386 | -#define OP_VDestroy 148 | |
| 9387 | -#define OP_VOpen 149 | |
| 9388 | -#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ | |
| 9389 | -#define OP_VNext 151 | |
| 9390 | -#define OP_VRename 152 | |
| 9391 | -#define OP_Pagecount 153 | |
| 9392 | -#define OP_MaxPgcnt 154 | |
| 9393 | -#define OP_Init 155 /* synopsis: Start at P2 */ | |
| 9394 | -#define OP_Noop 156 | |
| 9395 | -#define OP_Explain 157 | |
| 9424 | +#define OP_VCreate 148 | |
| 9425 | +#define OP_VDestroy 149 | |
| 9426 | +#define OP_VOpen 150 | |
| 9427 | +#define OP_VColumn 151 /* synopsis: r[P3]=vcolumn(P2) */ | |
| 9428 | +#define OP_VNext 152 | |
| 9429 | +#define OP_VRename 153 | |
| 9430 | +#define OP_Pagecount 154 | |
| 9431 | +#define OP_MaxPgcnt 155 | |
| 9432 | +#define OP_Init 156 /* synopsis: Start at P2 */ | |
| 9433 | +#define OP_Noop 157 | |
| 9434 | +#define OP_Explain 158 | |
| 9396 | 9435 | |
| 9397 | 9436 | |
| 9398 | 9437 | /* Properties such as "out2" or "jump" that are specified in |
| 9399 | 9438 | ** comments following the "case" for each opcode in the vdbe.c |
| 9400 | 9439 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | ||
| 9412 | 9451 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9413 | 9452 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9414 | 9453 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9415 | 9454 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9416 | 9455 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9417 | -/* 56 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\ | |
| 9418 | -/* 64 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c,\ | |
| 9456 | +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\ | |
| 9457 | +/* 64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\ | |
| 9419 | 9458 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9420 | 9459 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9421 | 9460 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9422 | -/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ | |
| 9423 | -/* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ | |
| 9424 | -/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,\ | |
| 9425 | -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15,\ | |
| 9426 | -/* 128 */ 0x01, 0x02, 0x00, 0x01, 0x08, 0x02, 0x05, 0x05,\ | |
| 9427 | -/* 136 */ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,\ | |
| 9428 | -/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01,\ | |
| 9429 | -/* 152 */ 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} | |
| 9461 | +/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ | |
| 9462 | +/* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\ | |
| 9463 | +/* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\ | |
| 9464 | +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ | |
| 9465 | +/* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\ | |
| 9466 | +/* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\ | |
| 9467 | +/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\ | |
| 9468 | +/* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} | |
| 9430 | 9469 | |
| 9431 | 9470 | /************** End of opcodes.h *********************************************/ |
| 9432 | 9471 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9433 | 9472 | |
| 9434 | 9473 | /* |
| @@ -10932,10 +10971,13 @@ | ||
| 10932 | 10971 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10933 | 10972 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10934 | 10973 | i16 nCol; /* Number of columns in this table */ |
| 10935 | 10974 | u16 nRef; /* Number of pointers to this Table */ |
| 10936 | 10975 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10976 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 10977 | + LogEst costMult; /* Cost multiplier for using this table */ | |
| 10978 | +#endif | |
| 10937 | 10979 | u8 tabFlags; /* Mask of TF_* values */ |
| 10938 | 10980 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10939 | 10981 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10940 | 10982 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10941 | 10983 | #endif |
| @@ -11591,10 +11633,11 @@ | ||
| 11591 | 11633 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11592 | 11634 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11593 | 11635 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11594 | 11636 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11595 | 11637 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11638 | +#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ | |
| 11596 | 11639 | |
| 11597 | 11640 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11598 | 11641 | */ |
| 11599 | 11642 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11600 | 11643 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | ||
| 11847 | 11890 | |
| 11848 | 11891 | /* |
| 11849 | 11892 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11850 | 11893 | */ |
| 11851 | 11894 | #if SQLITE_MAX_ATTACHED>30 |
| 11852 | - typedef sqlite3_uint64 yDbMask; | |
| 11895 | + typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; | |
| 11896 | +# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) | |
| 11897 | +# define DbMaskZero(M) memset((M),0,sizeof(M)) | |
| 11898 | +# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) | |
| 11899 | +# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) | |
| 11900 | +# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) | |
| 11853 | 11901 | #else |
| 11854 | 11902 | typedef unsigned int yDbMask; |
| 11903 | +# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) | |
| 11904 | +# define DbMaskZero(M) (M)=0 | |
| 11905 | +# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) | |
| 11906 | +# define DbMaskAllZero(M) (M)==0 | |
| 11907 | +# define DbMaskNonZero(M) (M)!=0 | |
| 11855 | 11908 | #endif |
| 11856 | 11909 | |
| 11857 | 11910 | /* |
| 11858 | 11911 | ** An SQL parser context. A copy of this structure is passed through |
| 11859 | 11912 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | ||
| 12522 | 12575 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12523 | 12576 | #else |
| 12524 | 12577 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12525 | 12578 | #endif |
| 12526 | 12579 | |
| 12580 | +#if SQLITE_MAX_ATTACHED>30 | |
| 12581 | +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); | |
| 12582 | +#endif | |
| 12527 | 12583 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12528 | 12584 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12529 | 12585 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12530 | 12586 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12531 | 12587 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | ||
| 12772 | 12828 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12773 | 12829 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12774 | 12830 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12775 | 12831 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12776 | 12832 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12833 | +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); | |
| 12777 | 12834 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12778 | 12835 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12779 | 12836 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12780 | 12837 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12781 | 12838 | |
| @@ -12801,11 +12858,11 @@ | ||
| 12801 | 12858 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12802 | 12859 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12803 | 12860 | #else |
| 12804 | 12861 | # define sqlite3FileSuffix3(X,Y) |
| 12805 | 12862 | #endif |
| 12806 | -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int); | |
| 12863 | +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); | |
| 12807 | 12864 | |
| 12808 | 12865 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12809 | 12866 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12810 | 12867 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12811 | 12868 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | ||
| 13876 | 13933 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13877 | 13934 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13878 | 13935 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13879 | 13936 | i16 nField; /* Number of fields in the header */ |
| 13880 | 13937 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13938 | +#ifdef SQLITE_DEBUG | |
| 13939 | + u8 seekOp; /* Most recent seek operation on this cursor */ | |
| 13940 | +#endif | |
| 13881 | 13941 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13882 | 13942 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13883 | 13943 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13884 | 13944 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13885 | 13945 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13886 | 13946 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13887 | 13947 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13888 | 13948 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13949 | + Pgno pgnoRoot; /* Root page of the open btree cursor */ | |
| 13889 | 13950 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13890 | 13951 | i64 seqCount; /* Sequence counter */ |
| 13891 | 13952 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13892 | 13953 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13893 | 13954 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | ||
| 18396 | 18457 | /* |
| 18397 | 18458 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18398 | 18459 | */ |
| 18399 | 18460 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18400 | 18461 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18401 | - if( sqlite3_initialize() ) return 0; | |
| 18462 | + if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; | |
| 18402 | 18463 | #endif |
| 18403 | 18464 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18404 | 18465 | } |
| 18405 | 18466 | |
| 18406 | 18467 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | ||
| 18577 | 18638 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18578 | 18639 | ** mutex and returns a pointer to it. If it returns NULL |
| 18579 | 18640 | ** that means that a mutex could not be allocated. |
| 18580 | 18641 | */ |
| 18581 | 18642 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18582 | - static sqlite3_debug_mutex aStatic[6]; | |
| 18643 | + static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1]; | |
| 18583 | 18644 | sqlite3_debug_mutex *pNew = 0; |
| 18584 | 18645 | switch( id ){ |
| 18585 | 18646 | case SQLITE_MUTEX_FAST: |
| 18586 | 18647 | case SQLITE_MUTEX_RECURSIVE: { |
| 18587 | 18648 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | ||
| 18774 | 18835 | ** <ul> |
| 18775 | 18836 | ** <li> SQLITE_MUTEX_FAST |
| 18776 | 18837 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18777 | 18838 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18778 | 18839 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18779 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 18840 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 18780 | 18841 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18781 | 18842 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18782 | 18843 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18844 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 18845 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 18846 | +** <li> SQLITE_MUTEX_STATIC_APP3 | |
| 18783 | 18847 | ** </ul> |
| 18784 | 18848 | ** |
| 18785 | 18849 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18786 | 18850 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18787 | 18851 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | ||
| 18806 | 18870 | ** mutex types, the same mutex is returned on every call that has |
| 18807 | 18871 | ** the same type number. |
| 18808 | 18872 | */ |
| 18809 | 18873 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18810 | 18874 | static sqlite3_mutex staticMutexes[] = { |
| 18875 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18876 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18877 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18811 | 18878 | SQLITE3_MUTEX_INITIALIZER, |
| 18812 | 18879 | SQLITE3_MUTEX_INITIALIZER, |
| 18813 | 18880 | SQLITE3_MUTEX_INITIALIZER, |
| 18814 | 18881 | SQLITE3_MUTEX_INITIALIZER, |
| 18815 | 18882 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | ||
| 19041 | 19108 | ** May you do good and not evil. |
| 19042 | 19109 | ** May you find forgiveness for yourself and forgive others. |
| 19043 | 19110 | ** May you share freely, never taking more than you give. |
| 19044 | 19111 | ** |
| 19045 | 19112 | ************************************************************************* |
| 19046 | -** This file contains the C functions that implement mutexes for win32 | |
| 19113 | +** This file contains the C functions that implement mutexes for Win32. | |
| 19047 | 19114 | */ |
| 19048 | 19115 | |
| 19049 | 19116 | #if SQLITE_OS_WIN |
| 19117 | +/* | |
| 19118 | +** Include code that is common to all os_*.c files | |
| 19119 | +*/ | |
| 19120 | +/************** Include os_common.h in the middle of mutex_w32.c *************/ | |
| 19121 | +/************** Begin file os_common.h ***************************************/ | |
| 19122 | +/* | |
| 19123 | +** 2004 May 22 | |
| 19124 | +** | |
| 19125 | +** The author disclaims copyright to this source code. In place of | |
| 19126 | +** a legal notice, here is a blessing: | |
| 19127 | +** | |
| 19128 | +** May you do good and not evil. | |
| 19129 | +** May you find forgiveness for yourself and forgive others. | |
| 19130 | +** May you share freely, never taking more than you give. | |
| 19131 | +** | |
| 19132 | +****************************************************************************** | |
| 19133 | +** | |
| 19134 | +** This file contains macros and a little bit of code that is common to | |
| 19135 | +** all of the platform-specific files (os_*.c) and is #included into those | |
| 19136 | +** files. | |
| 19137 | +** | |
| 19138 | +** This file should be #included by the os_*.c files only. It is not a | |
| 19139 | +** general purpose header file. | |
| 19140 | +*/ | |
| 19141 | +#ifndef _OS_COMMON_H_ | |
| 19142 | +#define _OS_COMMON_H_ | |
| 19143 | + | |
| 19144 | +/* | |
| 19145 | +** At least two bugs have slipped in because we changed the MEMORY_DEBUG | |
| 19146 | +** macro to SQLITE_DEBUG and some older makefiles have not yet made the | |
| 19147 | +** switch. The following code should catch this problem at compile-time. | |
| 19148 | +*/ | |
| 19149 | +#ifdef MEMORY_DEBUG | |
| 19150 | +# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." | |
| 19151 | +#endif | |
| 19152 | + | |
| 19153 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | |
| 19154 | +# ifndef SQLITE_DEBUG_OS_TRACE | |
| 19155 | +# define SQLITE_DEBUG_OS_TRACE 0 | |
| 19156 | +# endif | |
| 19157 | + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; | |
| 19158 | +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X | |
| 19159 | +#else | |
| 19160 | +# define OSTRACE(X) | |
| 19161 | +#endif | |
| 19162 | + | |
| 19163 | +/* | |
| 19164 | +** Macros for performance tracing. Normally turned off. Only works | |
| 19165 | +** on i486 hardware. | |
| 19166 | +*/ | |
| 19167 | +#ifdef SQLITE_PERFORMANCE_TRACE | |
| 19168 | + | |
| 19169 | +/* | |
| 19170 | +** hwtime.h contains inline assembler code for implementing | |
| 19171 | +** high-performance timing routines. | |
| 19172 | +*/ | |
| 19173 | +/************** Include hwtime.h in the middle of os_common.h ****************/ | |
| 19174 | +/************** Begin file hwtime.h ******************************************/ | |
| 19175 | +/* | |
| 19176 | +** 2008 May 27 | |
| 19177 | +** | |
| 19178 | +** The author disclaims copyright to this source code. In place of | |
| 19179 | +** a legal notice, here is a blessing: | |
| 19180 | +** | |
| 19181 | +** May you do good and not evil. | |
| 19182 | +** May you find forgiveness for yourself and forgive others. | |
| 19183 | +** May you share freely, never taking more than you give. | |
| 19184 | +** | |
| 19185 | +****************************************************************************** | |
| 19186 | +** | |
| 19187 | +** This file contains inline asm code for retrieving "high-performance" | |
| 19188 | +** counters for x86 class CPUs. | |
| 19189 | +*/ | |
| 19190 | +#ifndef _HWTIME_H_ | |
| 19191 | +#define _HWTIME_H_ | |
| 19192 | + | |
| 19193 | +/* | |
| 19194 | +** The following routine only works on pentium-class (or newer) processors. | |
| 19195 | +** It uses the RDTSC opcode to read the cycle count value out of the | |
| 19196 | +** processor and returns that value. This can be used for high-res | |
| 19197 | +** profiling. | |
| 19198 | +*/ | |
| 19199 | +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ | |
| 19200 | + (defined(i386) || defined(__i386__) || defined(_M_IX86)) | |
| 19201 | + | |
| 19202 | + #if defined(__GNUC__) | |
| 19203 | + | |
| 19204 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19205 | + unsigned int lo, hi; | |
| 19206 | + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | |
| 19207 | + return (sqlite_uint64)hi << 32 | lo; | |
| 19208 | + } | |
| 19209 | + | |
| 19210 | + #elif defined(_MSC_VER) | |
| 19211 | + | |
| 19212 | + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | |
| 19213 | + __asm { | |
| 19214 | + rdtsc | |
| 19215 | + ret ; return value at EDX:EAX | |
| 19216 | + } | |
| 19217 | + } | |
| 19218 | + | |
| 19219 | + #endif | |
| 19220 | + | |
| 19221 | +#elif (defined(__GNUC__) && defined(__x86_64__)) | |
| 19222 | + | |
| 19223 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19224 | + unsigned long val; | |
| 19225 | + __asm__ __volatile__ ("rdtsc" : "=A" (val)); | |
| 19226 | + return val; | |
| 19227 | + } | |
| 19228 | + | |
| 19229 | +#elif (defined(__GNUC__) && defined(__ppc__)) | |
| 19230 | + | |
| 19231 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19232 | + unsigned long long retval; | |
| 19233 | + unsigned long junk; | |
| 19234 | + __asm__ __volatile__ ("\n\ | |
| 19235 | + 1: mftbu %1\n\ | |
| 19236 | + mftb %L0\n\ | |
| 19237 | + mftbu %0\n\ | |
| 19238 | + cmpw %0,%1\n\ | |
| 19239 | + bne 1b" | |
| 19240 | + : "=r" (retval), "=r" (junk)); | |
| 19241 | + return retval; | |
| 19242 | + } | |
| 19243 | + | |
| 19244 | +#else | |
| 19245 | + | |
| 19246 | + #error Need implementation of sqlite3Hwtime() for your platform. | |
| 19247 | + | |
| 19248 | + /* | |
| 19249 | + ** To compile without implementing sqlite3Hwtime() for your platform, | |
| 19250 | + ** you can remove the above #error and use the following | |
| 19251 | + ** stub function. You will lose timing support for many | |
| 19252 | + ** of the debugging and testing utilities, but it should at | |
| 19253 | + ** least compile and run. | |
| 19254 | + */ | |
| 19255 | +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | |
| 19256 | + | |
| 19257 | +#endif | |
| 19258 | + | |
| 19259 | +#endif /* !defined(_HWTIME_H_) */ | |
| 19260 | + | |
| 19261 | +/************** End of hwtime.h **********************************************/ | |
| 19262 | +/************** Continuing where we left off in os_common.h ******************/ | |
| 19263 | + | |
| 19264 | +static sqlite_uint64 g_start; | |
| 19265 | +static sqlite_uint64 g_elapsed; | |
| 19266 | +#define TIMER_START g_start=sqlite3Hwtime() | |
| 19267 | +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start | |
| 19268 | +#define TIMER_ELAPSED g_elapsed | |
| 19269 | +#else | |
| 19270 | +#define TIMER_START | |
| 19271 | +#define TIMER_END | |
| 19272 | +#define TIMER_ELAPSED ((sqlite_uint64)0) | |
| 19273 | +#endif | |
| 19274 | + | |
| 19275 | +/* | |
| 19276 | +** If we compile with the SQLITE_TEST macro set, then the following block | |
| 19277 | +** of code will give us the ability to simulate a disk I/O error. This | |
| 19278 | +** is used for testing the I/O recovery logic. | |
| 19279 | +*/ | |
| 19280 | +#ifdef SQLITE_TEST | |
| 19281 | +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ | |
| 19282 | +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ | |
| 19283 | +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ | |
| 19284 | +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ | |
| 19285 | +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ | |
| 19286 | +SQLITE_API int sqlite3_diskfull_pending = 0; | |
| 19287 | +SQLITE_API int sqlite3_diskfull = 0; | |
| 19288 | +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) | |
| 19289 | +#define SimulateIOError(CODE) \ | |
| 19290 | + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ | |
| 19291 | + || sqlite3_io_error_pending-- == 1 ) \ | |
| 19292 | + { local_ioerr(); CODE; } | |
| 19293 | +static void local_ioerr(){ | |
| 19294 | + IOTRACE(("IOERR\n")); | |
| 19295 | + sqlite3_io_error_hit++; | |
| 19296 | + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; | |
| 19297 | +} | |
| 19298 | +#define SimulateDiskfullError(CODE) \ | |
| 19299 | + if( sqlite3_diskfull_pending ){ \ | |
| 19300 | + if( sqlite3_diskfull_pending == 1 ){ \ | |
| 19301 | + local_ioerr(); \ | |
| 19302 | + sqlite3_diskfull = 1; \ | |
| 19303 | + sqlite3_io_error_hit = 1; \ | |
| 19304 | + CODE; \ | |
| 19305 | + }else{ \ | |
| 19306 | + sqlite3_diskfull_pending--; \ | |
| 19307 | + } \ | |
| 19308 | + } | |
| 19309 | +#else | |
| 19310 | +#define SimulateIOErrorBenign(X) | |
| 19311 | +#define SimulateIOError(A) | |
| 19312 | +#define SimulateDiskfullError(A) | |
| 19313 | +#endif | |
| 19314 | + | |
| 19315 | +/* | |
| 19316 | +** When testing, keep a count of the number of open files. | |
| 19317 | +*/ | |
| 19318 | +#ifdef SQLITE_TEST | |
| 19319 | +SQLITE_API int sqlite3_open_file_count = 0; | |
| 19320 | +#define OpenCounter(X) sqlite3_open_file_count+=(X) | |
| 19321 | +#else | |
| 19322 | +#define OpenCounter(X) | |
| 19323 | +#endif | |
| 19324 | + | |
| 19325 | +#endif /* !defined(_OS_COMMON_H_) */ | |
| 19326 | + | |
| 19327 | +/************** End of os_common.h *******************************************/ | |
| 19328 | +/************** Continuing where we left off in mutex_w32.c ******************/ | |
| 19329 | + | |
| 19050 | 19330 | /* |
| 19051 | 19331 | ** Include the header file for the Windows VFS. |
| 19052 | 19332 | */ |
| 19053 | 19333 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19054 | 19334 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | ||
| 19124 | 19404 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19125 | 19405 | #endif |
| 19126 | 19406 | |
| 19127 | 19407 | /* |
| 19128 | 19408 | ** The code in this file is only used if we are compiling multithreaded |
| 19129 | -** on a win32 system. | |
| 19409 | +** on a Win32 system. | |
| 19130 | 19410 | */ |
| 19131 | 19411 | #ifdef SQLITE_MUTEX_W32 |
| 19132 | 19412 | |
| 19133 | 19413 | /* |
| 19134 | 19414 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | ||
| 19137 | 19417 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19138 | 19418 | int id; /* Mutex type */ |
| 19139 | 19419 | #ifdef SQLITE_DEBUG |
| 19140 | 19420 | volatile int nRef; /* Number of enterances */ |
| 19141 | 19421 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19142 | - int trace; /* True to trace changes */ | |
| 19422 | + volatile int trace; /* True to trace changes */ | |
| 19143 | 19423 | #endif |
| 19144 | 19424 | }; |
| 19425 | + | |
| 19426 | +/* | |
| 19427 | +** These are the initializer values used when declaring a "static" mutex | |
| 19428 | +** on Win32. It should be noted that all mutexes require initialization | |
| 19429 | +** on the Win32 platform. | |
| 19430 | +*/ | |
| 19145 | 19431 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19432 | + | |
| 19146 | 19433 | #ifdef SQLITE_DEBUG |
| 19147 | -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } | |
| 19434 | +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ | |
| 19435 | + 0L, (DWORD)0, 0 } | |
| 19148 | 19436 | #else |
| 19149 | 19437 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19150 | 19438 | #endif |
| 19151 | 19439 | |
| 19152 | -/* | |
| 19153 | -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, | |
| 19154 | -** or WinCE. Return false (zero) for Win95, Win98, or WinME. | |
| 19155 | -** | |
| 19156 | -** Here is an interesting observation: Win95, Win98, and WinME lack | |
| 19157 | -** the LockFileEx() API. But we can still statically link against that | |
| 19158 | -** API as long as we don't call it win running Win95/98/ME. A call to | |
| 19159 | -** this routine is used to determine if the host is Win95/98/ME or | |
| 19160 | -** WinNT/2K/XP so that we will know whether or not we can safely call | |
| 19161 | -** the LockFileEx() API. | |
| 19162 | -** | |
| 19163 | -** mutexIsNT() is only used for the TryEnterCriticalSection() API call, | |
| 19164 | -** which is only available if your application was compiled with | |
| 19165 | -** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only | |
| 19166 | -** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef | |
| 19167 | -** this out as well. | |
| 19168 | -*/ | |
| 19169 | -#if 0 | |
| 19170 | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT | |
| 19171 | -# define mutexIsNT() (1) | |
| 19172 | -#else | |
| 19173 | - static int mutexIsNT(void){ | |
| 19174 | - static int osType = 0; | |
| 19175 | - if( osType==0 ){ | |
| 19176 | - OSVERSIONINFO sInfo; | |
| 19177 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 19178 | - GetVersionEx(&sInfo); | |
| 19179 | - osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; | |
| 19180 | - } | |
| 19181 | - return osType==2; | |
| 19182 | - } | |
| 19183 | -#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ | |
| 19184 | -#endif | |
| 19185 | - | |
| 19186 | 19440 | #ifdef SQLITE_DEBUG |
| 19187 | 19441 | /* |
| 19188 | 19442 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19189 | 19443 | ** intended for use only inside assert() statements. |
| 19190 | 19444 | */ |
| 19191 | 19445 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19192 | 19446 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19193 | 19447 | } |
| 19448 | + | |
| 19194 | 19449 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19195 | 19450 | return p->nRef==0 || p->owner!=tid; |
| 19196 | 19451 | } |
| 19452 | + | |
| 19197 | 19453 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19198 | - DWORD tid = GetCurrentThreadId(); | |
| 19454 | + DWORD tid = GetCurrentThreadId(); | |
| 19199 | 19455 | return winMutexNotheld2(p, tid); |
| 19200 | 19456 | } |
| 19201 | 19457 | #endif |
| 19202 | 19458 | |
| 19203 | - | |
| 19204 | 19459 | /* |
| 19205 | 19460 | ** Initialize and deinitialize the mutex subsystem. |
| 19206 | 19461 | */ |
| 19207 | -static sqlite3_mutex winMutex_staticMutexes[6] = { | |
| 19462 | +static sqlite3_mutex winMutex_staticMutexes[] = { | |
| 19463 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19464 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19465 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19208 | 19466 | SQLITE3_MUTEX_INITIALIZER, |
| 19209 | 19467 | SQLITE3_MUTEX_INITIALIZER, |
| 19210 | 19468 | SQLITE3_MUTEX_INITIALIZER, |
| 19211 | 19469 | SQLITE3_MUTEX_INITIALIZER, |
| 19212 | 19470 | SQLITE3_MUTEX_INITIALIZER, |
| 19213 | 19471 | SQLITE3_MUTEX_INITIALIZER |
| 19214 | 19472 | }; |
| 19473 | + | |
| 19215 | 19474 | static int winMutex_isInit = 0; |
| 19216 | -/* As winMutexInit() and winMutexEnd() are called as part | |
| 19217 | -** of the sqlite3_initialize and sqlite3_shutdown() | |
| 19218 | -** processing, the "interlocked" magic is probably not | |
| 19219 | -** strictly necessary. | |
| 19475 | +static int winMutex_isNt = -1; /* <0 means "need to query" */ | |
| 19476 | + | |
| 19477 | +/* As the winMutexInit() and winMutexEnd() functions are called as part | |
| 19478 | +** of the sqlite3_initialize() and sqlite3_shutdown() processing, the | |
| 19479 | +** "interlocked" magic used here is probably not strictly necessary. | |
| 19220 | 19480 | */ |
| 19221 | -static LONG winMutex_lock = 0; | |
| 19481 | +static LONG volatile winMutex_lock = 0; | |
| 19222 | 19482 | |
| 19483 | +SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ | |
| 19223 | 19484 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19224 | 19485 | |
| 19225 | -static int winMutexInit(void){ | |
| 19486 | +static int winMutexInit(void){ | |
| 19226 | 19487 | /* The first to increment to 1 does actual initialization */ |
| 19227 | 19488 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19228 | 19489 | int i; |
| 19229 | 19490 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19230 | 19491 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | ||
| 19233 | 19494 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19234 | 19495 | #endif |
| 19235 | 19496 | } |
| 19236 | 19497 | winMutex_isInit = 1; |
| 19237 | 19498 | }else{ |
| 19238 | - /* Someone else is in the process of initing the static mutexes */ | |
| 19499 | + /* Another thread is (in the process of) initializing the static | |
| 19500 | + ** mutexes */ | |
| 19239 | 19501 | while( !winMutex_isInit ){ |
| 19240 | 19502 | sqlite3_win32_sleep(1); |
| 19241 | 19503 | } |
| 19242 | 19504 | } |
| 19243 | - return SQLITE_OK; | |
| 19505 | + return SQLITE_OK; | |
| 19244 | 19506 | } |
| 19245 | 19507 | |
| 19246 | -static int winMutexEnd(void){ | |
| 19247 | - /* The first to decrement to 0 does actual shutdown | |
| 19508 | +static int winMutexEnd(void){ | |
| 19509 | + /* The first to decrement to 0 does actual shutdown | |
| 19248 | 19510 | ** (which should be the last to shutdown.) */ |
| 19249 | 19511 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19250 | 19512 | if( winMutex_isInit==1 ){ |
| 19251 | 19513 | int i; |
| 19252 | 19514 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | ||
| 19253 | 19515 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19254 | 19516 | } |
| 19255 | 19517 | winMutex_isInit = 0; |
| 19256 | 19518 | } |
| 19257 | 19519 | } |
| 19258 | - return SQLITE_OK; | |
| 19520 | + return SQLITE_OK; | |
| 19259 | 19521 | } |
| 19260 | 19522 | |
| 19261 | 19523 | /* |
| 19262 | 19524 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19263 | 19525 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | ||
| 19268 | 19530 | ** <ul> |
| 19269 | 19531 | ** <li> SQLITE_MUTEX_FAST |
| 19270 | 19532 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19271 | 19533 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19272 | 19534 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19273 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 19535 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 19274 | 19536 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19275 | 19537 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19276 | 19538 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19539 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 19540 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 19541 | +** <li> SQLITE_MUTEX_STATIC_APP3 | |
| 19277 | 19542 | ** </ul> |
| 19278 | 19543 | ** |
| 19279 | 19544 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19280 | 19545 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19281 | 19546 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | ||
| 19294 | 19559 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19295 | 19560 | ** SQLITE_MUTEX_RECURSIVE. |
| 19296 | 19561 | ** |
| 19297 | 19562 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19298 | 19563 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19299 | -** returns a different mutex on every call. But for the static | |
| 19564 | +** returns a different mutex on every call. But for the static | |
| 19300 | 19565 | ** mutex types, the same mutex is returned on every call that has |
| 19301 | 19566 | ** the same type number. |
| 19302 | 19567 | */ |
| 19303 | 19568 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19304 | 19569 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | ||
| 19305 | 19570 | |
| 19306 | 19571 | switch( iType ){ |
| 19307 | 19572 | case SQLITE_MUTEX_FAST: |
| 19308 | 19573 | case SQLITE_MUTEX_RECURSIVE: { |
| 19309 | 19574 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19310 | - if( p ){ | |
| 19575 | + if( p ){ | |
| 19311 | 19576 | #ifdef SQLITE_DEBUG |
| 19312 | 19577 | p->id = iType; |
| 19578 | +#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC | |
| 19579 | + p->trace = 1; | |
| 19580 | +#endif | |
| 19313 | 19581 | #endif |
| 19314 | 19582 | #if SQLITE_OS_WINRT |
| 19315 | 19583 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19316 | 19584 | #else |
| 19317 | 19585 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | ||
| 19318 | 19586 | #endif |
| 19319 | 19587 | } |
| 19320 | 19588 | break; |
| 19321 | 19589 | } |
| 19322 | 19590 | default: { |
| 19323 | - assert( winMutex_isInit==1 ); | |
| 19324 | 19591 | assert( iType-2 >= 0 ); |
| 19325 | 19592 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19593 | + assert( winMutex_isInit==1 ); | |
| 19326 | 19594 | p = &winMutex_staticMutexes[iType-2]; |
| 19327 | 19595 | #ifdef SQLITE_DEBUG |
| 19328 | 19596 | p->id = iType; |
| 19597 | +#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC | |
| 19598 | + p->trace = 1; | |
| 19599 | +#endif | |
| 19329 | 19600 | #endif |
| 19330 | 19601 | break; |
| 19331 | 19602 | } |
| 19332 | 19603 | } |
| 19333 | 19604 | return p; |
| @@ -19339,12 +19610,15 @@ | ||
| 19339 | 19610 | ** allocated mutex. SQLite is careful to deallocate every |
| 19340 | 19611 | ** mutex that it allocates. |
| 19341 | 19612 | */ |
| 19342 | 19613 | static void winMutexFree(sqlite3_mutex *p){ |
| 19343 | 19614 | assert( p ); |
| 19615 | +#ifdef SQLITE_DEBUG | |
| 19344 | 19616 | assert( p->nRef==0 && p->owner==0 ); |
| 19345 | 19617 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19618 | +#endif | |
| 19619 | + assert( winMutex_isInit==1 ); | |
| 19346 | 19620 | DeleteCriticalSection(&p->mutex); |
| 19347 | 19621 | sqlite3_free(p); |
| 19348 | 19622 | } |
| 19349 | 19623 | |
| 19350 | 19624 | /* |
| @@ -19357,53 +19631,71 @@ | ||
| 19357 | 19631 | ** mutex must be exited an equal number of times before another thread |
| 19358 | 19632 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19359 | 19633 | ** more than once, the behavior is undefined. |
| 19360 | 19634 | */ |
| 19361 | 19635 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19636 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19637 | + DWORD tid = GetCurrentThreadId(); | |
| 19638 | +#endif | |
| 19362 | 19639 | #ifdef SQLITE_DEBUG |
| 19363 | - DWORD tid = GetCurrentThreadId(); | |
| 19640 | + assert( p ); | |
| 19364 | 19641 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19642 | +#else | |
| 19643 | + assert( p ); | |
| 19365 | 19644 | #endif |
| 19645 | + assert( winMutex_isInit==1 ); | |
| 19366 | 19646 | EnterCriticalSection(&p->mutex); |
| 19367 | 19647 | #ifdef SQLITE_DEBUG |
| 19368 | 19648 | assert( p->nRef>0 || p->owner==0 ); |
| 19369 | - p->owner = tid; | |
| 19649 | + p->owner = tid; | |
| 19370 | 19650 | p->nRef++; |
| 19371 | 19651 | if( p->trace ){ |
| 19372 | - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19652 | + OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", | |
| 19653 | + tid, p, p->trace, p->nRef)); | |
| 19373 | 19654 | } |
| 19374 | 19655 | #endif |
| 19375 | 19656 | } |
| 19657 | + | |
| 19376 | 19658 | static int winMutexTry(sqlite3_mutex *p){ |
| 19377 | -#ifndef NDEBUG | |
| 19378 | - DWORD tid = GetCurrentThreadId(); | |
| 19659 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19660 | + DWORD tid = GetCurrentThreadId(); | |
| 19379 | 19661 | #endif |
| 19380 | 19662 | int rc = SQLITE_BUSY; |
| 19663 | + assert( p ); | |
| 19381 | 19664 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19382 | 19665 | /* |
| 19383 | 19666 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19384 | 19667 | ** is used it is merely an optimization. So it is OK for it to always |
| 19385 | - ** fail. | |
| 19668 | + ** fail. | |
| 19386 | 19669 | ** |
| 19387 | 19670 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19388 | 19671 | ** And some windows compilers complain if you try to use it without |
| 19389 | 19672 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19390 | 19673 | ** For that reason, we will omit this optimization for now. See |
| 19391 | 19674 | ** ticket #2685. |
| 19392 | 19675 | */ |
| 19393 | -#if 0 | |
| 19394 | - if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ | |
| 19676 | +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 | |
| 19677 | + assert( winMutex_isInit==1 ); | |
| 19678 | + assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); | |
| 19679 | + if( winMutex_isNt<0 ){ | |
| 19680 | + winMutex_isNt = sqlite3_win32_is_nt(); | |
| 19681 | + } | |
| 19682 | + assert( winMutex_isNt==0 || winMutex_isNt==1 ); | |
| 19683 | + if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ | |
| 19684 | +#ifdef SQLITE_DEBUG | |
| 19395 | 19685 | p->owner = tid; |
| 19396 | 19686 | p->nRef++; |
| 19687 | +#endif | |
| 19397 | 19688 | rc = SQLITE_OK; |
| 19398 | 19689 | } |
| 19399 | 19690 | #else |
| 19400 | 19691 | UNUSED_PARAMETER(p); |
| 19401 | 19692 | #endif |
| 19402 | 19693 | #ifdef SQLITE_DEBUG |
| 19403 | - if( rc==SQLITE_OK && p->trace ){ | |
| 19404 | - printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19694 | + if( p->trace ){ | |
| 19695 | + OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", | |
| 19696 | + tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); | |
| 19405 | 19697 | } |
| 19406 | 19698 | #endif |
| 19407 | 19699 | return rc; |
| 19408 | 19700 | } |
| 19409 | 19701 | |
| @@ -19412,22 +19704,27 @@ | ||
| 19412 | 19704 | ** previously entered by the same thread. The behavior |
| 19413 | 19705 | ** is undefined if the mutex is not currently entered or |
| 19414 | 19706 | ** is not currently allocated. SQLite will never do either. |
| 19415 | 19707 | */ |
| 19416 | 19708 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19417 | -#ifndef NDEBUG | |
| 19709 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19418 | 19710 | DWORD tid = GetCurrentThreadId(); |
| 19711 | +#endif | |
| 19712 | + assert( p ); | |
| 19713 | +#ifdef SQLITE_DEBUG | |
| 19419 | 19714 | assert( p->nRef>0 ); |
| 19420 | 19715 | assert( p->owner==tid ); |
| 19421 | 19716 | p->nRef--; |
| 19422 | 19717 | if( p->nRef==0 ) p->owner = 0; |
| 19423 | 19718 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19424 | 19719 | #endif |
| 19720 | + assert( winMutex_isInit==1 ); | |
| 19425 | 19721 | LeaveCriticalSection(&p->mutex); |
| 19426 | 19722 | #ifdef SQLITE_DEBUG |
| 19427 | 19723 | if( p->trace ){ |
| 19428 | - printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19724 | + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", | |
| 19725 | + tid, p, p->trace, p->nRef)); | |
| 19429 | 19726 | } |
| 19430 | 19727 | #endif |
| 19431 | 19728 | } |
| 19432 | 19729 | |
| 19433 | 19730 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | ||
| 19445 | 19742 | #else |
| 19446 | 19743 | 0, |
| 19447 | 19744 | 0 |
| 19448 | 19745 | #endif |
| 19449 | 19746 | }; |
| 19450 | - | |
| 19451 | 19747 | return &sMutex; |
| 19452 | 19748 | } |
| 19749 | + | |
| 19453 | 19750 | #endif /* SQLITE_MUTEX_W32 */ |
| 19454 | 19751 | |
| 19455 | 19752 | /************** End of mutex_w32.c *******************************************/ |
| 19456 | 19753 | /************** Begin file malloc.c ******************************************/ |
| 19457 | 19754 | /* |
| @@ -22422,13 +22719,13 @@ | ||
| 22422 | 22719 | testcase( c==(+1) ); |
| 22423 | 22720 | } |
| 22424 | 22721 | return c; |
| 22425 | 22722 | } |
| 22426 | 22723 | |
| 22427 | - | |
| 22428 | 22724 | /* |
| 22429 | -** Convert zNum to a 64-bit signed integer. | |
| 22725 | +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This | |
| 22726 | +** routine does *not* accept hexadecimal notation. | |
| 22430 | 22727 | ** |
| 22431 | 22728 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22432 | 22729 | ** integer, then write that value into *pNum and return 0. |
| 22433 | 22730 | ** |
| 22434 | 22731 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | ||
| 22511 | 22808 | assert( u-1==LARGEST_INT64 ); |
| 22512 | 22809 | return neg ? 0 : 2; |
| 22513 | 22810 | } |
| 22514 | 22811 | } |
| 22515 | 22812 | } |
| 22813 | + | |
| 22814 | +/* | |
| 22815 | +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, | |
| 22816 | +** into a 64-bit signed integer. This routine accepts hexadecimal literals, | |
| 22817 | +** whereas sqlite3Atoi64() does not. | |
| 22818 | +** | |
| 22819 | +** Returns: | |
| 22820 | +** | |
| 22821 | +** 0 Successful transformation. Fits in a 64-bit signed integer. | |
| 22822 | +** 1 Integer too large for a 64-bit signed integer or is malformed | |
| 22823 | +** 2 Special case of 9223372036854775808 | |
| 22824 | +*/ | |
| 22825 | +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ | |
| 22826 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 22827 | + if( z[0]=='0' | |
| 22828 | + && (z[1]=='x' || z[1]=='X') | |
| 22829 | + && sqlite3Isxdigit(z[2]) | |
| 22830 | + ){ | |
| 22831 | + u64 u = 0; | |
| 22832 | + int i, k; | |
| 22833 | + for(i=2; z[i]=='0'; i++){} | |
| 22834 | + for(k=i; sqlite3Isxdigit(z[k]); k++){ | |
| 22835 | + u = u*16 + sqlite3HexToInt(z[k]); | |
| 22836 | + } | |
| 22837 | + memcpy(pOut, &u, 8); | |
| 22838 | + return (z[k]==0 && k-i<=16) ? 0 : 1; | |
| 22839 | + }else | |
| 22840 | +#endif /* SQLITE_OMIT_HEX_INTEGER */ | |
| 22841 | + { | |
| 22842 | + return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); | |
| 22843 | + } | |
| 22844 | +} | |
| 22516 | 22845 | |
| 22517 | 22846 | /* |
| 22518 | 22847 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22519 | 22848 | ** *pValue to that integer and return true. Otherwise return false. |
| 22849 | +** | |
| 22850 | +** This routine accepts both decimal and hexadecimal notation for integers. | |
| 22520 | 22851 | ** |
| 22521 | 22852 | ** Any non-numeric characters that following zNum are ignored. |
| 22522 | 22853 | ** This is different from sqlite3Atoi64() which requires the |
| 22523 | 22854 | ** input number to be zero-terminated. |
| 22524 | 22855 | */ |
| @@ -22530,11 +22861,29 @@ | ||
| 22530 | 22861 | neg = 1; |
| 22531 | 22862 | zNum++; |
| 22532 | 22863 | }else if( zNum[0]=='+' ){ |
| 22533 | 22864 | zNum++; |
| 22534 | 22865 | } |
| 22535 | - while( zNum[0]=='0' ) zNum++; | |
| 22866 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 22867 | + else if( zNum[0]=='0' | |
| 22868 | + && (zNum[1]=='x' || zNum[1]=='X') | |
| 22869 | + && sqlite3Isxdigit(zNum[2]) | |
| 22870 | + ){ | |
| 22871 | + u32 u = 0; | |
| 22872 | + zNum += 2; | |
| 22873 | + while( zNum[0]=='0' ) zNum++; | |
| 22874 | + for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ | |
| 22875 | + u = u*16 + sqlite3HexToInt(zNum[i]); | |
| 22876 | + } | |
| 22877 | + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ | |
| 22878 | + memcpy(pValue, &u, 4); | |
| 22879 | + return 1; | |
| 22880 | + }else{ | |
| 22881 | + return 0; | |
| 22882 | + } | |
| 22883 | + } | |
| 22884 | +#endif | |
| 22536 | 22885 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22537 | 22886 | v = v*10 + c; |
| 22538 | 22887 | } |
| 22539 | 22888 | |
| 22540 | 22889 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | ||
| 23606 | 23955 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23607 | 23956 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23608 | 23957 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23609 | 23958 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23610 | 23959 | /* 51 */ "SetCookie" OpHelp(""), |
| 23611 | - /* 52 */ "OpenRead" OpHelp("root=P2 iDb=P3"), | |
| 23612 | - /* 53 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), | |
| 23613 | - /* 54 */ "OpenAutoindex" OpHelp("nColumn=P2"), | |
| 23614 | - /* 55 */ "OpenEphemeral" OpHelp("nColumn=P2"), | |
| 23615 | - /* 56 */ "SorterOpen" OpHelp(""), | |
| 23616 | - /* 57 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), | |
| 23617 | - /* 58 */ "Close" OpHelp(""), | |
| 23618 | - /* 59 */ "SeekLT" OpHelp(""), | |
| 23619 | - /* 60 */ "SeekLE" OpHelp(""), | |
| 23620 | - /* 61 */ "SeekGE" OpHelp(""), | |
| 23621 | - /* 62 */ "SeekGT" OpHelp(""), | |
| 23622 | - /* 63 */ "Seek" OpHelp("intkey=r[P2]"), | |
| 23623 | - /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), | |
| 23624 | - /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), | |
| 23625 | - /* 66 */ "Found" OpHelp("key=r[P3@P4]"), | |
| 23626 | - /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), | |
| 23627 | - /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), | |
| 23628 | - /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), | |
| 23629 | - /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), | |
| 23960 | + /* 52 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), | |
| 23961 | + /* 53 */ "OpenRead" OpHelp("root=P2 iDb=P3"), | |
| 23962 | + /* 54 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), | |
| 23963 | + /* 55 */ "OpenAutoindex" OpHelp("nColumn=P2"), | |
| 23964 | + /* 56 */ "OpenEphemeral" OpHelp("nColumn=P2"), | |
| 23965 | + /* 57 */ "SorterOpen" OpHelp(""), | |
| 23966 | + /* 58 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), | |
| 23967 | + /* 59 */ "Close" OpHelp(""), | |
| 23968 | + /* 60 */ "SeekLT" OpHelp("key=r[P3@P4]"), | |
| 23969 | + /* 61 */ "SeekLE" OpHelp("key=r[P3@P4]"), | |
| 23970 | + /* 62 */ "SeekGE" OpHelp("key=r[P3@P4]"), | |
| 23971 | + /* 63 */ "SeekGT" OpHelp("key=r[P3@P4]"), | |
| 23972 | + /* 64 */ "Seek" OpHelp("intkey=r[P2]"), | |
| 23973 | + /* 65 */ "NoConflict" OpHelp("key=r[P3@P4]"), | |
| 23974 | + /* 66 */ "NotFound" OpHelp("key=r[P3@P4]"), | |
| 23975 | + /* 67 */ "Found" OpHelp("key=r[P3@P4]"), | |
| 23976 | + /* 68 */ "NotExists" OpHelp("intkey=r[P3]"), | |
| 23977 | + /* 69 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), | |
| 23978 | + /* 70 */ "NewRowid" OpHelp("r[P2]=rowid"), | |
| 23630 | 23979 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23631 | 23980 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23632 | - /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), | |
| 23633 | - /* 74 */ "Delete" OpHelp(""), | |
| 23634 | - /* 75 */ "ResetCount" OpHelp(""), | |
| 23981 | + /* 73 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), | |
| 23982 | + /* 74 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), | |
| 23983 | + /* 75 */ "Delete" OpHelp(""), | |
| 23635 | 23984 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23636 | 23985 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23637 | 23986 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23638 | 23987 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23639 | 23988 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23640 | 23989 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23641 | 23990 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23642 | 23991 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23643 | - /* 84 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), | |
| 23992 | + /* 84 */ "ResetCount" OpHelp(""), | |
| 23644 | 23993 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23645 | 23994 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23646 | 23995 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23647 | 23996 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23648 | 23997 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | ||
| 23649 | 23998 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23650 | 23999 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 23651 | 24000 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23652 | 24001 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 23653 | 24002 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 23654 | - /* 95 */ "SorterData" OpHelp("r[P2]=data"), | |
| 24003 | + /* 95 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), | |
| 23655 | 24004 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 23656 | 24005 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 23657 | - /* 98 */ "RowKey" OpHelp("r[P2]=key"), | |
| 23658 | - /* 99 */ "RowData" OpHelp("r[P2]=data"), | |
| 23659 | - /* 100 */ "Rowid" OpHelp("r[P2]=rowid"), | |
| 23660 | - /* 101 */ "NullRow" OpHelp(""), | |
| 23661 | - /* 102 */ "Last" OpHelp(""), | |
| 23662 | - /* 103 */ "SorterSort" OpHelp(""), | |
| 23663 | - /* 104 */ "Sort" OpHelp(""), | |
| 23664 | - /* 105 */ "Rewind" OpHelp(""), | |
| 23665 | - /* 106 */ "SorterInsert" OpHelp(""), | |
| 23666 | - /* 107 */ "IdxInsert" OpHelp("key=r[P2]"), | |
| 23667 | - /* 108 */ "IdxDelete" OpHelp("key=r[P2@P3]"), | |
| 23668 | - /* 109 */ "IdxRowid" OpHelp("r[P2]=rowid"), | |
| 23669 | - /* 110 */ "IdxLE" OpHelp("key=r[P3@P4]"), | |
| 23670 | - /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), | |
| 23671 | - /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), | |
| 23672 | - /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), | |
| 23673 | - /* 114 */ "Destroy" OpHelp(""), | |
| 23674 | - /* 115 */ "Clear" OpHelp(""), | |
| 23675 | - /* 116 */ "ResetSorter" OpHelp(""), | |
| 23676 | - /* 117 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), | |
| 23677 | - /* 118 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), | |
| 23678 | - /* 119 */ "ParseSchema" OpHelp(""), | |
| 23679 | - /* 120 */ "LoadAnalysis" OpHelp(""), | |
| 23680 | - /* 121 */ "DropTable" OpHelp(""), | |
| 23681 | - /* 122 */ "DropIndex" OpHelp(""), | |
| 23682 | - /* 123 */ "DropTrigger" OpHelp(""), | |
| 23683 | - /* 124 */ "IntegrityCk" OpHelp(""), | |
| 23684 | - /* 125 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), | |
| 23685 | - /* 126 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), | |
| 23686 | - /* 127 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | |
| 23687 | - /* 128 */ "Program" OpHelp(""), | |
| 23688 | - /* 129 */ "Param" OpHelp(""), | |
| 23689 | - /* 130 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), | |
| 23690 | - /* 131 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | |
| 23691 | - /* 132 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), | |
| 24006 | + /* 98 */ "SorterData" OpHelp("r[P2]=data"), | |
| 24007 | + /* 99 */ "RowKey" OpHelp("r[P2]=key"), | |
| 24008 | + /* 100 */ "RowData" OpHelp("r[P2]=data"), | |
| 24009 | + /* 101 */ "Rowid" OpHelp("r[P2]=rowid"), | |
| 24010 | + /* 102 */ "NullRow" OpHelp(""), | |
| 24011 | + /* 103 */ "Last" OpHelp(""), | |
| 24012 | + /* 104 */ "SorterSort" OpHelp(""), | |
| 24013 | + /* 105 */ "Sort" OpHelp(""), | |
| 24014 | + /* 106 */ "Rewind" OpHelp(""), | |
| 24015 | + /* 107 */ "SorterInsert" OpHelp(""), | |
| 24016 | + /* 108 */ "IdxInsert" OpHelp("key=r[P2]"), | |
| 24017 | + /* 109 */ "IdxDelete" OpHelp("key=r[P2@P3]"), | |
| 24018 | + /* 110 */ "IdxRowid" OpHelp("r[P2]=rowid"), | |
| 24019 | + /* 111 */ "IdxLE" OpHelp("key=r[P3@P4]"), | |
| 24020 | + /* 112 */ "IdxGT" OpHelp("key=r[P3@P4]"), | |
| 24021 | + /* 113 */ "IdxLT" OpHelp("key=r[P3@P4]"), | |
| 24022 | + /* 114 */ "IdxGE" OpHelp("key=r[P3@P4]"), | |
| 24023 | + /* 115 */ "Destroy" OpHelp(""), | |
| 24024 | + /* 116 */ "Clear" OpHelp(""), | |
| 24025 | + /* 117 */ "ResetSorter" OpHelp(""), | |
| 24026 | + /* 118 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), | |
| 24027 | + /* 119 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), | |
| 24028 | + /* 120 */ "ParseSchema" OpHelp(""), | |
| 24029 | + /* 121 */ "LoadAnalysis" OpHelp(""), | |
| 24030 | + /* 122 */ "DropTable" OpHelp(""), | |
| 24031 | + /* 123 */ "DropIndex" OpHelp(""), | |
| 24032 | + /* 124 */ "DropTrigger" OpHelp(""), | |
| 24033 | + /* 125 */ "IntegrityCk" OpHelp(""), | |
| 24034 | + /* 126 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), | |
| 24035 | + /* 127 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), | |
| 24036 | + /* 128 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | |
| 24037 | + /* 129 */ "Program" OpHelp(""), | |
| 24038 | + /* 130 */ "Param" OpHelp(""), | |
| 24039 | + /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), | |
| 24040 | + /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | |
| 23692 | 24041 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23693 | - /* 134 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), | |
| 23694 | - /* 135 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), | |
| 23695 | - /* 136 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), | |
| 23696 | - /* 137 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), | |
| 23697 | - /* 138 */ "IncrVacuum" OpHelp(""), | |
| 23698 | - /* 139 */ "Expire" OpHelp(""), | |
| 23699 | - /* 140 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), | |
| 23700 | - /* 141 */ "VBegin" OpHelp(""), | |
| 23701 | - /* 142 */ "VCreate" OpHelp(""), | |
| 24042 | + /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), | |
| 24043 | + /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), | |
| 24044 | + /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), | |
| 24045 | + /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), | |
| 24046 | + /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), | |
| 24047 | + /* 139 */ "IncrVacuum" OpHelp(""), | |
| 24048 | + /* 140 */ "Expire" OpHelp(""), | |
| 24049 | + /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), | |
| 24050 | + /* 142 */ "VBegin" OpHelp(""), | |
| 23702 | 24051 | /* 143 */ "ToText" OpHelp(""), |
| 23703 | 24052 | /* 144 */ "ToBlob" OpHelp(""), |
| 23704 | 24053 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23705 | 24054 | /* 146 */ "ToInt" OpHelp(""), |
| 23706 | 24055 | /* 147 */ "ToReal" OpHelp(""), |
| 23707 | - /* 148 */ "VDestroy" OpHelp(""), | |
| 23708 | - /* 149 */ "VOpen" OpHelp(""), | |
| 23709 | - /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), | |
| 23710 | - /* 151 */ "VNext" OpHelp(""), | |
| 23711 | - /* 152 */ "VRename" OpHelp(""), | |
| 23712 | - /* 153 */ "Pagecount" OpHelp(""), | |
| 23713 | - /* 154 */ "MaxPgcnt" OpHelp(""), | |
| 23714 | - /* 155 */ "Init" OpHelp("Start at P2"), | |
| 23715 | - /* 156 */ "Noop" OpHelp(""), | |
| 23716 | - /* 157 */ "Explain" OpHelp(""), | |
| 24056 | + /* 148 */ "VCreate" OpHelp(""), | |
| 24057 | + /* 149 */ "VDestroy" OpHelp(""), | |
| 24058 | + /* 150 */ "VOpen" OpHelp(""), | |
| 24059 | + /* 151 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), | |
| 24060 | + /* 152 */ "VNext" OpHelp(""), | |
| 24061 | + /* 153 */ "VRename" OpHelp(""), | |
| 24062 | + /* 154 */ "Pagecount" OpHelp(""), | |
| 24063 | + /* 155 */ "MaxPgcnt" OpHelp(""), | |
| 24064 | + /* 156 */ "Init" OpHelp("Start at P2"), | |
| 24065 | + /* 157 */ "Noop" OpHelp(""), | |
| 24066 | + /* 158 */ "Explain" OpHelp(""), | |
| 23717 | 24067 | }; |
| 23718 | 24068 | return azName[i]; |
| 23719 | 24069 | } |
| 23720 | 24070 | #endif |
| 23721 | 24071 | |
| @@ -32066,14 +32416,14 @@ | ||
| 32066 | 32416 | ** |
| 32067 | 32417 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32068 | 32418 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32069 | 32419 | */ |
| 32070 | 32420 | #ifdef SQLITE_TEST |
| 32071 | -SQLITE_API int sqlite3_os_type = 0; | |
| 32421 | +SQLITE_API LONG volatile sqlite3_os_type = 0; | |
| 32072 | 32422 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32073 | 32423 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32074 | -static int sqlite3_os_type = 0; | |
| 32424 | +static LONG volatile sqlite3_os_type = 0; | |
| 32075 | 32425 | #endif |
| 32076 | 32426 | |
| 32077 | 32427 | #ifndef SYSCALL |
| 32078 | 32428 | # define SYSCALL sqlite3_syscall_ptr |
| 32079 | 32429 | #endif |
| @@ -32699,10 +33049,15 @@ | ||
| 32699 | 33049 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 32700 | 33050 | #endif |
| 32701 | 33051 | |
| 32702 | 33052 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 32703 | 33053 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 33054 | + | |
| 33055 | + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, | |
| 33056 | + | |
| 33057 | +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \ | |
| 33058 | + LONG,LONG))aSyscall[76].pCurrent) | |
| 32704 | 33059 | |
| 32705 | 33060 | }; /* End of the overrideable system calls */ |
| 32706 | 33061 | |
| 32707 | 33062 | /* |
| 32708 | 33063 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | ||
| 32950 | 33305 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32951 | 33306 | # define osIsNT() (1) |
| 32952 | 33307 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32953 | 33308 | # define osIsNT() (0) |
| 32954 | 33309 | #else |
| 32955 | - static int osIsNT(void){ | |
| 32956 | - if( sqlite3_os_type==0 ){ | |
| 33310 | +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) | |
| 33311 | +#endif | |
| 33312 | + | |
| 33313 | +/* | |
| 33314 | +** This function determines if the machine is running a version of Windows | |
| 33315 | +** based on the NT kernel. | |
| 33316 | +*/ | |
| 33317 | +SQLITE_API int sqlite3_win32_is_nt(void){ | |
| 33318 | + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ | |
| 32957 | 33319 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 32958 | - OSVERSIONINFOW sInfo; | |
| 32959 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 32960 | - osGetVersionExW(&sInfo); | |
| 33320 | + OSVERSIONINFOW sInfo; | |
| 33321 | + sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 33322 | + osGetVersionExW(&sInfo); | |
| 32961 | 33323 | #else |
| 32962 | - OSVERSIONINFOA sInfo; | |
| 32963 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 32964 | - osGetVersionExA(&sInfo); | |
| 32965 | -#endif | |
| 32966 | - sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; | |
| 32967 | - } | |
| 32968 | - return sqlite3_os_type==2; | |
| 32969 | - } | |
| 32970 | -#endif | |
| 33324 | + OSVERSIONINFOA sInfo; | |
| 33325 | + sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 33326 | + osGetVersionExA(&sInfo); | |
| 33327 | +#endif | |
| 33328 | + osInterlockedCompareExchange(&sqlite3_os_type, | |
| 33329 | + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); | |
| 33330 | + } | |
| 33331 | + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; | |
| 33332 | +} | |
| 32971 | 33333 | |
| 32972 | 33334 | #ifdef SQLITE_WIN32_MALLOC |
| 32973 | 33335 | /* |
| 32974 | 33336 | ** Allocate nBytes of memory. |
| 32975 | 33337 | */ |
| @@ -37121,11 +37483,11 @@ | ||
| 37121 | 37483 | }; |
| 37122 | 37484 | #endif |
| 37123 | 37485 | |
| 37124 | 37486 | /* Double-check that the aSyscall[] array has been constructed |
| 37125 | 37487 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37126 | - assert( ArraySize(aSyscall)==76 ); | |
| 37488 | + assert( ArraySize(aSyscall)==77 ); | |
| 37127 | 37489 | |
| 37128 | 37490 | /* get memory map allocation granularity */ |
| 37129 | 37491 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37130 | 37492 | #if SQLITE_OS_WINRT |
| 37131 | 37493 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | ||
| 52813 | 53175 | return pBt->nPage; |
| 52814 | 53176 | } |
| 52815 | 53177 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 52816 | 53178 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52817 | 53179 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 52818 | - return (int)btreePagecount(p->pBt); | |
| 53180 | + return btreePagecount(p->pBt); | |
| 52819 | 53181 | } |
| 52820 | 53182 | |
| 52821 | 53183 | /* |
| 52822 | 53184 | ** Get a page from the pager and initialize it. This routine is just a |
| 52823 | 53185 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | ||
| 62354 | 62716 | } |
| 62355 | 62717 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62356 | 62718 | pParse->aLabel = 0; |
| 62357 | 62719 | pParse->nLabel = 0; |
| 62358 | 62720 | *pMaxFuncArgs = nMaxArgs; |
| 62359 | - assert( p->bIsReader!=0 || p->btreeMask==0 ); | |
| 62721 | + assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); | |
| 62360 | 62722 | } |
| 62361 | 62723 | |
| 62362 | 62724 | /* |
| 62363 | 62725 | ** Return the address of the next instruction to be inserted. |
| 62364 | 62726 | */ |
| @@ -62381,11 +62743,11 @@ | ||
| 62381 | 62743 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62382 | 62744 | VdbeOp *aOp = p->aOp; |
| 62383 | 62745 | assert( aOp && !p->db->mallocFailed ); |
| 62384 | 62746 | |
| 62385 | 62747 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62386 | - assert( p->btreeMask==0 ); | |
| 62748 | + assert( DbMaskAllZero(p->btreeMask) ); | |
| 62387 | 62749 | |
| 62388 | 62750 | resolveP2Values(p, pnMaxArg); |
| 62389 | 62751 | *pnOp = p->nOp; |
| 62390 | 62752 | p->aOp = 0; |
| 62391 | 62753 | return aOp; |
| @@ -62966,13 +63328,13 @@ | ||
| 62966 | 63328 | ** p->btreeMask of databases that will require a lock. |
| 62967 | 63329 | */ |
| 62968 | 63330 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 62969 | 63331 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 62970 | 63332 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 62971 | - p->btreeMask |= ((yDbMask)1)<<i; | |
| 63333 | + DbMaskSet(p->btreeMask, i); | |
| 62972 | 63334 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 62973 | - p->lockMask |= ((yDbMask)1)<<i; | |
| 63335 | + DbMaskSet(p->lockMask, i); | |
| 62974 | 63336 | } |
| 62975 | 63337 | } |
| 62976 | 63338 | |
| 62977 | 63339 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 62978 | 63340 | /* |
| @@ -62996,20 +63358,19 @@ | ||
| 62996 | 63358 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 62997 | 63359 | ** be a problem. |
| 62998 | 63360 | */ |
| 62999 | 63361 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63000 | 63362 | int i; |
| 63001 | - yDbMask mask; | |
| 63002 | 63363 | sqlite3 *db; |
| 63003 | 63364 | Db *aDb; |
| 63004 | 63365 | int nDb; |
| 63005 | - if( p->lockMask==0 ) return; /* The common case */ | |
| 63366 | + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ | |
| 63006 | 63367 | db = p->db; |
| 63007 | 63368 | aDb = db->aDb; |
| 63008 | 63369 | nDb = db->nDb; |
| 63009 | - for(i=0, mask=1; i<nDb; i++, mask += mask){ | |
| 63010 | - if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63370 | + for(i=0; i<nDb; i++){ | |
| 63371 | + if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63011 | 63372 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63012 | 63373 | } |
| 63013 | 63374 | } |
| 63014 | 63375 | } |
| 63015 | 63376 | #endif |
| @@ -63018,20 +63379,19 @@ | ||
| 63018 | 63379 | /* |
| 63019 | 63380 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63020 | 63381 | */ |
| 63021 | 63382 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63022 | 63383 | int i; |
| 63023 | - yDbMask mask; | |
| 63024 | 63384 | sqlite3 *db; |
| 63025 | 63385 | Db *aDb; |
| 63026 | 63386 | int nDb; |
| 63027 | - if( p->lockMask==0 ) return; /* The common case */ | |
| 63387 | + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ | |
| 63028 | 63388 | db = p->db; |
| 63029 | 63389 | aDb = db->aDb; |
| 63030 | 63390 | nDb = db->nDb; |
| 63031 | - for(i=0, mask=1; i<nDb; i++, mask += mask){ | |
| 63032 | - if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63391 | + for(i=0; i<nDb; i++){ | |
| 63392 | + if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63033 | 63393 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63034 | 63394 | } |
| 63035 | 63395 | } |
| 63036 | 63396 | } |
| 63037 | 63397 | #endif |
| @@ -63998,11 +64358,11 @@ | ||
| 63998 | 64358 | int cnt = 0; |
| 63999 | 64359 | int nWrite = 0; |
| 64000 | 64360 | int nRead = 0; |
| 64001 | 64361 | p = db->pVdbe; |
| 64002 | 64362 | while( p ){ |
| 64003 | - if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ | |
| 64363 | + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ | |
| 64004 | 64364 | cnt++; |
| 64005 | 64365 | if( p->readOnly==0 ) nWrite++; |
| 64006 | 64366 | if( p->bIsReader ) nRead++; |
| 64007 | 64367 | } |
| 64008 | 64368 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | ||
| 64643 | 65003 | /* |
| 64644 | 65004 | ** Return the serial-type for the value stored in pMem. |
| 64645 | 65005 | */ |
| 64646 | 65006 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 64647 | 65007 | int flags = pMem->flags; |
| 64648 | - int n; | |
| 65008 | + u32 n; | |
| 64649 | 65009 | |
| 64650 | 65010 | if( flags&MEM_Null ){ |
| 64651 | 65011 | return 0; |
| 64652 | 65012 | } |
| 64653 | 65013 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | ||
| 64673 | 65033 | } |
| 64674 | 65034 | if( flags&MEM_Real ){ |
| 64675 | 65035 | return 7; |
| 64676 | 65036 | } |
| 64677 | 65037 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 64678 | - n = pMem->n; | |
| 65038 | + assert( pMem->n>=0 ); | |
| 65039 | + n = (u32)pMem->n; | |
| 64679 | 65040 | if( flags & MEM_Zero ){ |
| 64680 | 65041 | n += pMem->u.nZero; |
| 64681 | 65042 | } |
| 64682 | - assert( n>=0 ); | |
| 64683 | 65043 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 64684 | 65044 | } |
| 64685 | 65045 | |
| 64686 | 65046 | /* |
| 64687 | 65047 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | ||
| 67195 | 67555 | /* |
| 67196 | 67556 | ** Return true if the prepared statement is in need of being reset. |
| 67197 | 67557 | */ |
| 67198 | 67558 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67199 | 67559 | Vdbe *v = (Vdbe*)pStmt; |
| 67200 | - return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; | |
| 67560 | + return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; | |
| 67201 | 67561 | } |
| 67202 | 67562 | |
| 67203 | 67563 | /* |
| 67204 | 67564 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67205 | 67565 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | ||
| 67753 | 68113 | ** do so without loss of information. In other words, if the string |
| 67754 | 68114 | ** looks like a number, convert it into a number. If it does not |
| 67755 | 68115 | ** look like a number, leave it alone. |
| 67756 | 68116 | */ |
| 67757 | 68117 | static void applyNumericAffinity(Mem *pRec){ |
| 67758 | - if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ | |
| 67759 | - double rValue; | |
| 67760 | - i64 iValue; | |
| 67761 | - u8 enc = pRec->enc; | |
| 67762 | - if( (pRec->flags&MEM_Str)==0 ) return; | |
| 67763 | - if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | |
| 67764 | - if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | |
| 67765 | - pRec->u.i = iValue; | |
| 67766 | - pRec->flags |= MEM_Int; | |
| 67767 | - }else{ | |
| 67768 | - pRec->r = rValue; | |
| 67769 | - pRec->flags |= MEM_Real; | |
| 67770 | - } | |
| 67771 | - } | |
| 67772 | -} | |
| 68118 | + double rValue; | |
| 68119 | + i64 iValue; | |
| 68120 | + u8 enc = pRec->enc; | |
| 68121 | + if( (pRec->flags&MEM_Str)==0 ) return; | |
| 68122 | + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | |
| 68123 | + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | |
| 68124 | + pRec->u.i = iValue; | |
| 68125 | + pRec->flags |= MEM_Int; | |
| 68126 | + }else{ | |
| 68127 | + pRec->r = rValue; | |
| 68128 | + pRec->flags |= MEM_Real; | |
| 68129 | + } | |
| 68130 | +} | |
| 68131 | +#define ApplyNumericAffinity(X) \ | |
| 68132 | + if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} | |
| 67773 | 68133 | |
| 67774 | 68134 | /* |
| 67775 | 68135 | ** Processing is determine by the affinity parameter: |
| 67776 | 68136 | ** |
| 67777 | 68137 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | ||
| 67804 | 68164 | } |
| 67805 | 68165 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 67806 | 68166 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 67807 | 68167 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 67808 | 68168 | || affinity==SQLITE_AFF_NUMERIC ); |
| 67809 | - applyNumericAffinity(pRec); | |
| 68169 | + ApplyNumericAffinity(pRec); | |
| 67810 | 68170 | if( pRec->flags & MEM_Real ){ |
| 67811 | 68171 | sqlite3VdbeIntegerAffinity(pRec); |
| 67812 | 68172 | } |
| 67813 | 68173 | } |
| 67814 | 68174 | } |
| @@ -68385,16 +68745,18 @@ | ||
| 68385 | 68745 | break; |
| 68386 | 68746 | } |
| 68387 | 68747 | |
| 68388 | 68748 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68389 | 68749 | ** |
| 68390 | -** Set up register P1 so that it will OP_Yield to the co-routine | |
| 68750 | +** Set up register P1 so that it will Yield to the coroutine | |
| 68391 | 68751 | ** located at address P3. |
| 68392 | 68752 | ** |
| 68393 | -** If P2!=0 then the co-routine implementation immediately follows | |
| 68394 | -** this opcode. So jump over the co-routine implementation to | |
| 68753 | +** If P2!=0 then the coroutine implementation immediately follows | |
| 68754 | +** this opcode. So jump over the coroutine implementation to | |
| 68395 | 68755 | ** address P2. |
| 68756 | +** | |
| 68757 | +** See also: EndCoroutine | |
| 68396 | 68758 | */ |
| 68397 | 68759 | case OP_InitCoroutine: { /* jump */ |
| 68398 | 68760 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68399 | 68761 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68400 | 68762 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | ||
| 68406 | 68768 | break; |
| 68407 | 68769 | } |
| 68408 | 68770 | |
| 68409 | 68771 | /* Opcode: EndCoroutine P1 * * * * |
| 68410 | 68772 | ** |
| 68411 | -** The instruction at the address in register P1 is an OP_Yield. | |
| 68412 | -** Jump to the P2 parameter of that OP_Yield. | |
| 68773 | +** The instruction at the address in register P1 is an Yield. | |
| 68774 | +** Jump to the P2 parameter of that Yield. | |
| 68413 | 68775 | ** After the jump, register P1 becomes undefined. |
| 68776 | +** | |
| 68777 | +** See also: InitCoroutine | |
| 68414 | 68778 | */ |
| 68415 | 68779 | case OP_EndCoroutine: { /* in1 */ |
| 68416 | 68780 | VdbeOp *pCaller; |
| 68417 | 68781 | pIn1 = &aMem[pOp->p1]; |
| 68418 | 68782 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | ||
| 68425 | 68789 | break; |
| 68426 | 68790 | } |
| 68427 | 68791 | |
| 68428 | 68792 | /* Opcode: Yield P1 P2 * * * |
| 68429 | 68793 | ** |
| 68430 | -** Swap the program counter with the value in register P1. | |
| 68794 | +** Swap the program counter with the value in register P1. This | |
| 68795 | +** has the effect of yielding to a coroutine. | |
| 68431 | 68796 | ** |
| 68432 | -** If the co-routine ends with OP_Yield or OP_Return then continue | |
| 68433 | -** to the next instruction. But if the co-routine ends with | |
| 68434 | -** OP_EndCoroutine, jump immediately to P2. | |
| 68797 | +** If the coroutine that is launched by this instruction ends with | |
| 68798 | +** Yield or Return then continue to the next instruction. But if | |
| 68799 | +** the coroutine launched by this instruction ends with | |
| 68800 | +** EndCoroutine, then jump to P2 rather than continuing with the | |
| 68801 | +** next instruction. | |
| 68802 | +** | |
| 68803 | +** See also: InitCoroutine | |
| 68435 | 68804 | */ |
| 68436 | 68805 | case OP_Yield: { /* in1, jump */ |
| 68437 | 68806 | int pcDest; |
| 68438 | 68807 | pIn1 = &aMem[pOp->p1]; |
| 68439 | 68808 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | ||
| 69814 | 70183 | break; |
| 69815 | 70184 | } |
| 69816 | 70185 | |
| 69817 | 70186 | /* Opcode: Once P1 P2 * * * |
| 69818 | 70187 | ** |
| 69819 | -** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, | |
| 69820 | -** set the flag and fall through to the next instruction. In other words, | |
| 69821 | -** this opcode causes all following opcodes up through P2 (but not including | |
| 69822 | -** P2) to run just once and to be skipped on subsequent times through the loop. | |
| 70188 | +** Check the "once" flag number P1. If it is set, jump to instruction P2. | |
| 70189 | +** Otherwise, set the flag and fall through to the next instruction. | |
| 70190 | +** In other words, this opcode causes all following opcodes up through P2 | |
| 70191 | +** (but not including P2) to run just once and to be skipped on subsequent | |
| 70192 | +** times through the loop. | |
| 70193 | +** | |
| 70194 | +** All "once" flags are initially cleared whenever a prepared statement | |
| 70195 | +** first begins to run. | |
| 69823 | 70196 | */ |
| 69824 | 70197 | case OP_Once: { /* jump */ |
| 69825 | 70198 | assert( pOp->p1<p->nOnceFlag ); |
| 69826 | 70199 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 69827 | 70200 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | ||
| 70652 | 71025 | int iGen; |
| 70653 | 71026 | |
| 70654 | 71027 | assert( p->bIsReader ); |
| 70655 | 71028 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 70656 | 71029 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70657 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 71030 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 70658 | 71031 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 70659 | 71032 | rc = SQLITE_READONLY; |
| 70660 | 71033 | goto abort_due_to_error; |
| 70661 | 71034 | } |
| 70662 | 71035 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | ||
| 70747 | 71120 | iDb = pOp->p1; |
| 70748 | 71121 | iCookie = pOp->p3; |
| 70749 | 71122 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 70750 | 71123 | assert( iDb>=0 && iDb<db->nDb ); |
| 70751 | 71124 | assert( db->aDb[iDb].pBt!=0 ); |
| 70752 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 71125 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 70753 | 71126 | |
| 70754 | 71127 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 70755 | 71128 | pOut->u.i = iMeta; |
| 70756 | 71129 | break; |
| 70757 | 71130 | } |
| @@ -70768,11 +71141,11 @@ | ||
| 70768 | 71141 | */ |
| 70769 | 71142 | case OP_SetCookie: { /* in3 */ |
| 70770 | 71143 | Db *pDb; |
| 70771 | 71144 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 70772 | 71145 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70773 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 71146 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 70774 | 71147 | assert( p->readOnly==0 ); |
| 70775 | 71148 | pDb = &db->aDb[pOp->p1]; |
| 70776 | 71149 | assert( pDb->pBt!=0 ); |
| 70777 | 71150 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 70778 | 71151 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | ||
| 70823 | 71196 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 70824 | 71197 | ** structure, then said structure defines the content and collating |
| 70825 | 71198 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 70826 | 71199 | ** value, it is set to the number of columns in the table. |
| 70827 | 71200 | ** |
| 70828 | -** See also OpenWrite. | |
| 71201 | +** See also: OpenWrite, ReopenIdx | |
| 71202 | +*/ | |
| 71203 | +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 | |
| 71204 | +** Synopsis: root=P2 iDb=P3 | |
| 71205 | +** | |
| 71206 | +** The ReopenIdx opcode works exactly like ReadOpen except that it first | |
| 71207 | +** checks to see if the cursor on P1 is already open with a root page | |
| 71208 | +** number of P2 and if it is this opcode becomes a no-op. In other words, | |
| 71209 | +** if the cursor is already open, do not reopen it. | |
| 71210 | +** | |
| 71211 | +** The ReopenIdx opcode may only be used with P5==0 and with P4 being | |
| 71212 | +** a P4_KEYINFO object. Furthermore, the P3 value must be the same as | |
| 71213 | +** every other ReopenIdx or OpenRead for the same cursor number. | |
| 71214 | +** | |
| 71215 | +** See the OpenRead opcode documentation for additional information. | |
| 70829 | 71216 | */ |
| 70830 | 71217 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 70831 | 71218 | ** Synopsis: root=P2 iDb=P3 |
| 70832 | 71219 | ** |
| 70833 | 71220 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | ||
| 70845 | 71232 | ** in read/write mode. For a given table, there can be one or more read-only |
| 70846 | 71233 | ** cursors or a single read/write cursor but not both. |
| 70847 | 71234 | ** |
| 70848 | 71235 | ** See also OpenRead. |
| 70849 | 71236 | */ |
| 71237 | +case OP_ReopenIdx: { | |
| 71238 | + VdbeCursor *pCur; | |
| 71239 | + | |
| 71240 | + assert( pOp->p5==0 ); | |
| 71241 | + assert( pOp->p4type==P4_KEYINFO ); | |
| 71242 | + pCur = p->apCsr[pOp->p1]; | |
| 71243 | + if( pCur && pCur->pgnoRoot==pOp->p2 ){ | |
| 71244 | + assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ | |
| 71245 | + break; | |
| 71246 | + } | |
| 71247 | + /* If the cursor is not currently open or is open on a different | |
| 71248 | + ** index, then fall through into OP_OpenRead to force a reopen */ | |
| 71249 | +} | |
| 70850 | 71250 | case OP_OpenRead: |
| 70851 | 71251 | case OP_OpenWrite: { |
| 70852 | 71252 | int nField; |
| 70853 | 71253 | KeyInfo *pKeyInfo; |
| 70854 | 71254 | int p2; |
| @@ -70859,11 +71259,12 @@ | ||
| 70859 | 71259 | Db *pDb; |
| 70860 | 71260 | |
| 70861 | 71261 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 70862 | 71262 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 70863 | 71263 | assert( p->bIsReader ); |
| 70864 | - assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); | |
| 71264 | + assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx | |
| 71265 | + || p->readOnly==0 ); | |
| 70865 | 71266 | |
| 70866 | 71267 | if( p->expired ){ |
| 70867 | 71268 | rc = SQLITE_ABORT; |
| 70868 | 71269 | break; |
| 70869 | 71270 | } |
| @@ -70871,11 +71272,11 @@ | ||
| 70871 | 71272 | nField = 0; |
| 70872 | 71273 | pKeyInfo = 0; |
| 70873 | 71274 | p2 = pOp->p2; |
| 70874 | 71275 | iDb = pOp->p3; |
| 70875 | 71276 | assert( iDb>=0 && iDb<db->nDb ); |
| 70876 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 71277 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 70877 | 71278 | pDb = &db->aDb[iDb]; |
| 70878 | 71279 | pX = pDb->pBt; |
| 70879 | 71280 | assert( pX!=0 ); |
| 70880 | 71281 | if( pOp->opcode==OP_OpenWrite ){ |
| 70881 | 71282 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | ||
| 70916 | 71317 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 70917 | 71318 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 70918 | 71319 | if( pCur==0 ) goto no_mem; |
| 70919 | 71320 | pCur->nullRow = 1; |
| 70920 | 71321 | pCur->isOrdered = 1; |
| 71322 | + pCur->pgnoRoot = p2; | |
| 70921 | 71323 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 70922 | 71324 | pCur->pKeyInfo = pKeyInfo; |
| 70923 | 71325 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 70924 | 71326 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 70925 | 71327 | |
| @@ -71070,11 +71472,11 @@ | ||
| 71070 | 71472 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71071 | 71473 | p->apCsr[pOp->p1] = 0; |
| 71072 | 71474 | break; |
| 71073 | 71475 | } |
| 71074 | 71476 | |
| 71075 | -/* Opcode: SeekGe P1 P2 P3 P4 * | |
| 71477 | +/* Opcode: SeekGE P1 P2 P3 P4 * | |
| 71076 | 71478 | ** Synopsis: key=r[P3@P4] |
| 71077 | 71479 | ** |
| 71078 | 71480 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71079 | 71481 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71080 | 71482 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | ||
| 71081 | 71483 | ** that are used as an unpacked index key. |
| 71082 | 71484 | ** |
| 71083 | 71485 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71084 | 71486 | ** is greater than or equal to the key value. If there are no records |
| 71085 | 71487 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71488 | +** | |
| 71489 | +** This opcode leaves the cursor configured to move in forward order, | |
| 71490 | +** from the begining toward the end. In other words, the cursor is | |
| 71491 | +** configured to use Next, not Prev. | |
| 71086 | 71492 | ** |
| 71087 | 71493 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71088 | 71494 | */ |
| 71089 | -/* Opcode: SeekGt P1 P2 P3 P4 * | |
| 71495 | +/* Opcode: SeekGT P1 P2 P3 P4 * | |
| 71090 | 71496 | ** Synopsis: key=r[P3@P4] |
| 71091 | 71497 | ** |
| 71092 | 71498 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71093 | 71499 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71094 | 71500 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | ||
| 71095 | 71501 | ** that are used as an unpacked index key. |
| 71096 | 71502 | ** |
| 71097 | 71503 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71098 | 71504 | ** is greater than the key value. If there are no records greater than |
| 71099 | 71505 | ** the key and P2 is not zero, then jump to P2. |
| 71506 | +** | |
| 71507 | +** This opcode leaves the cursor configured to move in forward order, | |
| 71508 | +** from the begining toward the end. In other words, the cursor is | |
| 71509 | +** configured to use Next, not Prev. | |
| 71100 | 71510 | ** |
| 71101 | 71511 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71102 | 71512 | */ |
| 71103 | -/* Opcode: SeekLt P1 P2 P3 P4 * | |
| 71513 | +/* Opcode: SeekLT P1 P2 P3 P4 * | |
| 71104 | 71514 | ** Synopsis: key=r[P3@P4] |
| 71105 | 71515 | ** |
| 71106 | 71516 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71107 | 71517 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71108 | 71518 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | ||
| 71109 | 71519 | ** that are used as an unpacked index key. |
| 71110 | 71520 | ** |
| 71111 | 71521 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71112 | 71522 | ** is less than the key value. If there are no records less than |
| 71113 | 71523 | ** the key and P2 is not zero, then jump to P2. |
| 71524 | +** | |
| 71525 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 71526 | +** from the end toward the beginning. In other words, the cursor is | |
| 71527 | +** configured to use Prev, not Next. | |
| 71114 | 71528 | ** |
| 71115 | 71529 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71116 | 71530 | */ |
| 71117 | -/* Opcode: SeekLe P1 P2 P3 P4 * | |
| 71531 | +/* Opcode: SeekLE P1 P2 P3 P4 * | |
| 71118 | 71532 | ** Synopsis: key=r[P3@P4] |
| 71119 | 71533 | ** |
| 71120 | 71534 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71121 | 71535 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71122 | 71536 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | ||
| 71123 | 71537 | ** that are used as an unpacked index key. |
| 71124 | 71538 | ** |
| 71125 | 71539 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71126 | 71540 | ** is less than or equal to the key value. If there are no records |
| 71127 | 71541 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71542 | +** | |
| 71543 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 71544 | +** from the end toward the beginning. In other words, the cursor is | |
| 71545 | +** configured to use Prev, not Next. | |
| 71128 | 71546 | ** |
| 71129 | 71547 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71130 | 71548 | */ |
| 71131 | 71549 | case OP_SeekLT: /* jump, in3 */ |
| 71132 | 71550 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | ||
| 71149 | 71567 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71150 | 71568 | assert( pC->isOrdered ); |
| 71151 | 71569 | assert( pC->pCursor!=0 ); |
| 71152 | 71570 | oc = pOp->opcode; |
| 71153 | 71571 | pC->nullRow = 0; |
| 71572 | +#ifdef SQLITE_DEBUG | |
| 71573 | + pC->seekOp = pOp->opcode; | |
| 71574 | +#endif | |
| 71154 | 71575 | if( pC->isTable ){ |
| 71155 | 71576 | /* The input value in P3 might be of any type: integer, real, string, |
| 71156 | 71577 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71157 | 71578 | ** the seek, so covert it. */ |
| 71158 | 71579 | pIn3 = &aMem[pOp->p3]; |
| 71159 | - applyNumericAffinity(pIn3); | |
| 71580 | + ApplyNumericAffinity(pIn3); | |
| 71160 | 71581 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71161 | 71582 | pC->rowidIsValid = 0; |
| 71162 | 71583 | |
| 71163 | 71584 | /* If the P3 value could not be converted into an integer without |
| 71164 | 71585 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | ||
| 71303 | 71724 | ** record. |
| 71304 | 71725 | ** |
| 71305 | 71726 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71306 | 71727 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71307 | 71728 | ** P1 is left pointing at the matching entry. |
| 71729 | +** | |
| 71730 | +** This operation leaves the cursor in a state where it cannot be | |
| 71731 | +** advanced in either direction. In other words, the Next and Prev | |
| 71732 | +** opcodes do not work after this operation. | |
| 71308 | 71733 | ** |
| 71309 | 71734 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71310 | 71735 | */ |
| 71311 | 71736 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71312 | 71737 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | ||
| 71318 | 71743 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71319 | 71744 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71320 | 71745 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71321 | 71746 | ** falls through to the next instruction and P1 is left pointing at the |
| 71322 | 71747 | ** matching entry. |
| 71748 | +** | |
| 71749 | +** This operation leaves the cursor in a state where it cannot be | |
| 71750 | +** advanced in either direction. In other words, the Next and Prev | |
| 71751 | +** opcodes do not work after this operation. | |
| 71323 | 71752 | ** |
| 71324 | 71753 | ** See also: Found, NotExists, NoConflict |
| 71325 | 71754 | */ |
| 71326 | 71755 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71327 | 71756 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | ||
| 71337 | 71766 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71338 | 71767 | ** cursor pointing to the matching row. |
| 71339 | 71768 | ** |
| 71340 | 71769 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71341 | 71770 | ** branch is always taken if any part of the search key input is NULL. |
| 71771 | +** | |
| 71772 | +** This operation leaves the cursor in a state where it cannot be | |
| 71773 | +** advanced in either direction. In other words, the Next and Prev | |
| 71774 | +** opcodes do not work after this operation. | |
| 71342 | 71775 | ** |
| 71343 | 71776 | ** See also: NotFound, Found, NotExists |
| 71344 | 71777 | */ |
| 71345 | 71778 | case OP_NoConflict: /* jump, in3 */ |
| 71346 | 71779 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | ||
| 71360 | 71793 | |
| 71361 | 71794 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71362 | 71795 | assert( pOp->p4type==P4_INT32 ); |
| 71363 | 71796 | pC = p->apCsr[pOp->p1]; |
| 71364 | 71797 | assert( pC!=0 ); |
| 71798 | +#ifdef SQLITE_DEBUG | |
| 71799 | + pC->seekOp = 0; | |
| 71800 | +#endif | |
| 71365 | 71801 | pIn3 = &aMem[pOp->p3]; |
| 71366 | 71802 | assert( pC->pCursor!=0 ); |
| 71367 | 71803 | assert( pC->isTable==0 ); |
| 71368 | 71804 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71369 | 71805 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | ||
| 71430 | 71866 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71431 | 71867 | ** through to the next instruction. |
| 71432 | 71868 | ** |
| 71433 | 71869 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71434 | 71870 | ** (with arbitrary multi-value keys). |
| 71871 | +** | |
| 71872 | +** This opcode leaves the cursor in a state where it cannot be advanced | |
| 71873 | +** in either direction. In other words, the Next and Prev opcodes will | |
| 71874 | +** not work following this opcode. | |
| 71435 | 71875 | ** |
| 71436 | 71876 | ** See also: Found, NotFound, NoConflict |
| 71437 | 71877 | */ |
| 71438 | 71878 | case OP_NotExists: { /* jump, in3 */ |
| 71439 | 71879 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | ||
| 71444 | 71884 | pIn3 = &aMem[pOp->p3]; |
| 71445 | 71885 | assert( pIn3->flags & MEM_Int ); |
| 71446 | 71886 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71447 | 71887 | pC = p->apCsr[pOp->p1]; |
| 71448 | 71888 | assert( pC!=0 ); |
| 71889 | +#ifdef SQLITE_DEBUG | |
| 71890 | + pC->seekOp = 0; | |
| 71891 | +#endif | |
| 71449 | 71892 | assert( pC->isTable ); |
| 71450 | 71893 | assert( pC->pseudoTableReg==0 ); |
| 71451 | 71894 | pCrsr = pC->pCursor; |
| 71452 | 71895 | assert( pCrsr!=0 ); |
| 71453 | 71896 | res = 0; |
| @@ -71806,16 +72249,16 @@ | ||
| 71806 | 72249 | p->nChange = 0; |
| 71807 | 72250 | break; |
| 71808 | 72251 | } |
| 71809 | 72252 | |
| 71810 | 72253 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 71811 | -** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 | |
| 72254 | +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 | |
| 71812 | 72255 | ** |
| 71813 | 72256 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 71814 | 72257 | ** the record blob in register P3 against a prefix of the entry that |
| 71815 | -** the sorter cursor currently points to. The final P4 fields of both | |
| 71816 | -** the P3 and sorter record are ignored. | |
| 72258 | +** the sorter cursor currently points to. Only the first P4 fields | |
| 72259 | +** of r[P3] and the sorter record are compared. | |
| 71817 | 72260 | ** |
| 71818 | 72261 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 71819 | 72262 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 71820 | 72263 | ** the comparison is assumed to be equal. |
| 71821 | 72264 | ** |
| @@ -71823,18 +72266,18 @@ | ||
| 71823 | 72266 | ** each other. Jump to P2 if they are different. |
| 71824 | 72267 | */ |
| 71825 | 72268 | case OP_SorterCompare: { |
| 71826 | 72269 | VdbeCursor *pC; |
| 71827 | 72270 | int res; |
| 71828 | - int nIgnore; | |
| 72271 | + int nKeyCol; | |
| 71829 | 72272 | |
| 71830 | 72273 | pC = p->apCsr[pOp->p1]; |
| 71831 | 72274 | assert( isSorter(pC) ); |
| 71832 | 72275 | assert( pOp->p4type==P4_INT32 ); |
| 71833 | 72276 | pIn3 = &aMem[pOp->p3]; |
| 71834 | - nIgnore = pOp->p4.i; | |
| 71835 | - rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); | |
| 72277 | + nKeyCol = pOp->p4.i; | |
| 72278 | + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); | |
| 71836 | 72279 | VdbeBranchTaken(res!=0,2); |
| 71837 | 72280 | if( res ){ |
| 71838 | 72281 | pc = pOp->p2-1; |
| 71839 | 72282 | } |
| 71840 | 72283 | break; |
| @@ -72010,15 +72453,19 @@ | ||
| 72010 | 72453 | break; |
| 72011 | 72454 | } |
| 72012 | 72455 | |
| 72013 | 72456 | /* Opcode: Last P1 P2 * * * |
| 72014 | 72457 | ** |
| 72015 | -** The next use of the Rowid or Column or Next instruction for P1 | |
| 72458 | +** The next use of the Rowid or Column or Prev instruction for P1 | |
| 72016 | 72459 | ** will refer to the last entry in the database table or index. |
| 72017 | 72460 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72018 | 72461 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72019 | 72462 | ** to the following instruction. |
| 72463 | +** | |
| 72464 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 72465 | +** from the end toward the beginning. In other words, the cursor is | |
| 72466 | +** configured to use Prev, not Next. | |
| 72020 | 72467 | */ |
| 72021 | 72468 | case OP_Last: { /* jump */ |
| 72022 | 72469 | VdbeCursor *pC; |
| 72023 | 72470 | BtCursor *pCrsr; |
| 72024 | 72471 | int res; |
| @@ -72032,10 +72479,13 @@ | ||
| 72032 | 72479 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72033 | 72480 | pC->nullRow = (u8)res; |
| 72034 | 72481 | pC->deferredMoveto = 0; |
| 72035 | 72482 | pC->rowidIsValid = 0; |
| 72036 | 72483 | pC->cacheStatus = CACHE_STALE; |
| 72484 | +#ifdef SQLITE_DEBUG | |
| 72485 | + pC->seekOp = OP_Last; | |
| 72486 | +#endif | |
| 72037 | 72487 | if( pOp->p2>0 ){ |
| 72038 | 72488 | VdbeBranchTaken(res!=0,2); |
| 72039 | 72489 | if( res ) pc = pOp->p2 - 1; |
| 72040 | 72490 | } |
| 72041 | 72491 | break; |
| @@ -72068,10 +72518,14 @@ | ||
| 72068 | 72518 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72069 | 72519 | ** will refer to the first entry in the database table or index. |
| 72070 | 72520 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72071 | 72521 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72072 | 72522 | ** to the following instruction. |
| 72523 | +** | |
| 72524 | +** This opcode leaves the cursor configured to move in forward order, | |
| 72525 | +** from the begining toward the end. In other words, the cursor is | |
| 72526 | +** configured to use Next, not Prev. | |
| 72073 | 72527 | */ |
| 72074 | 72528 | case OP_Rewind: { /* jump */ |
| 72075 | 72529 | VdbeCursor *pC; |
| 72076 | 72530 | BtCursor *pCrsr; |
| 72077 | 72531 | int res; |
| @@ -72079,10 +72533,13 @@ | ||
| 72079 | 72533 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72080 | 72534 | pC = p->apCsr[pOp->p1]; |
| 72081 | 72535 | assert( pC!=0 ); |
| 72082 | 72536 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72083 | 72537 | res = 1; |
| 72538 | +#ifdef SQLITE_DEBUG | |
| 72539 | + pC->seekOp = OP_Rewind; | |
| 72540 | +#endif | |
| 72084 | 72541 | if( isSorter(pC) ){ |
| 72085 | 72542 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72086 | 72543 | }else{ |
| 72087 | 72544 | pCrsr = pC->pCursor; |
| 72088 | 72545 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | ||
| 72104 | 72561 | ** |
| 72105 | 72562 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72106 | 72563 | ** table or index. If there are no more key/value pairs then fall through |
| 72107 | 72564 | ** to the following instruction. But if the cursor advance was successful, |
| 72108 | 72565 | ** jump immediately to P2. |
| 72566 | +** | |
| 72567 | +** The Next opcode is only valid following an SeekGT, SeekGE, or | |
| 72568 | +** OP_Rewind opcode used to position the cursor. Next is not allowed | |
| 72569 | +** to follow SeekLT, SeekLE, or OP_Last. | |
| 72109 | 72570 | ** |
| 72110 | 72571 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72111 | 72572 | ** been opened prior to this opcode or the program will segfault. |
| 72112 | 72573 | ** |
| 72113 | 72574 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | ||
| 72123 | 72584 | ** |
| 72124 | 72585 | ** See also: Prev, NextIfOpen |
| 72125 | 72586 | */ |
| 72126 | 72587 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72127 | 72588 | ** |
| 72128 | -** This opcode works just like OP_Next except that if cursor P1 is not | |
| 72589 | +** This opcode works just like Next except that if cursor P1 is not | |
| 72129 | 72590 | ** open it behaves a no-op. |
| 72130 | 72591 | */ |
| 72131 | 72592 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72132 | 72593 | ** |
| 72133 | 72594 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72134 | 72595 | ** table or index. If there is no previous key/value pairs then fall through |
| 72135 | 72596 | ** to the following instruction. But if the cursor backup was successful, |
| 72136 | 72597 | ** jump immediately to P2. |
| 72137 | 72598 | ** |
| 72599 | +** | |
| 72600 | +** The Prev opcode is only valid following an SeekLT, SeekLE, or | |
| 72601 | +** OP_Last opcode used to position the cursor. Prev is not allowed | |
| 72602 | +** to follow SeekGT, SeekGE, or OP_Rewind. | |
| 72603 | +** | |
| 72138 | 72604 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72139 | 72605 | ** not open then the behavior is undefined. |
| 72140 | 72606 | ** |
| 72141 | 72607 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72142 | 72608 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | ||
| 72149 | 72615 | ** If P5 is positive and the jump is taken, then event counter |
| 72150 | 72616 | ** number P5-1 in the prepared statement is incremented. |
| 72151 | 72617 | */ |
| 72152 | 72618 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72153 | 72619 | ** |
| 72154 | -** This opcode works just like OP_Prev except that if cursor P1 is not | |
| 72620 | +** This opcode works just like Prev except that if cursor P1 is not | |
| 72155 | 72621 | ** open it behaves a no-op. |
| 72156 | 72622 | */ |
| 72157 | 72623 | case OP_SorterNext: { /* jump */ |
| 72158 | 72624 | VdbeCursor *pC; |
| 72159 | 72625 | int res; |
| @@ -72180,10 +72646,20 @@ | ||
| 72180 | 72646 | testcase( res==1 ); |
| 72181 | 72647 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72182 | 72648 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72183 | 72649 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72184 | 72650 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72651 | + | |
| 72652 | + /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. | |
| 72653 | + ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ | |
| 72654 | + assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen | |
| 72655 | + || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE | |
| 72656 | + || pC->seekOp==OP_Rewind ); | |
| 72657 | + assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen | |
| 72658 | + || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE | |
| 72659 | + || pC->seekOp==OP_Last ); | |
| 72660 | + | |
| 72185 | 72661 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72186 | 72662 | next_tail: |
| 72187 | 72663 | pC->cacheStatus = CACHE_STALE; |
| 72188 | 72664 | VdbeBranchTaken(res==0,2); |
| 72189 | 72665 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | ||
| 72462 | 72938 | rc = SQLITE_LOCKED; |
| 72463 | 72939 | p->errorAction = OE_Abort; |
| 72464 | 72940 | }else{ |
| 72465 | 72941 | iDb = pOp->p3; |
| 72466 | 72942 | assert( iCnt==1 ); |
| 72467 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 72943 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 72468 | 72944 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72469 | 72945 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72470 | 72946 | pOut->flags = MEM_Int; |
| 72471 | 72947 | pOut->u.i = iMoved; |
| 72472 | 72948 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | ||
| 72502 | 72978 | case OP_Clear: { |
| 72503 | 72979 | int nChange; |
| 72504 | 72980 | |
| 72505 | 72981 | nChange = 0; |
| 72506 | 72982 | assert( p->readOnly==0 ); |
| 72507 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); | |
| 72983 | + assert( DbMaskTest(p->btreeMask, pOp->p2) ); | |
| 72508 | 72984 | rc = sqlite3BtreeClearTable( |
| 72509 | 72985 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72510 | 72986 | ); |
| 72511 | 72987 | if( pOp->p3 ){ |
| 72512 | 72988 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | ||
| 72572 | 73048 | int flags; |
| 72573 | 73049 | Db *pDb; |
| 72574 | 73050 | |
| 72575 | 73051 | pgno = 0; |
| 72576 | 73052 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72577 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 73053 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 72578 | 73054 | assert( p->readOnly==0 ); |
| 72579 | 73055 | pDb = &db->aDb[pOp->p1]; |
| 72580 | 73056 | assert( pDb->pBt!=0 ); |
| 72581 | 73057 | if( pOp->opcode==OP_CreateTable ){ |
| 72582 | 73058 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | ||
| 72660 | 73136 | |
| 72661 | 73137 | /* Opcode: DropTable P1 * * P4 * |
| 72662 | 73138 | ** |
| 72663 | 73139 | ** Remove the internal (in-memory) data structures that describe |
| 72664 | 73140 | ** the table named P4 in database P1. This is called after a table |
| 72665 | -** is dropped in order to keep the internal representation of the | |
| 73141 | +** is dropped from disk (using the Destroy opcode) in order to keep | |
| 73142 | +** the internal representation of the | |
| 72666 | 73143 | ** schema consistent with what is on disk. |
| 72667 | 73144 | */ |
| 72668 | 73145 | case OP_DropTable: { |
| 72669 | 73146 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 72670 | 73147 | break; |
| @@ -72672,11 +73149,12 @@ | ||
| 72672 | 73149 | |
| 72673 | 73150 | /* Opcode: DropIndex P1 * * P4 * |
| 72674 | 73151 | ** |
| 72675 | 73152 | ** Remove the internal (in-memory) data structures that describe |
| 72676 | 73153 | ** the index named P4 in database P1. This is called after an index |
| 72677 | -** is dropped in order to keep the internal representation of the | |
| 73154 | +** is dropped from disk (using the Destroy opcode) | |
| 73155 | +** in order to keep the internal representation of the | |
| 72678 | 73156 | ** schema consistent with what is on disk. |
| 72679 | 73157 | */ |
| 72680 | 73158 | case OP_DropIndex: { |
| 72681 | 73159 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 72682 | 73160 | break; |
| @@ -72684,11 +73162,12 @@ | ||
| 72684 | 73162 | |
| 72685 | 73163 | /* Opcode: DropTrigger P1 * * P4 * |
| 72686 | 73164 | ** |
| 72687 | 73165 | ** Remove the internal (in-memory) data structures that describe |
| 72688 | 73166 | ** the trigger named P4 in database P1. This is called after a trigger |
| 72689 | -** is dropped in order to keep the internal representation of the | |
| 73167 | +** is dropped from disk (using the Destroy opcode) in order to keep | |
| 73168 | +** the internal representation of the | |
| 72690 | 73169 | ** schema consistent with what is on disk. |
| 72691 | 73170 | */ |
| 72692 | 73171 | case OP_DropTrigger: { |
| 72693 | 73172 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 72694 | 73173 | break; |
| @@ -72737,11 +73216,11 @@ | ||
| 72737 | 73216 | for(j=0; j<nRoot; j++){ |
| 72738 | 73217 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 72739 | 73218 | } |
| 72740 | 73219 | aRoot[j] = 0; |
| 72741 | 73220 | assert( pOp->p5<db->nDb ); |
| 72742 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); | |
| 73221 | + assert( DbMaskTest(p->btreeMask, pOp->p5) ); | |
| 72743 | 73222 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 72744 | 73223 | (int)pnErr->u.i, &nErr); |
| 72745 | 73224 | sqlite3DbFree(db, aRoot); |
| 72746 | 73225 | pnErr->u.i -= nErr; |
| 72747 | 73226 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | ||
| 73397 | 73876 | */ |
| 73398 | 73877 | case OP_IncrVacuum: { /* jump */ |
| 73399 | 73878 | Btree *pBt; |
| 73400 | 73879 | |
| 73401 | 73880 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73402 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 73881 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 73403 | 73882 | assert( p->readOnly==0 ); |
| 73404 | 73883 | pBt = db->aDb[pOp->p1].pBt; |
| 73405 | 73884 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73406 | 73885 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73407 | 73886 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | ||
| 73412 | 73891 | } |
| 73413 | 73892 | #endif |
| 73414 | 73893 | |
| 73415 | 73894 | /* Opcode: Expire P1 * * * * |
| 73416 | 73895 | ** |
| 73417 | -** Cause precompiled statements to become expired. An expired statement | |
| 73418 | -** fails with an error code of SQLITE_SCHEMA if it is ever executed | |
| 73419 | -** (via sqlite3_step()). | |
| 73896 | +** Cause precompiled statements to expire. When an expired statement | |
| 73897 | +** is executed using sqlite3_step() it will either automatically | |
| 73898 | +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) | |
| 73899 | +** or it will fail with SQLITE_SCHEMA. | |
| 73420 | 73900 | ** |
| 73421 | 73901 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73422 | -** then only the currently executing statement is affected. | |
| 73902 | +** then only the currently executing statement is expired. | |
| 73423 | 73903 | */ |
| 73424 | 73904 | case OP_Expire: { |
| 73425 | 73905 | if( !pOp->p1 ){ |
| 73426 | 73906 | sqlite3ExpirePreparedStatements(db); |
| 73427 | 73907 | }else{ |
| @@ -73449,11 +73929,11 @@ | ||
| 73449 | 73929 | case OP_TableLock: { |
| 73450 | 73930 | u8 isWriteLock = (u8)pOp->p3; |
| 73451 | 73931 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73452 | 73932 | int p1 = pOp->p1; |
| 73453 | 73933 | assert( p1>=0 && p1<db->nDb ); |
| 73454 | - assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); | |
| 73934 | + assert( DbMaskTest(p->btreeMask, p1) ); | |
| 73455 | 73935 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73456 | 73936 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73457 | 73937 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73458 | 73938 | const char *z = pOp->p4.z; |
| 73459 | 73939 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | ||
| 73899 | 74379 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 73900 | 74380 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 73901 | 74381 | if( zTrace ){ |
| 73902 | 74382 | int i; |
| 73903 | 74383 | for(i=0; i<db->nDb; i++){ |
| 73904 | - if( (MASKBIT(i) & p->btreeMask)==0 ) continue; | |
| 74384 | + if( DbMaskTest(p->btreeMask, i)==0 ) continue; | |
| 73905 | 74385 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 73906 | 74386 | } |
| 73907 | 74387 | } |
| 73908 | 74388 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 73909 | 74389 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | ||
| 74889 | 75369 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 74890 | 75370 | ** has been allocated and contains an unpacked record that is used as key2. |
| 74891 | 75371 | */ |
| 74892 | 75372 | static void vdbeSorterCompare( |
| 74893 | 75373 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 74894 | - int nIgnore, /* Ignore the last nIgnore fields */ | |
| 75374 | + int nKeyCol, /* Num of columns. 0 means "all" */ | |
| 74895 | 75375 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 74896 | 75376 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 74897 | 75377 | int *pRes /* OUT: Result of comparison */ |
| 74898 | 75378 | ){ |
| 74899 | 75379 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | ||
| 74903 | 75383 | |
| 74904 | 75384 | if( pKey2 ){ |
| 74905 | 75385 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 74906 | 75386 | } |
| 74907 | 75387 | |
| 74908 | - if( nIgnore ){ | |
| 74909 | - r2->nField = pKeyInfo->nField - nIgnore; | |
| 74910 | - assert( r2->nField>0 ); | |
| 74911 | - for(i=0; i<r2->nField; i++){ | |
| 75388 | + if( nKeyCol ){ | |
| 75389 | + r2->nField = nKeyCol; | |
| 75390 | + for(i=0; i<nKeyCol; i++){ | |
| 74912 | 75391 | if( r2->aMem[i].flags & MEM_Null ){ |
| 74913 | 75392 | *pRes = -1; |
| 74914 | 75393 | return; |
| 74915 | 75394 | } |
| 74916 | 75395 | } |
| @@ -75588,18 +76067,18 @@ | ||
| 75588 | 76067 | ** key. |
| 75589 | 76068 | */ |
| 75590 | 76069 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 75591 | 76070 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 75592 | 76071 | Mem *pVal, /* Value to compare to current sorter key */ |
| 75593 | - int nIgnore, /* Ignore this many fields at the end */ | |
| 76072 | + int nKeyCol, /* Only compare this many fields */ | |
| 75594 | 76073 | int *pRes /* OUT: Result of comparison */ |
| 75595 | 76074 | ){ |
| 75596 | 76075 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75597 | 76076 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 75598 | 76077 | |
| 75599 | 76078 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 75600 | - vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes); | |
| 76079 | + vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes); | |
| 75601 | 76080 | return SQLITE_OK; |
| 75602 | 76081 | } |
| 75603 | 76082 | |
| 75604 | 76083 | /************** End of vdbesort.c ********************************************/ |
| 75605 | 76084 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | ||
| 79352 | 79831 | } |
| 79353 | 79832 | } |
| 79354 | 79833 | } |
| 79355 | 79834 | |
| 79356 | 79835 | if( eType==0 ){ |
| 79357 | - /* Could not found an existing table or index to use as the RHS b-tree. | |
| 79836 | + /* Could not find an existing table or index to use as the RHS b-tree. | |
| 79358 | 79837 | ** We will have to generate an ephemeral table to do the job. |
| 79359 | 79838 | */ |
| 79360 | 79839 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79361 | 79840 | int rMayHaveNull = 0; |
| 79362 | 79841 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | ||
| 79482 | 79961 | /* Case 1: expr IN (SELECT ...) |
| 79483 | 79962 | ** |
| 79484 | 79963 | ** Generate code to write the results of the select into the temporary |
| 79485 | 79964 | ** table allocated and opened above. |
| 79486 | 79965 | */ |
| 79966 | + Select *pSelect = pExpr->x.pSelect; | |
| 79487 | 79967 | SelectDest dest; |
| 79488 | 79968 | ExprList *pEList; |
| 79489 | 79969 | |
| 79490 | 79970 | assert( !isRowid ); |
| 79491 | 79971 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79492 | 79972 | dest.affSdst = (u8)affinity; |
| 79493 | 79973 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79494 | - pExpr->x.pSelect->iLimit = 0; | |
| 79974 | + pSelect->iLimit = 0; | |
| 79975 | + testcase( pSelect->selFlags & SF_Distinct ); | |
| 79976 | + pSelect->selFlags &= ~SF_Distinct; | |
| 79495 | 79977 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79496 | - if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ | |
| 79978 | + if( sqlite3Select(pParse, pSelect, &dest) ){ | |
| 79497 | 79979 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79498 | 79980 | return 0; |
| 79499 | 79981 | } |
| 79500 | - pEList = pExpr->x.pSelect->pEList; | |
| 79982 | + pEList = pSelect->pEList; | |
| 79501 | 79983 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79502 | 79984 | assert( pEList!=0 ); |
| 79503 | 79985 | assert( pEList->nExpr>0 ); |
| 79504 | 79986 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79505 | 79987 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | ||
| 79803 | 80285 | }else{ |
| 79804 | 80286 | int c; |
| 79805 | 80287 | i64 value; |
| 79806 | 80288 | const char *z = pExpr->u.zToken; |
| 79807 | 80289 | assert( z!=0 ); |
| 79808 | - c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); | |
| 80290 | + c = sqlite3DecOrHexToI64(z, &value); | |
| 79809 | 80291 | if( c==0 || (c==2 && negFlag) ){ |
| 79810 | 80292 | char *zV; |
| 79811 | 80293 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 79812 | 80294 | zV = dup8bytes(v, (char*)&value); |
| 79813 | 80295 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 79814 | 80296 | }else{ |
| 79815 | 80297 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 79816 | 80298 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 79817 | 80299 | #else |
| 79818 | - codeReal(v, z, negFlag, iMem); | |
| 80300 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 80301 | + if( sqlite3_strnicmp(z,"0x",2)==0 ){ | |
| 80302 | + sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); | |
| 80303 | + }else | |
| 80304 | +#endif | |
| 80305 | + { | |
| 80306 | + codeReal(v, z, negFlag, iMem); | |
| 80307 | + } | |
| 79819 | 80308 | #endif |
| 79820 | 80309 | } |
| 79821 | 80310 | } |
| 79822 | 80311 | } |
| 79823 | 80312 | |
| @@ -83186,19 +83675,24 @@ | ||
| 83186 | 83675 | } |
| 83187 | 83676 | |
| 83188 | 83677 | /* |
| 83189 | 83678 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83190 | 83679 | ** are: |
| 83191 | -** N: The number of columns in the index including the rowid/pk | |
| 83192 | -** K: The number of columns in the index excluding the rowid/pk | |
| 83193 | -** C: The number of rows in the index | |
| 83194 | -** | |
| 83195 | -** C is only used for STAT3 and STAT4. | |
| 83196 | -** | |
| 83197 | -** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables, | |
| 83198 | -** N=K+P where P is the number of columns in the primary key. For the | |
| 83199 | -** covering index that implements the original WITHOUT ROWID table, N==K. | |
| 83680 | +** N: The number of columns in the index including the rowid/pk (note 1) | |
| 83681 | +** K: The number of columns in the index excluding the rowid/pk. | |
| 83682 | +** C: The number of rows in the index (note 2) | |
| 83683 | +** | |
| 83684 | +** Note 1: In the special case of the covering index that implements a | |
| 83685 | +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the | |
| 83686 | +** total number of columns in the table. | |
| 83687 | +** | |
| 83688 | +** Note 2: C is only used for STAT3 and STAT4. | |
| 83689 | +** | |
| 83690 | +** For indexes on ordinary rowid tables, N==K+1. But for indexes on | |
| 83691 | +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the | |
| 83692 | +** PRIMARY KEY of the table. The covering index that implements the | |
| 83693 | +** original WITHOUT ROWID table as N==K as a special case. | |
| 83200 | 83694 | ** |
| 83201 | 83695 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83202 | 83696 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83203 | 83697 | ** the size of the blob is sizeof(void*) bytes). |
| 83204 | 83698 | */ |
| @@ -83504,11 +83998,14 @@ | ||
| 83504 | 83998 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83505 | 83999 | ** C Index of left-most column to differ from previous row |
| 83506 | 84000 | ** R Rowid for the current row. Might be a key record for |
| 83507 | 84001 | ** WITHOUT ROWID tables. |
| 83508 | 84002 | ** |
| 83509 | -** The SQL function always returns NULL. | |
| 84003 | +** This SQL function always returns NULL. It's purpose it to accumulate | |
| 84004 | +** statistical data and/or samples in the Stat4Accum object about the | |
| 84005 | +** index being analyzed. The stat_get() SQL function will later be used to | |
| 84006 | +** extract relevant information for constructing the sqlite_statN tables. | |
| 83510 | 84007 | ** |
| 83511 | 84008 | ** The R parameter is only used for STAT3 and STAT4 |
| 83512 | 84009 | */ |
| 83513 | 84010 | static void statPush( |
| 83514 | 84011 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | ||
| 83598 | 84095 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 83599 | 84096 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 83600 | 84097 | |
| 83601 | 84098 | /* |
| 83602 | 84099 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 83603 | -** used to query the results. Content is returned for parameter J | |
| 84100 | +** used to query statistical information that has been gathered into | |
| 84101 | +** the Stat4Accum object by prior calls to stat_push(). The P parameter | |
| 84102 | +** is a BLOB which is decoded into a pointer to the Stat4Accum objects. | |
| 84103 | +** The content to returned is determined by the parameter J | |
| 83604 | 84104 | ** which is one of the STAT_GET_xxxx values defined above. |
| 83605 | 84105 | ** |
| 83606 | 84106 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 83607 | 84107 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 83608 | 84108 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | ||
| 83817 | 84317 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 83818 | 84318 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 83819 | 84319 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 83820 | 84320 | |
| 83821 | 84321 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 83822 | - int nCol; /* Number of columns indexed by pIdx */ | |
| 83823 | - int *aGotoChng; /* Array of jump instruction addresses */ | |
| 84322 | + int nCol; /* Number of columns in pIdx. "N" */ | |
| 83824 | 84323 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 83825 | - int addrGotoChng0; /* Address of "Goto addr_chng_0" */ | |
| 83826 | 84324 | int addrNextRow; /* Address of "next_row:" */ |
| 83827 | 84325 | const char *zIdxName; /* Name of the index */ |
| 84326 | + int nColTest; /* Number of columns to test for changes */ | |
| 83828 | 84327 | |
| 83829 | 84328 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 83830 | 84329 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 83831 | 84330 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 83832 | 84331 | nCol = pIdx->nKeyCol; |
| 83833 | 84332 | zIdxName = pTab->zName; |
| 84333 | + nColTest = nCol - 1; | |
| 83834 | 84334 | }else{ |
| 83835 | 84335 | nCol = pIdx->nColumn; |
| 83836 | 84336 | zIdxName = pIdx->zName; |
| 84337 | + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; | |
| 83837 | 84338 | } |
| 83838 | - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); | |
| 83839 | - if( aGotoChng==0 ) continue; | |
| 83840 | 84339 | |
| 83841 | 84340 | /* Populate the register containing the index name. */ |
| 83842 | 84341 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 83843 | 84342 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 83844 | 84343 | |
| @@ -83863,11 +84362,11 @@ | ||
| 83863 | 84362 | ** regPrev(0) = idx(0) |
| 83864 | 84363 | ** chng_addr_1: |
| 83865 | 84364 | ** regPrev(1) = idx(1) |
| 83866 | 84365 | ** ... |
| 83867 | 84366 | ** |
| 83868 | - ** chng_addr_N: | |
| 84367 | + ** endDistinctTest: | |
| 83869 | 84368 | ** regRowid = idx(rowid) |
| 83870 | 84369 | ** stat_push(P, regChng, regRowid) |
| 83871 | 84370 | ** Next csr |
| 83872 | 84371 | ** if !eof(csr) goto next_row; |
| 83873 | 84372 | ** |
| @@ -83876,24 +84375,27 @@ | ||
| 83876 | 84375 | |
| 83877 | 84376 | /* Make sure there are enough memory cells allocated to accommodate |
| 83878 | 84377 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 83879 | 84378 | ** when building a record to insert into the sample column of |
| 83880 | 84379 | ** the sqlite_stat4 table. */ |
| 83881 | - pParse->nMem = MAX(pParse->nMem, regPrev+nCol); | |
| 84380 | + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); | |
| 83882 | 84381 | |
| 83883 | 84382 | /* Open a read-only cursor on the index being analyzed. */ |
| 83884 | 84383 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 83885 | 84384 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 83886 | 84385 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 83887 | 84386 | VdbeComment((v, "%s", pIdx->zName)); |
| 83888 | 84387 | |
| 83889 | 84388 | /* Invoke the stat_init() function. The arguments are: |
| 83890 | 84389 | ** |
| 83891 | - ** (1) the number of columns in the index including the rowid, | |
| 83892 | - ** (2) the number of rows in the index, | |
| 84390 | + ** (1) the number of columns in the index including the rowid | |
| 84391 | + ** (or for a WITHOUT ROWID table, the number of PK columns), | |
| 84392 | + ** (2) the number of columns in the key without the rowid/pk | |
| 84393 | + ** (3) the number of rows in the index, | |
| 83893 | 84394 | ** |
| 83894 | - ** The second argument is only used for STAT3 and STAT4 | |
| 84395 | + ** | |
| 84396 | + ** The third argument is only used for STAT3 and STAT4 | |
| 83895 | 84397 | */ |
| 83896 | 84398 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83897 | 84399 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 83898 | 84400 | #endif |
| 83899 | 84401 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | ||
| 83911 | 84413 | ** |
| 83912 | 84414 | */ |
| 83913 | 84415 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 83914 | 84416 | VdbeCoverage(v); |
| 83915 | 84417 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 83916 | - addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 83917 | - | |
| 83918 | - /* | |
| 83919 | - ** next_row: | |
| 83920 | - ** regChng = 0 | |
| 83921 | - ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 83922 | - ** regChng = 1 | |
| 83923 | - ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 83924 | - ** ... | |
| 83925 | - ** regChng = N | |
| 83926 | - ** goto chng_addr_N | |
| 83927 | - */ | |
| 83928 | 84418 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 83929 | - for(i=0; i<nCol; i++){ | |
| 83930 | - char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | |
| 83931 | - sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | |
| 83932 | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | |
| 83933 | - aGotoChng[i] = | |
| 83934 | - sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | |
| 83935 | - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); | |
| 83936 | - VdbeCoverage(v); | |
| 83937 | - } | |
| 83938 | - sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); | |
| 83939 | - aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 83940 | - | |
| 83941 | - /* | |
| 83942 | - ** chng_addr_0: | |
| 83943 | - ** regPrev(0) = idx(0) | |
| 83944 | - ** chng_addr_1: | |
| 83945 | - ** regPrev(1) = idx(1) | |
| 83946 | - ** ... | |
| 83947 | - */ | |
| 83948 | - sqlite3VdbeJumpHere(v, addrGotoChng0); | |
| 83949 | - for(i=0; i<nCol; i++){ | |
| 83950 | - sqlite3VdbeJumpHere(v, aGotoChng[i]); | |
| 83951 | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); | |
| 83952 | - } | |
| 83953 | - | |
| 84419 | + | |
| 84420 | + if( nColTest>0 ){ | |
| 84421 | + int endDistinctTest = sqlite3VdbeMakeLabel(v); | |
| 84422 | + int *aGotoChng; /* Array of jump instruction addresses */ | |
| 84423 | + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); | |
| 84424 | + if( aGotoChng==0 ) continue; | |
| 84425 | + | |
| 84426 | + /* | |
| 84427 | + ** next_row: | |
| 84428 | + ** regChng = 0 | |
| 84429 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 84430 | + ** regChng = 1 | |
| 84431 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 84432 | + ** ... | |
| 84433 | + ** regChng = N | |
| 84434 | + ** goto endDistinctTest | |
| 84435 | + */ | |
| 84436 | + sqlite3VdbeAddOp0(v, OP_Goto); | |
| 84437 | + addrNextRow = sqlite3VdbeCurrentAddr(v); | |
| 84438 | + if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ | |
| 84439 | + /* For a single-column UNIQUE index, once we have found a non-NULL | |
| 84440 | + ** row, we know that all the rest will be distinct, so skip | |
| 84441 | + ** subsequent distinctness tests. */ | |
| 84442 | + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); | |
| 84443 | + VdbeCoverage(v); | |
| 84444 | + } | |
| 84445 | + for(i=0; i<nColTest; i++){ | |
| 84446 | + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | |
| 84447 | + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | |
| 84448 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | |
| 84449 | + aGotoChng[i] = | |
| 84450 | + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | |
| 84451 | + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); | |
| 84452 | + VdbeCoverage(v); | |
| 84453 | + } | |
| 84454 | + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); | |
| 84455 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); | |
| 84456 | + | |
| 84457 | + | |
| 84458 | + /* | |
| 84459 | + ** chng_addr_0: | |
| 84460 | + ** regPrev(0) = idx(0) | |
| 84461 | + ** chng_addr_1: | |
| 84462 | + ** regPrev(1) = idx(1) | |
| 84463 | + ** ... | |
| 84464 | + */ | |
| 84465 | + sqlite3VdbeJumpHere(v, addrNextRow-1); | |
| 84466 | + for(i=0; i<nColTest; i++){ | |
| 84467 | + sqlite3VdbeJumpHere(v, aGotoChng[i]); | |
| 84468 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); | |
| 84469 | + } | |
| 84470 | + sqlite3VdbeResolveLabel(v, endDistinctTest); | |
| 84471 | + sqlite3DbFree(db, aGotoChng); | |
| 84472 | + } | |
| 84473 | + | |
| 83954 | 84474 | /* |
| 83955 | 84475 | ** chng_addr_N: |
| 83956 | 84476 | ** regRowid = idx(rowid) // STAT34 only |
| 83957 | 84477 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 83958 | 84478 | ** Next csr |
| 83959 | 84479 | ** if !eof(csr) goto next_row; |
| 83960 | 84480 | */ |
| 83961 | - sqlite3VdbeJumpHere(v, aGotoChng[nCol]); | |
| 83962 | 84481 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83963 | 84482 | assert( regRowid==(regStat4+2) ); |
| 83964 | 84483 | if( HasRowid(pTab) ){ |
| 83965 | 84484 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 83966 | 84485 | }else{ |
| @@ -84034,11 +84553,10 @@ | ||
| 84034 | 84553 | } |
| 84035 | 84554 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84036 | 84555 | |
| 84037 | 84556 | /* End of analysis */ |
| 84038 | 84557 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84039 | - sqlite3DbFree(db, aGotoChng); | |
| 84040 | 84558 | } |
| 84041 | 84559 | |
| 84042 | 84560 | |
| 84043 | 84561 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84044 | 84562 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | ||
| 84135 | 84653 | int i; |
| 84136 | 84654 | char *z, *zDb; |
| 84137 | 84655 | Table *pTab; |
| 84138 | 84656 | Index *pIdx; |
| 84139 | 84657 | Token *pTableName; |
| 84658 | + Vdbe *v; | |
| 84140 | 84659 | |
| 84141 | 84660 | /* Read the database schema. If an error occurs, leave an error message |
| 84142 | 84661 | ** and code in pParse and return NULL. */ |
| 84143 | 84662 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84144 | 84663 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | ||
| 84182 | 84701 | } |
| 84183 | 84702 | sqlite3DbFree(db, z); |
| 84184 | 84703 | } |
| 84185 | 84704 | } |
| 84186 | 84705 | } |
| 84706 | + v = sqlite3GetVdbe(pParse); | |
| 84707 | + if( v ) sqlite3VdbeAddOp0(v, OP_Expire); | |
| 84187 | 84708 | } |
| 84188 | 84709 | |
| 84189 | 84710 | /* |
| 84190 | 84711 | ** Used to pass information from the analyzer reader through to the |
| 84191 | 84712 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | ||
| 84240 | 84761 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84241 | 84762 | assert( pIndex!=0 ); |
| 84242 | 84763 | #else |
| 84243 | 84764 | if( pIndex ) |
| 84244 | 84765 | #endif |
| 84245 | - { | |
| 84246 | - if( strcmp(z, "unordered")==0 ){ | |
| 84766 | + while( z[0] ){ | |
| 84767 | + if( sqlite3_strglob("unordered*", z)==0 ){ | |
| 84247 | 84768 | pIndex->bUnordered = 1; |
| 84248 | 84769 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84249 | - int v32 = 0; | |
| 84250 | - sqlite3GetInt32(z+3, &v32); | |
| 84251 | - pIndex->szIdxRow = sqlite3LogEst(v32); | |
| 84770 | + pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); | |
| 84252 | 84771 | } |
| 84772 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 84773 | + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ | |
| 84774 | + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); | |
| 84775 | + } | |
| 84776 | +#endif | |
| 84777 | + while( z[0]!=0 && z[0]!=' ' ) z++; | |
| 84778 | + while( z[0]==' ' ) z++; | |
| 84253 | 84779 | } |
| 84254 | 84780 | } |
| 84255 | 84781 | |
| 84256 | 84782 | /* |
| 84257 | 84783 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | ||
| 84288 | 84814 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84289 | 84815 | } |
| 84290 | 84816 | z = argv[2]; |
| 84291 | 84817 | |
| 84292 | 84818 | if( pIndex ){ |
| 84819 | + pIndex->bUnordered = 0; | |
| 84293 | 84820 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84294 | 84821 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84295 | 84822 | }else{ |
| 84296 | 84823 | Index fakeIdx; |
| 84297 | 84824 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84825 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 84826 | + fakeIdx.pTable = pTable; | |
| 84827 | +#endif | |
| 84298 | 84828 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84299 | 84829 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84300 | 84830 | } |
| 84301 | 84831 | |
| 84302 | 84832 | return 0; |
| @@ -85568,10 +86098,23 @@ | ||
| 85568 | 86098 | } |
| 85569 | 86099 | #else |
| 85570 | 86100 | #define codeTableLocks(x) |
| 85571 | 86101 | #endif |
| 85572 | 86102 | |
| 86103 | +/* | |
| 86104 | +** Return TRUE if the given yDbMask object is empty - if it contains no | |
| 86105 | +** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() | |
| 86106 | +** macros when SQLITE_MAX_ATTACHED is greater than 30. | |
| 86107 | +*/ | |
| 86108 | +#if SQLITE_MAX_ATTACHED>30 | |
| 86109 | +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ | |
| 86110 | + int i; | |
| 86111 | + for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0; | |
| 86112 | + return 1; | |
| 86113 | +} | |
| 86114 | +#endif | |
| 86115 | + | |
| 85573 | 86116 | /* |
| 85574 | 86117 | ** This routine is called after a single SQL statement has been |
| 85575 | 86118 | ** parsed and a VDBE program to execute that statement has been |
| 85576 | 86119 | ** prepared. This routine puts the finishing touches on the |
| 85577 | 86120 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | ||
| 85604 | 86147 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 85605 | 86148 | ** set for each database that is used. Generate code to start a |
| 85606 | 86149 | ** transaction on each used database and to verify the schema cookie |
| 85607 | 86150 | ** on each used database. |
| 85608 | 86151 | */ |
| 85609 | - if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ | |
| 85610 | - yDbMask mask; | |
| 86152 | + if( db->mallocFailed==0 | |
| 86153 | + && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) | |
| 86154 | + ){ | |
| 85611 | 86155 | int iDb, i; |
| 85612 | 86156 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 85613 | 86157 | sqlite3VdbeJumpHere(v, 0); |
| 85614 | - for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ | |
| 85615 | - if( (mask & pParse->cookieMask)==0 ) continue; | |
| 86158 | + for(iDb=0; iDb<db->nDb; iDb++){ | |
| 86159 | + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; | |
| 85616 | 86160 | sqlite3VdbeUsesBtree(v, iDb); |
| 85617 | 86161 | sqlite3VdbeAddOp4Int(v, |
| 85618 | 86162 | OP_Transaction, /* Opcode */ |
| 85619 | 86163 | iDb, /* P1 */ |
| 85620 | - (mask & pParse->writeMask)!=0, /* P2 */ | |
| 86164 | + DbMaskTest(pParse->writeMask,iDb), /* P2 */ | |
| 85621 | 86165 | pParse->cookieValue[iDb], /* P3 */ |
| 85622 | 86166 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 85623 | 86167 | ); |
| 85624 | 86168 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 85625 | 86169 | } |
| @@ -85671,11 +86215,11 @@ | ||
| 85671 | 86215 | } |
| 85672 | 86216 | pParse->nTab = 0; |
| 85673 | 86217 | pParse->nMem = 0; |
| 85674 | 86218 | pParse->nSet = 0; |
| 85675 | 86219 | pParse->nVar = 0; |
| 85676 | - pParse->cookieMask = 0; | |
| 86220 | + DbMaskZero(pParse->cookieMask); | |
| 85677 | 86221 | } |
| 85678 | 86222 | |
| 85679 | 86223 | /* |
| 85680 | 86224 | ** Run the parser and code generator recursively in order to generate |
| 85681 | 86225 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | ||
| 88153 | 88697 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88154 | 88698 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88155 | 88699 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88156 | 88700 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88157 | 88701 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88158 | - pKey->nField - pIndex->nKeyCol); VdbeCoverage(v); | |
| 88702 | + pIndex->nKeyCol); VdbeCoverage(v); | |
| 88159 | 88703 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88160 | 88704 | }else{ |
| 88161 | 88705 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88162 | 88706 | } |
| 88163 | 88707 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | ||
| 89298 | 89842 | ** later, by sqlite3FinishCoding(). |
| 89299 | 89843 | */ |
| 89300 | 89844 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89301 | 89845 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89302 | 89846 | sqlite3 *db = pToplevel->db; |
| 89303 | - yDbMask mask; | |
| 89304 | 89847 | |
| 89305 | 89848 | assert( iDb>=0 && iDb<db->nDb ); |
| 89306 | 89849 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89307 | 89850 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89308 | 89851 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89309 | - mask = ((yDbMask)1)<<iDb; | |
| 89310 | - if( (pToplevel->cookieMask & mask)==0 ){ | |
| 89311 | - pToplevel->cookieMask |= mask; | |
| 89852 | + if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ | |
| 89853 | + DbMaskSet(pToplevel->cookieMask, iDb); | |
| 89312 | 89854 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89313 | 89855 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89314 | 89856 | sqlite3OpenTempDatabase(pToplevel); |
| 89315 | 89857 | } |
| 89316 | 89858 | } |
| @@ -89345,11 +89887,11 @@ | ||
| 89345 | 89887 | ** necessary to undo a write and the checkpoint should not be set. |
| 89346 | 89888 | */ |
| 89347 | 89889 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89348 | 89890 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89349 | 89891 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89350 | - pToplevel->writeMask |= ((yDbMask)1)<<iDb; | |
| 89892 | + DbMaskSet(pToplevel->writeMask, iDb); | |
| 89351 | 89893 | pToplevel->isMultiWrite |= setStatement; |
| 89352 | 89894 | } |
| 89353 | 89895 | |
| 89354 | 89896 | /* |
| 89355 | 89897 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | ||
| 98033 | 98575 | ** Note that the values returned are one less that the values that |
| 98034 | 98576 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98035 | 98577 | ** to support legacy SQL code. The safety level used to be boolean |
| 98036 | 98578 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98037 | 98579 | */ |
| 98038 | -static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ | |
| 98580 | +static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ | |
| 98039 | 98581 | /* 123456789 123456789 */ |
| 98040 | 98582 | static const char zText[] = "onoffalseyestruefull"; |
| 98041 | 98583 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98042 | 98584 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98043 | 98585 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | ||
| 98055 | 98597 | } |
| 98056 | 98598 | |
| 98057 | 98599 | /* |
| 98058 | 98600 | ** Interpret the given string as a boolean value. |
| 98059 | 98601 | */ |
| 98060 | -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){ | |
| 98602 | +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){ | |
| 98061 | 98603 | return getSafetyLevel(z,1,dflt)!=0; |
| 98062 | 98604 | } |
| 98063 | 98605 | |
| 98064 | 98606 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98065 | 98607 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | ||
| 98601 | 99143 | */ |
| 98602 | 99144 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 98603 | 99145 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 98604 | 99146 | i64 iLimit = -2; |
| 98605 | 99147 | if( zRight ){ |
| 98606 | - sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 99148 | + sqlite3DecOrHexToI64(zRight, &iLimit); | |
| 98607 | 99149 | if( iLimit<-1 ) iLimit = -1; |
| 98608 | 99150 | } |
| 98609 | 99151 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 98610 | 99152 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 98611 | 99153 | break; |
| @@ -98729,11 +99271,11 @@ | ||
| 98729 | 99271 | sqlite3_int64 sz; |
| 98730 | 99272 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 98731 | 99273 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 98732 | 99274 | if( zRight ){ |
| 98733 | 99275 | int ii; |
| 98734 | - sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 99276 | + sqlite3DecOrHexToI64(zRight, &sz); | |
| 98735 | 99277 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 98736 | 99278 | if( pId2->n==0 ) db->szMmap = sz; |
| 98737 | 99279 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 98738 | 99280 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 98739 | 99281 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | ||
| 99772 | 100314 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 99773 | 100315 | ** use -1. |
| 99774 | 100316 | */ |
| 99775 | 100317 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 99776 | 100318 | sqlite3_int64 N; |
| 99777 | - if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ | |
| 100319 | + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ | |
| 99778 | 100320 | sqlite3_soft_heap_limit64(N); |
| 99779 | 100321 | } |
| 99780 | 100322 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 99781 | 100323 | break; |
| 99782 | 100324 | } |
| @@ -112245,11 +112787,12 @@ | ||
| 112245 | 112787 | int nEq = pLoop->u.btree.nEq; |
| 112246 | 112788 | sqlite3 *db = pParse->db; |
| 112247 | 112789 | int nLower = -1; |
| 112248 | 112790 | int nUpper = p->nSample+1; |
| 112249 | 112791 | int rc = SQLITE_OK; |
| 112250 | - u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity; | |
| 112792 | + int iCol = p->aiColumn[nEq]; | |
| 112793 | + u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; | |
| 112251 | 112794 | CollSeq *pColl; |
| 112252 | 112795 | |
| 112253 | 112796 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112254 | 112797 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112255 | 112798 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | ||
| 113620 | 114163 | int regRowid = 0; /* Register holding rowid */ |
| 113621 | 114164 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 113622 | 114165 | int iRetInit; /* Address of regReturn init */ |
| 113623 | 114166 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 113624 | 114167 | int ii; /* Loop counter */ |
| 114168 | + u16 wctrlFlags; /* Flags for sub-WHERE clause */ | |
| 113625 | 114169 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 113626 | 114170 | Table *pTab = pTabItem->pTab; |
| 113627 | 114171 | |
| 113628 | 114172 | pTerm = pLoop->aLTerm[0]; |
| 113629 | 114173 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | ||
| 113715 | 114259 | |
| 113716 | 114260 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 113717 | 114261 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 113718 | 114262 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 113719 | 114263 | */ |
| 114264 | + wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | | |
| 114265 | + WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY; | |
| 113720 | 114266 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 113721 | 114267 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 113722 | 114268 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 113723 | 114269 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113724 | 114270 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | ||
| 113727 | 114273 | pAndExpr->pLeft = pOrExpr; |
| 113728 | 114274 | pOrExpr = pAndExpr; |
| 113729 | 114275 | } |
| 113730 | 114276 | /* Loop through table entries that match term pOrTerm. */ |
| 113731 | 114277 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 113732 | - WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | | |
| 113733 | - WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); | |
| 114278 | + wctrlFlags, iCovCur); | |
| 113734 | 114279 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 113735 | 114280 | if( pSubWInfo ){ |
| 113736 | 114281 | WhereLoop *pSubLoop; |
| 113737 | 114282 | explainOneScan( |
| 113738 | 114283 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | ||
| 113819 | 114364 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 113820 | 114365 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 113821 | 114366 | ){ |
| 113822 | 114367 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 113823 | 114368 | pCov = pSubLoop->u.btree.pIndex; |
| 114369 | + wctrlFlags |= WHERE_REOPEN_IDX; | |
| 113824 | 114370 | }else{ |
| 113825 | 114371 | pCov = 0; |
| 113826 | 114372 | } |
| 113827 | 114373 | |
| 113828 | 114374 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | ||
| 114425 | 114971 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114426 | 114972 | } |
| 114427 | 114973 | } |
| 114428 | 114974 | } |
| 114429 | 114975 | |
| 114976 | +/* | |
| 114977 | +** Adjust the cost C by the costMult facter T. This only occurs if | |
| 114978 | +** compiled with -DSQLITE_ENABLE_COSTMULT | |
| 114979 | +*/ | |
| 114980 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 114981 | +# define ApplyCostMultiplier(C,T) C += T | |
| 114982 | +#else | |
| 114983 | +# define ApplyCostMultiplier(C,T) | |
| 114984 | +#endif | |
| 114985 | + | |
| 114430 | 114986 | /* |
| 114431 | 114987 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114432 | 114988 | ** index pIndex. Try to match one more. |
| 114433 | 114989 | ** |
| 114434 | 114990 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | ||
| 114621 | 115177 | testcase( eOp & WO_ISNULL ); |
| 114622 | 115178 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 114623 | 115179 | }else{ |
| 114624 | 115180 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 114625 | 115181 | } |
| 114626 | - assert( rc!=SQLITE_OK || nOut>0 ); | |
| 114627 | 115182 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 114628 | 115183 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 114629 | 115184 | if( nOut ){ |
| 114630 | 115185 | pNew->nOut = sqlite3LogEst(nOut); |
| 114631 | 115186 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | ||
| 114653 | 115208 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 114654 | 115209 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 114655 | 115210 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 114656 | 115211 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 114657 | 115212 | } |
| 115213 | + ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); | |
| 114658 | 115214 | |
| 114659 | 115215 | nOutUnadjusted = pNew->nOut; |
| 114660 | 115216 | pNew->rRun += nInMul + nIn; |
| 114661 | 115217 | pNew->nOut += nInMul + nIn; |
| 114662 | 115218 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | ||
| 114772 | 115328 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 114773 | 115329 | ** |
| 114774 | 115330 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 114775 | 115331 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 114776 | 115332 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 115333 | +** | |
| 115334 | +** The estimated values (nRow, nVisit, nSeek) often contain a large amount | |
| 115335 | +** of uncertainty. For this reason, scoring is designed to pick plans that | |
| 115336 | +** "do the least harm" if the estimates are inaccurate. For example, a | |
| 115337 | +** log(nRow) factor is omitted from a non-covering index scan in order to | |
| 115338 | +** bias the scoring in favor of using an index, since the worst-case | |
| 115339 | +** performance of using an index is far better than the worst-case performance | |
| 115340 | +** of a full table scan. | |
| 114777 | 115341 | */ |
| 114778 | 115342 | static int whereLoopAddBtree( |
| 114779 | 115343 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114780 | 115344 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114781 | 115345 | ){ |
| @@ -114859,10 +115423,11 @@ | ||
| 114859 | 115423 | pNew->aLTerm[0] = pTerm; |
| 114860 | 115424 | /* TUNING: One-time cost for computing the automatic index is |
| 114861 | 115425 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 114862 | 115426 | ** the table being indexed. */ |
| 114863 | 115427 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 115428 | + ApplyCostMultiplier(pNew->rSetup, pTab->costMult); | |
| 114864 | 115429 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 114865 | 115430 | ** is more than the usual guess of 10 rows, since we have no way |
| 114866 | 115431 | ** of knowning how selective the index will ultimately be. It would |
| 114867 | 115432 | ** not be unreasonable to make this value much larger. */ |
| 114868 | 115433 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | ||
| 114900 | 115465 | |
| 114901 | 115466 | /* Full table scan */ |
| 114902 | 115467 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114903 | 115468 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 114904 | 115469 | pNew->rRun = rSize + 16; |
| 115470 | + ApplyCostMultiplier(pNew->rRun, pTab->costMult); | |
| 114905 | 115471 | whereLoopOutputAdjust(pWC, pNew); |
| 114906 | 115472 | rc = whereLoopInsert(pBuilder, pNew); |
| 114907 | 115473 | pNew->nOut = rSize; |
| 114908 | 115474 | if( rc ) break; |
| 114909 | 115475 | }else{ |
| @@ -114935,11 +115501,11 @@ | ||
| 114935 | 115501 | ** also add the cost of visiting table rows (N*3.0). */ |
| 114936 | 115502 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114937 | 115503 | if( m!=0 ){ |
| 114938 | 115504 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 114939 | 115505 | } |
| 114940 | - | |
| 115506 | + ApplyCostMultiplier(pNew->rRun, pTab->costMult); | |
| 114941 | 115507 | whereLoopOutputAdjust(pWC, pNew); |
| 114942 | 115508 | rc = whereLoopInsert(pBuilder, pNew); |
| 114943 | 115509 | pNew->nOut = rSize; |
| 114944 | 115510 | if( rc ) break; |
| 114945 | 115511 | } |
| @@ -116410,10 +116976,11 @@ | ||
| 116410 | 116976 | } |
| 116411 | 116977 | op = OP_OpenWrite; |
| 116412 | 116978 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116413 | 116979 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116414 | 116980 | iIndexCur = iIdxCur; |
| 116981 | + if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; | |
| 116415 | 116982 | }else{ |
| 116416 | 116983 | iIndexCur = pParse->nTab++; |
| 116417 | 116984 | } |
| 116418 | 116985 | pLevel->iIdxCur = iIndexCur; |
| 116419 | 116986 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | ||
| 120734 | 121301 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 120735 | 121302 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 120736 | 121303 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 120737 | 121304 | testcase( z[0]=='9' ); |
| 120738 | 121305 | *tokenType = TK_INTEGER; |
| 121306 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 121307 | + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ | |
| 121308 | + for(i=3; sqlite3Isxdigit(z[i]); i++){} | |
| 121309 | + return i; | |
| 121310 | + } | |
| 121311 | +#endif | |
| 120739 | 121312 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 120740 | 121313 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 120741 | 121314 | if( z[i]=='.' ){ |
| 120742 | 121315 | i++; |
| 120743 | 121316 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | ||
| 122410 | 122983 | |
| 122411 | 122984 | /* |
| 122412 | 122985 | ** Return a static string containing the name corresponding to the error code |
| 122413 | 122986 | ** specified in the argument. |
| 122414 | 122987 | */ |
| 122415 | -#if defined(SQLITE_TEST) | |
| 122988 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 122416 | 122989 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122417 | 122990 | const char *zName = 0; |
| 122418 | 122991 | int i, origRc = rc; |
| 122419 | 122992 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122420 | 122993 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | ||
| 123455 | 124028 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 123456 | 124029 | #endif |
| 123457 | 124030 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 123458 | 124031 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 123459 | 124032 | #endif |
| 123460 | -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 | |
| 123461 | -# error SQLITE_MAX_ATTACHED must be between 0 and 62 | |
| 124033 | +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 | |
| 124034 | +# error SQLITE_MAX_ATTACHED must be between 0 and 125 | |
| 123462 | 124035 | #endif |
| 123463 | 124036 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 123464 | 124037 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 123465 | 124038 | #endif |
| 123466 | 124039 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | ||
| 124715 | 125288 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 124716 | 125289 | #endif |
| 124717 | 125290 | break; |
| 124718 | 125291 | } |
| 124719 | 125292 | |
| 125293 | + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); | |
| 125294 | + ** | |
| 125295 | + ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if | |
| 125296 | + ** not. | |
| 125297 | + */ | |
| 125298 | + case SQLITE_TESTCTRL_ISINIT: { | |
| 125299 | + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; | |
| 125300 | + break; | |
| 125301 | + } | |
| 125302 | + | |
| 124720 | 125303 | } |
| 124721 | 125304 | va_end(ap); |
| 124722 | 125305 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 124723 | 125306 | return rc; |
| 124724 | 125307 | } |
| @@ -124763,11 +125346,11 @@ | ||
| 124763 | 125346 | const char *zParam, /* URI parameter sought */ |
| 124764 | 125347 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 124765 | 125348 | ){ |
| 124766 | 125349 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 124767 | 125350 | sqlite3_int64 v; |
| 124768 | - if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ | |
| 125351 | + if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ | |
| 124769 | 125352 | bDflt = v; |
| 124770 | 125353 | } |
| 124771 | 125354 | return bDflt; |
| 124772 | 125355 | } |
| 124773 | 125356 | |
| @@ -126294,11 +126877,11 @@ | ||
| 126294 | 126877 | |
| 126295 | 126878 | /* fts3_tokenize_vtab.c */ |
| 126296 | 126879 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126297 | 126880 | |
| 126298 | 126881 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126299 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 126882 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 126300 | 126883 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126301 | 126884 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126302 | 126885 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126303 | 126886 | #endif |
| 126304 | 126887 | |
| @@ -129764,11 +130347,11 @@ | ||
| 129764 | 130347 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 129765 | 130348 | ** And so on. |
| 129766 | 130349 | */ |
| 129767 | 130350 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129768 | 130351 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129769 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130352 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129770 | 130353 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 129771 | 130354 | #endif |
| 129772 | 130355 | #ifdef SQLITE_ENABLE_ICU |
| 129773 | 130356 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129774 | 130357 | #endif |
| @@ -129782,20 +130365,20 @@ | ||
| 129782 | 130365 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 129783 | 130366 | int rc = SQLITE_OK; |
| 129784 | 130367 | Fts3Hash *pHash = 0; |
| 129785 | 130368 | const sqlite3_tokenizer_module *pSimple = 0; |
| 129786 | 130369 | const sqlite3_tokenizer_module *pPorter = 0; |
| 129787 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130370 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129788 | 130371 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 129789 | 130372 | #endif |
| 129790 | 130373 | |
| 129791 | 130374 | #ifdef SQLITE_ENABLE_ICU |
| 129792 | 130375 | const sqlite3_tokenizer_module *pIcu = 0; |
| 129793 | 130376 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 129794 | 130377 | #endif |
| 129795 | 130378 | |
| 129796 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130379 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129797 | 130380 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 129798 | 130381 | #endif |
| 129799 | 130382 | |
| 129800 | 130383 | #ifdef SQLITE_TEST |
| 129801 | 130384 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | ||
| 129819 | 130402 | /* Load the built-in tokenizers into the hash table */ |
| 129820 | 130403 | if( rc==SQLITE_OK ){ |
| 129821 | 130404 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 129822 | 130405 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 129823 | 130406 | |
| 129824 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130407 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129825 | 130408 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 129826 | 130409 | #endif |
| 129827 | 130410 | #ifdef SQLITE_ENABLE_ICU |
| 129828 | 130411 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 129829 | 130412 | #endif |
| @@ -143079,11 +143662,11 @@ | ||
| 143079 | 143662 | ****************************************************************************** |
| 143080 | 143663 | ** |
| 143081 | 143664 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143082 | 143665 | */ |
| 143083 | 143666 | |
| 143084 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 143667 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 143085 | 143668 | |
| 143086 | 143669 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143087 | 143670 | |
| 143088 | 143671 | /* #include <assert.h> */ |
| 143089 | 143672 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | ||
| 143295 | 143878 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143296 | 143879 | pNew->bRemoveDiacritic = 1; |
| 143297 | 143880 | |
| 143298 | 143881 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143299 | 143882 | const char *z = azArg[i]; |
| 143300 | - int n = strlen(z); | |
| 143883 | + int n = (int)strlen(z); | |
| 143301 | 143884 | |
| 143302 | 143885 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143303 | 143886 | pNew->bRemoveDiacritic = 1; |
| 143304 | 143887 | } |
| 143305 | 143888 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | ||
| 143427 | 144010 | }while( unicodeIsAlnum(p, iCode) |
| 143428 | 144011 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 143429 | 144012 | ); |
| 143430 | 144013 | |
| 143431 | 144014 | /* Set the output variables and return. */ |
| 143432 | - pCsr->iOff = (z - pCsr->aInput); | |
| 144015 | + pCsr->iOff = (int)(z - pCsr->aInput); | |
| 143433 | 144016 | *paToken = pCsr->zToken; |
| 143434 | - *pnToken = zOut - pCsr->zToken; | |
| 143435 | - *piStart = (zStart - pCsr->aInput); | |
| 143436 | - *piEnd = (zEnd - pCsr->aInput); | |
| 144017 | + *pnToken = (int)(zOut - pCsr->zToken); | |
| 144018 | + *piStart = (int)(zStart - pCsr->aInput); | |
| 144019 | + *piEnd = (int)(zEnd - pCsr->aInput); | |
| 143437 | 144020 | *piPos = pCsr->iToken++; |
| 143438 | 144021 | return SQLITE_OK; |
| 143439 | 144022 | } |
| 143440 | 144023 | |
| 143441 | 144024 | /* |
| @@ -143454,11 +144037,11 @@ | ||
| 143454 | 144037 | }; |
| 143455 | 144038 | *ppModule = &module; |
| 143456 | 144039 | } |
| 143457 | 144040 | |
| 143458 | 144041 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 143459 | -#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ | |
| 144042 | +#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ | |
| 143460 | 144043 | |
| 143461 | 144044 | /************** End of fts3_unicode.c ****************************************/ |
| 143462 | 144045 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 143463 | 144046 | /* |
| 143464 | 144047 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | ||
| 143475 | 144058 | |
| 143476 | 144059 | /* |
| 143477 | 144060 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 143478 | 144061 | */ |
| 143479 | 144062 | |
| 143480 | -#if defined(SQLITE_ENABLE_FTS4_UNICODE61) | |
| 144063 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 143481 | 144064 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 143482 | 144065 | |
| 143483 | 144066 | /* #include <assert.h> */ |
| 143484 | 144067 | |
| 143485 | 144068 | /* |
| @@ -143822,11 +144405,11 @@ | ||
| 143822 | 144405 | } |
| 143823 | 144406 | |
| 143824 | 144407 | return ret; |
| 143825 | 144408 | } |
| 143826 | 144409 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 143827 | -#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ | |
| 144410 | +#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ | |
| 143828 | 144411 | |
| 143829 | 144412 | /************** End of fts3_unicode2.c ***************************************/ |
| 143830 | 144413 | /************** Begin file rtree.c *******************************************/ |
| 143831 | 144414 | /* |
| 143832 | 144415 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | ||
| 145359 | 145942 | int rc = SQLITE_OK; |
| 145360 | 145943 | int iCell = 0; |
| 145361 | 145944 | |
| 145362 | 145945 | rtreeReference(pRtree); |
| 145363 | 145946 | |
| 145947 | + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ | |
| 145364 | 145948 | freeCursorConstraints(pCsr); |
| 145949 | + sqlite3_free(pCsr->aPoint); | |
| 145950 | + memset(pCsr, 0, sizeof(RtreeCursor)); | |
| 145951 | + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; | |
| 145952 | + | |
| 145365 | 145953 | pCsr->iStrategy = idxNum; |
| 145366 | - | |
| 145367 | 145954 | if( idxNum==1 ){ |
| 145368 | 145955 | /* Special case - lookup by rowid. */ |
| 145369 | 145956 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145370 | 145957 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145371 | 145958 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145372 | 145959 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -2150,31 +2150,37 @@ | |
| 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | |
| 2152 | /* |
| 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | ** |
| 2155 | ** ^This routine sets a callback function that might be invoked whenever |
| 2156 | ** an attempt is made to open a database table that another thread |
| 2157 | ** or process has locked. |
| 2158 | ** |
| 2159 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2160 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2161 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2162 | ** |
| 2163 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2164 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2165 | ** the busy handler callback is the number of times that the busy handler has |
| 2166 | ** been invoked for this locking event. ^If the |
| 2167 | ** busy callback returns 0, then no additional attempts are made to |
| 2168 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. |
| 2169 | ** ^If the callback returns non-zero, then another attempt |
| 2170 | ** is made to open the database for reading and the cycle repeats. |
| 2171 | ** |
| 2172 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2173 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2174 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2175 | ** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. |
| 2176 | ** Consider a scenario where one process is holding a read lock that |
| 2177 | ** it is trying to promote to a reserved lock and |
| 2178 | ** a second process is holding a reserved lock that it is trying |
| 2179 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2180 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | |
| 2202 | ** this is important. |
| 2203 | ** |
| 2204 | ** ^(There can only be a single busy handler defined for each |
| 2205 | ** [database connection]. Setting a new busy handler clears any |
| 2206 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2207 | ** will also set or clear the busy handler. |
| 2208 | ** |
| 2209 | ** The busy callback should not take any actions which modify the |
| 2210 | ** database connection that invoked the busy handler. Any such actions |
| 2211 | ** result in undefined behavior. |
| 2212 | ** |
| 2213 | ** A busy handler must not close the database connection |
| 2214 | ** or [prepared statement] that invoked the busy handler. |
| 2215 | */ |
| @@ -2230,10 +2238,12 @@ | |
| 2230 | ** |
| 2231 | ** ^(There can only be a single busy handler for a particular |
| 2232 | ** [database connection] any any given moment. If another busy handler |
| 2233 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2234 | ** this routine, that other busy handler is cleared.)^ |
| 2235 | */ |
| 2236 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2237 | |
| 2238 | /* |
| 2239 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | |
| 4818 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4819 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4820 | ** will be placed in that directory.)^ ^If this variable |
| 4821 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4822 | ** temporary file directory. |
| 4823 | ** |
| 4824 | ** It is not safe to read or modify this variable in more than one |
| 4825 | ** thread at a time. It is not safe to read or modify this variable |
| 4826 | ** if a [database connection] is being used at the same time in a separate |
| 4827 | ** thread. |
| @@ -4837,10 +4854,15 @@ | |
| 4837 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4838 | ** using [sqlite3_free]. |
| 4839 | ** Hence, if this variable is modified directly, either it should be |
| 4840 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4841 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4842 | ** |
| 4843 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4844 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4845 | ** features that require the use of temporary files may fail. Here is an |
| 4846 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | |
| 5971 | ** <ul> |
| 5972 | ** <li> SQLITE_MUTEX_FAST |
| 5973 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5974 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5975 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5976 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 5977 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5978 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5979 | ** <li> SQLITE_MUTEX_STATIC_LRU2 |
| 5980 | ** </ul>)^ |
| 5981 | ** |
| 5982 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5983 | ** cause sqlite3_mutex_alloc() to create |
| 5984 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | |
| 6178 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6179 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6180 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6181 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6182 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6183 | |
| 6184 | /* |
| 6185 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6186 | ** |
| 6187 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | |
| 6273 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6274 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6275 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6276 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6277 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6278 | #define SQLITE_TESTCTRL_LAST 22 |
| 6279 | |
| 6280 | /* |
| 6281 | ** CAPI3REF: SQLite Runtime Status |
| 6282 | ** |
| 6283 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | |
| 7256 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7257 | ** configured by this function. |
| 7258 | ** |
| 7259 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7260 | ** from SQL. |
| 7261 | ** |
| 7262 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7263 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7264 | ** pages. The use of this interface |
| 7265 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | |
| 7273 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7274 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7275 | ** empty string, then a checkpoint is run on all databases of |
| 7276 | ** connection D. ^If the database connection D is not in |
| 7277 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7278 | ** |
| 7279 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7280 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7281 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7282 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | |
| 7295 | ** <dl> |
| 7296 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7297 | ** Checkpoint as many frames as possible without waiting for any database |
| 7298 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7299 | ** are checkpointed. This mode is the same as calling |
| 7300 | ** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. |
| 7301 | ** |
| 7302 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7303 | ** This mode blocks (calls the busy-handler callback) until there is no |
| 7304 | ** database writer and all readers are reading from the most recent database |
| 7305 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7306 | ** database file. This call blocks database writers while it is running, |
| 7307 | ** but not database readers. |
| 7308 | ** |
| 7309 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7310 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7311 | ** checkpointing the log file it blocks (calls the busy-handler callback) |
| 7312 | ** until all readers are reading from the database file only. This ensures |
| 7313 | ** that the next client to write to the database file restarts the log file |
| 7314 | ** from the beginning. This call blocks database writers while it is running, |
| 7315 | ** but not database readers. |
| 7316 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | |
| 9285 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9286 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9287 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9288 | #define OP_ReadCookie 50 |
| 9289 | #define OP_SetCookie 51 |
| 9290 | #define OP_OpenRead 52 /* synopsis: root=P2 iDb=P3 */ |
| 9291 | #define OP_OpenWrite 53 /* synopsis: root=P2 iDb=P3 */ |
| 9292 | #define OP_OpenAutoindex 54 /* synopsis: nColumn=P2 */ |
| 9293 | #define OP_OpenEphemeral 55 /* synopsis: nColumn=P2 */ |
| 9294 | #define OP_SorterOpen 56 |
| 9295 | #define OP_OpenPseudo 57 /* synopsis: P3 columns in r[P2] */ |
| 9296 | #define OP_Close 58 |
| 9297 | #define OP_SeekLT 59 |
| 9298 | #define OP_SeekLE 60 |
| 9299 | #define OP_SeekGE 61 |
| 9300 | #define OP_SeekGT 62 |
| 9301 | #define OP_Seek 63 /* synopsis: intkey=r[P2] */ |
| 9302 | #define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ |
| 9303 | #define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ |
| 9304 | #define OP_Found 66 /* synopsis: key=r[P3@P4] */ |
| 9305 | #define OP_NotExists 67 /* synopsis: intkey=r[P3] */ |
| 9306 | #define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9307 | #define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ |
| 9308 | #define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9309 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9310 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9311 | #define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ |
| 9312 | #define OP_Delete 74 |
| 9313 | #define OP_ResetCount 75 |
| 9314 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9315 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9316 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9317 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9318 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9319 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9320 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9321 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9322 | #define OP_SorterCompare 84 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ |
| 9323 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9324 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9325 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9326 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9327 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | |
| 9328 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9329 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9330 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9331 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9332 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9333 | #define OP_SorterData 95 /* synopsis: r[P2]=data */ |
| 9334 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9335 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9336 | #define OP_RowKey 98 /* synopsis: r[P2]=key */ |
| 9337 | #define OP_RowData 99 /* synopsis: r[P2]=data */ |
| 9338 | #define OP_Rowid 100 /* synopsis: r[P2]=rowid */ |
| 9339 | #define OP_NullRow 101 |
| 9340 | #define OP_Last 102 |
| 9341 | #define OP_SorterSort 103 |
| 9342 | #define OP_Sort 104 |
| 9343 | #define OP_Rewind 105 |
| 9344 | #define OP_SorterInsert 106 |
| 9345 | #define OP_IdxInsert 107 /* synopsis: key=r[P2] */ |
| 9346 | #define OP_IdxDelete 108 /* synopsis: key=r[P2@P3] */ |
| 9347 | #define OP_IdxRowid 109 /* synopsis: r[P2]=rowid */ |
| 9348 | #define OP_IdxLE 110 /* synopsis: key=r[P3@P4] */ |
| 9349 | #define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ |
| 9350 | #define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ |
| 9351 | #define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ |
| 9352 | #define OP_Destroy 114 |
| 9353 | #define OP_Clear 115 |
| 9354 | #define OP_ResetSorter 116 |
| 9355 | #define OP_CreateIndex 117 /* synopsis: r[P2]=root iDb=P1 */ |
| 9356 | #define OP_CreateTable 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9357 | #define OP_ParseSchema 119 |
| 9358 | #define OP_LoadAnalysis 120 |
| 9359 | #define OP_DropTable 121 |
| 9360 | #define OP_DropIndex 122 |
| 9361 | #define OP_DropTrigger 123 |
| 9362 | #define OP_IntegrityCk 124 |
| 9363 | #define OP_RowSetAdd 125 /* synopsis: rowset(P1)=r[P2] */ |
| 9364 | #define OP_RowSetRead 126 /* synopsis: r[P3]=rowset(P1) */ |
| 9365 | #define OP_RowSetTest 127 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9366 | #define OP_Program 128 |
| 9367 | #define OP_Param 129 |
| 9368 | #define OP_FkCounter 130 /* synopsis: fkctr[P1]+=P2 */ |
| 9369 | #define OP_FkIfZero 131 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9370 | #define OP_MemMax 132 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9371 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9372 | #define OP_IfPos 134 /* synopsis: if r[P1]>0 goto P2 */ |
| 9373 | #define OP_IfNeg 135 /* synopsis: if r[P1]<0 goto P2 */ |
| 9374 | #define OP_IfZero 136 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9375 | #define OP_AggFinal 137 /* synopsis: accum=r[P1] N=P2 */ |
| 9376 | #define OP_IncrVacuum 138 |
| 9377 | #define OP_Expire 139 |
| 9378 | #define OP_TableLock 140 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9379 | #define OP_VBegin 141 |
| 9380 | #define OP_VCreate 142 |
| 9381 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9382 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9383 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9384 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9385 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9386 | #define OP_VDestroy 148 |
| 9387 | #define OP_VOpen 149 |
| 9388 | #define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9389 | #define OP_VNext 151 |
| 9390 | #define OP_VRename 152 |
| 9391 | #define OP_Pagecount 153 |
| 9392 | #define OP_MaxPgcnt 154 |
| 9393 | #define OP_Init 155 /* synopsis: Start at P2 */ |
| 9394 | #define OP_Noop 156 |
| 9395 | #define OP_Explain 157 |
| 9396 | |
| 9397 | |
| 9398 | /* Properties such as "out2" or "jump" that are specified in |
| 9399 | ** comments following the "case" for each opcode in the vdbe.c |
| 9400 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | |
| 9412 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9413 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9414 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9415 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9416 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9417 | /* 56 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\ |
| 9418 | /* 64 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c,\ |
| 9419 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9420 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9421 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9422 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ |
| 9423 | /* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ |
| 9424 | /* 112 */ 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,\ |
| 9425 | /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15,\ |
| 9426 | /* 128 */ 0x01, 0x02, 0x00, 0x01, 0x08, 0x02, 0x05, 0x05,\ |
| 9427 | /* 136 */ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,\ |
| 9428 | /* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01,\ |
| 9429 | /* 152 */ 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9430 | |
| 9431 | /************** End of opcodes.h *********************************************/ |
| 9432 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9433 | |
| 9434 | /* |
| @@ -10932,10 +10971,13 @@ | |
| 10932 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10933 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10934 | i16 nCol; /* Number of columns in this table */ |
| 10935 | u16 nRef; /* Number of pointers to this Table */ |
| 10936 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10937 | u8 tabFlags; /* Mask of TF_* values */ |
| 10938 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10939 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10940 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10941 | #endif |
| @@ -11591,10 +11633,11 @@ | |
| 11591 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11592 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11593 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11594 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11595 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11596 | |
| 11597 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11598 | */ |
| 11599 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11600 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | |
| 11847 | |
| 11848 | /* |
| 11849 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11850 | */ |
| 11851 | #if SQLITE_MAX_ATTACHED>30 |
| 11852 | typedef sqlite3_uint64 yDbMask; |
| 11853 | #else |
| 11854 | typedef unsigned int yDbMask; |
| 11855 | #endif |
| 11856 | |
| 11857 | /* |
| 11858 | ** An SQL parser context. A copy of this structure is passed through |
| 11859 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | |
| 12522 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12523 | #else |
| 12524 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12525 | #endif |
| 12526 | |
| 12527 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12528 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12529 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12530 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12531 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | |
| 12772 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12773 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12774 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12775 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12776 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12777 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12778 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12779 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12780 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12781 | |
| @@ -12801,11 +12858,11 @@ | |
| 12801 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12802 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12803 | #else |
| 12804 | # define sqlite3FileSuffix3(X,Y) |
| 12805 | #endif |
| 12806 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int); |
| 12807 | |
| 12808 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12809 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12810 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12811 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | |
| 13876 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13877 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13878 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13879 | i16 nField; /* Number of fields in the header */ |
| 13880 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13881 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13882 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13883 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13884 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13885 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13886 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13887 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13888 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13889 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13890 | i64 seqCount; /* Sequence counter */ |
| 13891 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13892 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13893 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | |
| 18396 | /* |
| 18397 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18398 | */ |
| 18399 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18400 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18401 | if( sqlite3_initialize() ) return 0; |
| 18402 | #endif |
| 18403 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18404 | } |
| 18405 | |
| 18406 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | |
| 18577 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18578 | ** mutex and returns a pointer to it. If it returns NULL |
| 18579 | ** that means that a mutex could not be allocated. |
| 18580 | */ |
| 18581 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18582 | static sqlite3_debug_mutex aStatic[6]; |
| 18583 | sqlite3_debug_mutex *pNew = 0; |
| 18584 | switch( id ){ |
| 18585 | case SQLITE_MUTEX_FAST: |
| 18586 | case SQLITE_MUTEX_RECURSIVE: { |
| 18587 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | |
| 18774 | ** <ul> |
| 18775 | ** <li> SQLITE_MUTEX_FAST |
| 18776 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18777 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18778 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18779 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 18780 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18781 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18782 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18783 | ** </ul> |
| 18784 | ** |
| 18785 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18786 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18787 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | |
| 18806 | ** mutex types, the same mutex is returned on every call that has |
| 18807 | ** the same type number. |
| 18808 | */ |
| 18809 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18810 | static sqlite3_mutex staticMutexes[] = { |
| 18811 | SQLITE3_MUTEX_INITIALIZER, |
| 18812 | SQLITE3_MUTEX_INITIALIZER, |
| 18813 | SQLITE3_MUTEX_INITIALIZER, |
| 18814 | SQLITE3_MUTEX_INITIALIZER, |
| 18815 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | |
| 19041 | ** May you do good and not evil. |
| 19042 | ** May you find forgiveness for yourself and forgive others. |
| 19043 | ** May you share freely, never taking more than you give. |
| 19044 | ** |
| 19045 | ************************************************************************* |
| 19046 | ** This file contains the C functions that implement mutexes for win32 |
| 19047 | */ |
| 19048 | |
| 19049 | #if SQLITE_OS_WIN |
| 19050 | /* |
| 19051 | ** Include the header file for the Windows VFS. |
| 19052 | */ |
| 19053 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19054 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | |
| 19124 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19125 | #endif |
| 19126 | |
| 19127 | /* |
| 19128 | ** The code in this file is only used if we are compiling multithreaded |
| 19129 | ** on a win32 system. |
| 19130 | */ |
| 19131 | #ifdef SQLITE_MUTEX_W32 |
| 19132 | |
| 19133 | /* |
| 19134 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | |
| 19137 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19138 | int id; /* Mutex type */ |
| 19139 | #ifdef SQLITE_DEBUG |
| 19140 | volatile int nRef; /* Number of enterances */ |
| 19141 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19142 | int trace; /* True to trace changes */ |
| 19143 | #endif |
| 19144 | }; |
| 19145 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19146 | #ifdef SQLITE_DEBUG |
| 19147 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } |
| 19148 | #else |
| 19149 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19150 | #endif |
| 19151 | |
| 19152 | /* |
| 19153 | ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
| 19154 | ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
| 19155 | ** |
| 19156 | ** Here is an interesting observation: Win95, Win98, and WinME lack |
| 19157 | ** the LockFileEx() API. But we can still statically link against that |
| 19158 | ** API as long as we don't call it win running Win95/98/ME. A call to |
| 19159 | ** this routine is used to determine if the host is Win95/98/ME or |
| 19160 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 19161 | ** the LockFileEx() API. |
| 19162 | ** |
| 19163 | ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, |
| 19164 | ** which is only available if your application was compiled with |
| 19165 | ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only |
| 19166 | ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef |
| 19167 | ** this out as well. |
| 19168 | */ |
| 19169 | #if 0 |
| 19170 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 19171 | # define mutexIsNT() (1) |
| 19172 | #else |
| 19173 | static int mutexIsNT(void){ |
| 19174 | static int osType = 0; |
| 19175 | if( osType==0 ){ |
| 19176 | OSVERSIONINFO sInfo; |
| 19177 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 19178 | GetVersionEx(&sInfo); |
| 19179 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 19180 | } |
| 19181 | return osType==2; |
| 19182 | } |
| 19183 | #endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ |
| 19184 | #endif |
| 19185 | |
| 19186 | #ifdef SQLITE_DEBUG |
| 19187 | /* |
| 19188 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19189 | ** intended for use only inside assert() statements. |
| 19190 | */ |
| 19191 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19192 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19193 | } |
| 19194 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19195 | return p->nRef==0 || p->owner!=tid; |
| 19196 | } |
| 19197 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19198 | DWORD tid = GetCurrentThreadId(); |
| 19199 | return winMutexNotheld2(p, tid); |
| 19200 | } |
| 19201 | #endif |
| 19202 | |
| 19203 | |
| 19204 | /* |
| 19205 | ** Initialize and deinitialize the mutex subsystem. |
| 19206 | */ |
| 19207 | static sqlite3_mutex winMutex_staticMutexes[6] = { |
| 19208 | SQLITE3_MUTEX_INITIALIZER, |
| 19209 | SQLITE3_MUTEX_INITIALIZER, |
| 19210 | SQLITE3_MUTEX_INITIALIZER, |
| 19211 | SQLITE3_MUTEX_INITIALIZER, |
| 19212 | SQLITE3_MUTEX_INITIALIZER, |
| 19213 | SQLITE3_MUTEX_INITIALIZER |
| 19214 | }; |
| 19215 | static int winMutex_isInit = 0; |
| 19216 | /* As winMutexInit() and winMutexEnd() are called as part |
| 19217 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 19218 | ** processing, the "interlocked" magic is probably not |
| 19219 | ** strictly necessary. |
| 19220 | */ |
| 19221 | static LONG winMutex_lock = 0; |
| 19222 | |
| 19223 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19224 | |
| 19225 | static int winMutexInit(void){ |
| 19226 | /* The first to increment to 1 does actual initialization */ |
| 19227 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19228 | int i; |
| 19229 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19230 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | |
| 19233 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19234 | #endif |
| 19235 | } |
| 19236 | winMutex_isInit = 1; |
| 19237 | }else{ |
| 19238 | /* Someone else is in the process of initing the static mutexes */ |
| 19239 | while( !winMutex_isInit ){ |
| 19240 | sqlite3_win32_sleep(1); |
| 19241 | } |
| 19242 | } |
| 19243 | return SQLITE_OK; |
| 19244 | } |
| 19245 | |
| 19246 | static int winMutexEnd(void){ |
| 19247 | /* The first to decrement to 0 does actual shutdown |
| 19248 | ** (which should be the last to shutdown.) */ |
| 19249 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19250 | if( winMutex_isInit==1 ){ |
| 19251 | int i; |
| 19252 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | |
| 19253 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19254 | } |
| 19255 | winMutex_isInit = 0; |
| 19256 | } |
| 19257 | } |
| 19258 | return SQLITE_OK; |
| 19259 | } |
| 19260 | |
| 19261 | /* |
| 19262 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19263 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | |
| 19268 | ** <ul> |
| 19269 | ** <li> SQLITE_MUTEX_FAST |
| 19270 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19271 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19272 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19273 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 19274 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19275 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19276 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19277 | ** </ul> |
| 19278 | ** |
| 19279 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19280 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19281 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | |
| 19294 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19295 | ** SQLITE_MUTEX_RECURSIVE. |
| 19296 | ** |
| 19297 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19298 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19299 | ** returns a different mutex on every call. But for the static |
| 19300 | ** mutex types, the same mutex is returned on every call that has |
| 19301 | ** the same type number. |
| 19302 | */ |
| 19303 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19304 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | |
| 19305 | |
| 19306 | switch( iType ){ |
| 19307 | case SQLITE_MUTEX_FAST: |
| 19308 | case SQLITE_MUTEX_RECURSIVE: { |
| 19309 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19310 | if( p ){ |
| 19311 | #ifdef SQLITE_DEBUG |
| 19312 | p->id = iType; |
| 19313 | #endif |
| 19314 | #if SQLITE_OS_WINRT |
| 19315 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19316 | #else |
| 19317 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | |
| 19318 | #endif |
| 19319 | } |
| 19320 | break; |
| 19321 | } |
| 19322 | default: { |
| 19323 | assert( winMutex_isInit==1 ); |
| 19324 | assert( iType-2 >= 0 ); |
| 19325 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19326 | p = &winMutex_staticMutexes[iType-2]; |
| 19327 | #ifdef SQLITE_DEBUG |
| 19328 | p->id = iType; |
| 19329 | #endif |
| 19330 | break; |
| 19331 | } |
| 19332 | } |
| 19333 | return p; |
| @@ -19339,12 +19610,15 @@ | |
| 19339 | ** allocated mutex. SQLite is careful to deallocate every |
| 19340 | ** mutex that it allocates. |
| 19341 | */ |
| 19342 | static void winMutexFree(sqlite3_mutex *p){ |
| 19343 | assert( p ); |
| 19344 | assert( p->nRef==0 && p->owner==0 ); |
| 19345 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19346 | DeleteCriticalSection(&p->mutex); |
| 19347 | sqlite3_free(p); |
| 19348 | } |
| 19349 | |
| 19350 | /* |
| @@ -19357,53 +19631,71 @@ | |
| 19357 | ** mutex must be exited an equal number of times before another thread |
| 19358 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19359 | ** more than once, the behavior is undefined. |
| 19360 | */ |
| 19361 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19362 | #ifdef SQLITE_DEBUG |
| 19363 | DWORD tid = GetCurrentThreadId(); |
| 19364 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19365 | #endif |
| 19366 | EnterCriticalSection(&p->mutex); |
| 19367 | #ifdef SQLITE_DEBUG |
| 19368 | assert( p->nRef>0 || p->owner==0 ); |
| 19369 | p->owner = tid; |
| 19370 | p->nRef++; |
| 19371 | if( p->trace ){ |
| 19372 | printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19373 | } |
| 19374 | #endif |
| 19375 | } |
| 19376 | static int winMutexTry(sqlite3_mutex *p){ |
| 19377 | #ifndef NDEBUG |
| 19378 | DWORD tid = GetCurrentThreadId(); |
| 19379 | #endif |
| 19380 | int rc = SQLITE_BUSY; |
| 19381 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19382 | /* |
| 19383 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19384 | ** is used it is merely an optimization. So it is OK for it to always |
| 19385 | ** fail. |
| 19386 | ** |
| 19387 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19388 | ** And some windows compilers complain if you try to use it without |
| 19389 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19390 | ** For that reason, we will omit this optimization for now. See |
| 19391 | ** ticket #2685. |
| 19392 | */ |
| 19393 | #if 0 |
| 19394 | if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ |
| 19395 | p->owner = tid; |
| 19396 | p->nRef++; |
| 19397 | rc = SQLITE_OK; |
| 19398 | } |
| 19399 | #else |
| 19400 | UNUSED_PARAMETER(p); |
| 19401 | #endif |
| 19402 | #ifdef SQLITE_DEBUG |
| 19403 | if( rc==SQLITE_OK && p->trace ){ |
| 19404 | printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19405 | } |
| 19406 | #endif |
| 19407 | return rc; |
| 19408 | } |
| 19409 | |
| @@ -19412,22 +19704,27 @@ | |
| 19412 | ** previously entered by the same thread. The behavior |
| 19413 | ** is undefined if the mutex is not currently entered or |
| 19414 | ** is not currently allocated. SQLite will never do either. |
| 19415 | */ |
| 19416 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19417 | #ifndef NDEBUG |
| 19418 | DWORD tid = GetCurrentThreadId(); |
| 19419 | assert( p->nRef>0 ); |
| 19420 | assert( p->owner==tid ); |
| 19421 | p->nRef--; |
| 19422 | if( p->nRef==0 ) p->owner = 0; |
| 19423 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19424 | #endif |
| 19425 | LeaveCriticalSection(&p->mutex); |
| 19426 | #ifdef SQLITE_DEBUG |
| 19427 | if( p->trace ){ |
| 19428 | printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19429 | } |
| 19430 | #endif |
| 19431 | } |
| 19432 | |
| 19433 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | |
| 19445 | #else |
| 19446 | 0, |
| 19447 | 0 |
| 19448 | #endif |
| 19449 | }; |
| 19450 | |
| 19451 | return &sMutex; |
| 19452 | } |
| 19453 | #endif /* SQLITE_MUTEX_W32 */ |
| 19454 | |
| 19455 | /************** End of mutex_w32.c *******************************************/ |
| 19456 | /************** Begin file malloc.c ******************************************/ |
| 19457 | /* |
| @@ -22422,13 +22719,13 @@ | |
| 22422 | testcase( c==(+1) ); |
| 22423 | } |
| 22424 | return c; |
| 22425 | } |
| 22426 | |
| 22427 | |
| 22428 | /* |
| 22429 | ** Convert zNum to a 64-bit signed integer. |
| 22430 | ** |
| 22431 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22432 | ** integer, then write that value into *pNum and return 0. |
| 22433 | ** |
| 22434 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | |
| 22511 | assert( u-1==LARGEST_INT64 ); |
| 22512 | return neg ? 0 : 2; |
| 22513 | } |
| 22514 | } |
| 22515 | } |
| 22516 | |
| 22517 | /* |
| 22518 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22519 | ** *pValue to that integer and return true. Otherwise return false. |
| 22520 | ** |
| 22521 | ** Any non-numeric characters that following zNum are ignored. |
| 22522 | ** This is different from sqlite3Atoi64() which requires the |
| 22523 | ** input number to be zero-terminated. |
| 22524 | */ |
| @@ -22530,11 +22861,29 @@ | |
| 22530 | neg = 1; |
| 22531 | zNum++; |
| 22532 | }else if( zNum[0]=='+' ){ |
| 22533 | zNum++; |
| 22534 | } |
| 22535 | while( zNum[0]=='0' ) zNum++; |
| 22536 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22537 | v = v*10 + c; |
| 22538 | } |
| 22539 | |
| 22540 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | |
| 23606 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23607 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23608 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23609 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23610 | /* 51 */ "SetCookie" OpHelp(""), |
| 23611 | /* 52 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23612 | /* 53 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23613 | /* 54 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23614 | /* 55 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23615 | /* 56 */ "SorterOpen" OpHelp(""), |
| 23616 | /* 57 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 23617 | /* 58 */ "Close" OpHelp(""), |
| 23618 | /* 59 */ "SeekLT" OpHelp(""), |
| 23619 | /* 60 */ "SeekLE" OpHelp(""), |
| 23620 | /* 61 */ "SeekGE" OpHelp(""), |
| 23621 | /* 62 */ "SeekGT" OpHelp(""), |
| 23622 | /* 63 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23623 | /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23624 | /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23625 | /* 66 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23626 | /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23627 | /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23628 | /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23629 | /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23630 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23631 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23632 | /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23633 | /* 74 */ "Delete" OpHelp(""), |
| 23634 | /* 75 */ "ResetCount" OpHelp(""), |
| 23635 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23636 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23637 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23638 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23639 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23640 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23641 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23642 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23643 | /* 84 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), |
| 23644 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23645 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23646 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23647 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23648 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | |
| 23649 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23650 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 23651 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23652 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 23653 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 23654 | /* 95 */ "SorterData" OpHelp("r[P2]=data"), |
| 23655 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 23656 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 23657 | /* 98 */ "RowKey" OpHelp("r[P2]=key"), |
| 23658 | /* 99 */ "RowData" OpHelp("r[P2]=data"), |
| 23659 | /* 100 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 23660 | /* 101 */ "NullRow" OpHelp(""), |
| 23661 | /* 102 */ "Last" OpHelp(""), |
| 23662 | /* 103 */ "SorterSort" OpHelp(""), |
| 23663 | /* 104 */ "Sort" OpHelp(""), |
| 23664 | /* 105 */ "Rewind" OpHelp(""), |
| 23665 | /* 106 */ "SorterInsert" OpHelp(""), |
| 23666 | /* 107 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 23667 | /* 108 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 23668 | /* 109 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 23669 | /* 110 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 23670 | /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 23671 | /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 23672 | /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 23673 | /* 114 */ "Destroy" OpHelp(""), |
| 23674 | /* 115 */ "Clear" OpHelp(""), |
| 23675 | /* 116 */ "ResetSorter" OpHelp(""), |
| 23676 | /* 117 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23677 | /* 118 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23678 | /* 119 */ "ParseSchema" OpHelp(""), |
| 23679 | /* 120 */ "LoadAnalysis" OpHelp(""), |
| 23680 | /* 121 */ "DropTable" OpHelp(""), |
| 23681 | /* 122 */ "DropIndex" OpHelp(""), |
| 23682 | /* 123 */ "DropTrigger" OpHelp(""), |
| 23683 | /* 124 */ "IntegrityCk" OpHelp(""), |
| 23684 | /* 125 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23685 | /* 126 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23686 | /* 127 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23687 | /* 128 */ "Program" OpHelp(""), |
| 23688 | /* 129 */ "Param" OpHelp(""), |
| 23689 | /* 130 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23690 | /* 131 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23691 | /* 132 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23692 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23693 | /* 134 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 23694 | /* 135 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23695 | /* 136 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 23696 | /* 137 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23697 | /* 138 */ "IncrVacuum" OpHelp(""), |
| 23698 | /* 139 */ "Expire" OpHelp(""), |
| 23699 | /* 140 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23700 | /* 141 */ "VBegin" OpHelp(""), |
| 23701 | /* 142 */ "VCreate" OpHelp(""), |
| 23702 | /* 143 */ "ToText" OpHelp(""), |
| 23703 | /* 144 */ "ToBlob" OpHelp(""), |
| 23704 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23705 | /* 146 */ "ToInt" OpHelp(""), |
| 23706 | /* 147 */ "ToReal" OpHelp(""), |
| 23707 | /* 148 */ "VDestroy" OpHelp(""), |
| 23708 | /* 149 */ "VOpen" OpHelp(""), |
| 23709 | /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23710 | /* 151 */ "VNext" OpHelp(""), |
| 23711 | /* 152 */ "VRename" OpHelp(""), |
| 23712 | /* 153 */ "Pagecount" OpHelp(""), |
| 23713 | /* 154 */ "MaxPgcnt" OpHelp(""), |
| 23714 | /* 155 */ "Init" OpHelp("Start at P2"), |
| 23715 | /* 156 */ "Noop" OpHelp(""), |
| 23716 | /* 157 */ "Explain" OpHelp(""), |
| 23717 | }; |
| 23718 | return azName[i]; |
| 23719 | } |
| 23720 | #endif |
| 23721 | |
| @@ -32066,14 +32416,14 @@ | |
| 32066 | ** |
| 32067 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32068 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32069 | */ |
| 32070 | #ifdef SQLITE_TEST |
| 32071 | SQLITE_API int sqlite3_os_type = 0; |
| 32072 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32073 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32074 | static int sqlite3_os_type = 0; |
| 32075 | #endif |
| 32076 | |
| 32077 | #ifndef SYSCALL |
| 32078 | # define SYSCALL sqlite3_syscall_ptr |
| 32079 | #endif |
| @@ -32699,10 +33049,15 @@ | |
| 32699 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 32700 | #endif |
| 32701 | |
| 32702 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 32703 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 32704 | |
| 32705 | }; /* End of the overrideable system calls */ |
| 32706 | |
| 32707 | /* |
| 32708 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | |
| 32950 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32951 | # define osIsNT() (1) |
| 32952 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32953 | # define osIsNT() (0) |
| 32954 | #else |
| 32955 | static int osIsNT(void){ |
| 32956 | if( sqlite3_os_type==0 ){ |
| 32957 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 32958 | OSVERSIONINFOW sInfo; |
| 32959 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 32960 | osGetVersionExW(&sInfo); |
| 32961 | #else |
| 32962 | OSVERSIONINFOA sInfo; |
| 32963 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 32964 | osGetVersionExA(&sInfo); |
| 32965 | #endif |
| 32966 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 32967 | } |
| 32968 | return sqlite3_os_type==2; |
| 32969 | } |
| 32970 | #endif |
| 32971 | |
| 32972 | #ifdef SQLITE_WIN32_MALLOC |
| 32973 | /* |
| 32974 | ** Allocate nBytes of memory. |
| 32975 | */ |
| @@ -37121,11 +37483,11 @@ | |
| 37121 | }; |
| 37122 | #endif |
| 37123 | |
| 37124 | /* Double-check that the aSyscall[] array has been constructed |
| 37125 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37126 | assert( ArraySize(aSyscall)==76 ); |
| 37127 | |
| 37128 | /* get memory map allocation granularity */ |
| 37129 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37130 | #if SQLITE_OS_WINRT |
| 37131 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | |
| 52813 | return pBt->nPage; |
| 52814 | } |
| 52815 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 52816 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52817 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 52818 | return (int)btreePagecount(p->pBt); |
| 52819 | } |
| 52820 | |
| 52821 | /* |
| 52822 | ** Get a page from the pager and initialize it. This routine is just a |
| 52823 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | |
| 62354 | } |
| 62355 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62356 | pParse->aLabel = 0; |
| 62357 | pParse->nLabel = 0; |
| 62358 | *pMaxFuncArgs = nMaxArgs; |
| 62359 | assert( p->bIsReader!=0 || p->btreeMask==0 ); |
| 62360 | } |
| 62361 | |
| 62362 | /* |
| 62363 | ** Return the address of the next instruction to be inserted. |
| 62364 | */ |
| @@ -62381,11 +62743,11 @@ | |
| 62381 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62382 | VdbeOp *aOp = p->aOp; |
| 62383 | assert( aOp && !p->db->mallocFailed ); |
| 62384 | |
| 62385 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62386 | assert( p->btreeMask==0 ); |
| 62387 | |
| 62388 | resolveP2Values(p, pnMaxArg); |
| 62389 | *pnOp = p->nOp; |
| 62390 | p->aOp = 0; |
| 62391 | return aOp; |
| @@ -62966,13 +63328,13 @@ | |
| 62966 | ** p->btreeMask of databases that will require a lock. |
| 62967 | */ |
| 62968 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 62969 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 62970 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 62971 | p->btreeMask |= ((yDbMask)1)<<i; |
| 62972 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 62973 | p->lockMask |= ((yDbMask)1)<<i; |
| 62974 | } |
| 62975 | } |
| 62976 | |
| 62977 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 62978 | /* |
| @@ -62996,20 +63358,19 @@ | |
| 62996 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 62997 | ** be a problem. |
| 62998 | */ |
| 62999 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63000 | int i; |
| 63001 | yDbMask mask; |
| 63002 | sqlite3 *db; |
| 63003 | Db *aDb; |
| 63004 | int nDb; |
| 63005 | if( p->lockMask==0 ) return; /* The common case */ |
| 63006 | db = p->db; |
| 63007 | aDb = db->aDb; |
| 63008 | nDb = db->nDb; |
| 63009 | for(i=0, mask=1; i<nDb; i++, mask += mask){ |
| 63010 | if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ |
| 63011 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63012 | } |
| 63013 | } |
| 63014 | } |
| 63015 | #endif |
| @@ -63018,20 +63379,19 @@ | |
| 63018 | /* |
| 63019 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63020 | */ |
| 63021 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63022 | int i; |
| 63023 | yDbMask mask; |
| 63024 | sqlite3 *db; |
| 63025 | Db *aDb; |
| 63026 | int nDb; |
| 63027 | if( p->lockMask==0 ) return; /* The common case */ |
| 63028 | db = p->db; |
| 63029 | aDb = db->aDb; |
| 63030 | nDb = db->nDb; |
| 63031 | for(i=0, mask=1; i<nDb; i++, mask += mask){ |
| 63032 | if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ |
| 63033 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63034 | } |
| 63035 | } |
| 63036 | } |
| 63037 | #endif |
| @@ -63998,11 +64358,11 @@ | |
| 63998 | int cnt = 0; |
| 63999 | int nWrite = 0; |
| 64000 | int nRead = 0; |
| 64001 | p = db->pVdbe; |
| 64002 | while( p ){ |
| 64003 | if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ |
| 64004 | cnt++; |
| 64005 | if( p->readOnly==0 ) nWrite++; |
| 64006 | if( p->bIsReader ) nRead++; |
| 64007 | } |
| 64008 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | |
| 64643 | /* |
| 64644 | ** Return the serial-type for the value stored in pMem. |
| 64645 | */ |
| 64646 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 64647 | int flags = pMem->flags; |
| 64648 | int n; |
| 64649 | |
| 64650 | if( flags&MEM_Null ){ |
| 64651 | return 0; |
| 64652 | } |
| 64653 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | |
| 64673 | } |
| 64674 | if( flags&MEM_Real ){ |
| 64675 | return 7; |
| 64676 | } |
| 64677 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 64678 | n = pMem->n; |
| 64679 | if( flags & MEM_Zero ){ |
| 64680 | n += pMem->u.nZero; |
| 64681 | } |
| 64682 | assert( n>=0 ); |
| 64683 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 64684 | } |
| 64685 | |
| 64686 | /* |
| 64687 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | |
| 67195 | /* |
| 67196 | ** Return true if the prepared statement is in need of being reset. |
| 67197 | */ |
| 67198 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67199 | Vdbe *v = (Vdbe*)pStmt; |
| 67200 | return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; |
| 67201 | } |
| 67202 | |
| 67203 | /* |
| 67204 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67205 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | |
| 67753 | ** do so without loss of information. In other words, if the string |
| 67754 | ** looks like a number, convert it into a number. If it does not |
| 67755 | ** look like a number, leave it alone. |
| 67756 | */ |
| 67757 | static void applyNumericAffinity(Mem *pRec){ |
| 67758 | if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ |
| 67759 | double rValue; |
| 67760 | i64 iValue; |
| 67761 | u8 enc = pRec->enc; |
| 67762 | if( (pRec->flags&MEM_Str)==0 ) return; |
| 67763 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; |
| 67764 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ |
| 67765 | pRec->u.i = iValue; |
| 67766 | pRec->flags |= MEM_Int; |
| 67767 | }else{ |
| 67768 | pRec->r = rValue; |
| 67769 | pRec->flags |= MEM_Real; |
| 67770 | } |
| 67771 | } |
| 67772 | } |
| 67773 | |
| 67774 | /* |
| 67775 | ** Processing is determine by the affinity parameter: |
| 67776 | ** |
| 67777 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | |
| 67804 | } |
| 67805 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 67806 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 67807 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 67808 | || affinity==SQLITE_AFF_NUMERIC ); |
| 67809 | applyNumericAffinity(pRec); |
| 67810 | if( pRec->flags & MEM_Real ){ |
| 67811 | sqlite3VdbeIntegerAffinity(pRec); |
| 67812 | } |
| 67813 | } |
| 67814 | } |
| @@ -68385,16 +68745,18 @@ | |
| 68385 | break; |
| 68386 | } |
| 68387 | |
| 68388 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68389 | ** |
| 68390 | ** Set up register P1 so that it will OP_Yield to the co-routine |
| 68391 | ** located at address P3. |
| 68392 | ** |
| 68393 | ** If P2!=0 then the co-routine implementation immediately follows |
| 68394 | ** this opcode. So jump over the co-routine implementation to |
| 68395 | ** address P2. |
| 68396 | */ |
| 68397 | case OP_InitCoroutine: { /* jump */ |
| 68398 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68399 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68400 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | |
| 68406 | break; |
| 68407 | } |
| 68408 | |
| 68409 | /* Opcode: EndCoroutine P1 * * * * |
| 68410 | ** |
| 68411 | ** The instruction at the address in register P1 is an OP_Yield. |
| 68412 | ** Jump to the P2 parameter of that OP_Yield. |
| 68413 | ** After the jump, register P1 becomes undefined. |
| 68414 | */ |
| 68415 | case OP_EndCoroutine: { /* in1 */ |
| 68416 | VdbeOp *pCaller; |
| 68417 | pIn1 = &aMem[pOp->p1]; |
| 68418 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | |
| 68425 | break; |
| 68426 | } |
| 68427 | |
| 68428 | /* Opcode: Yield P1 P2 * * * |
| 68429 | ** |
| 68430 | ** Swap the program counter with the value in register P1. |
| 68431 | ** |
| 68432 | ** If the co-routine ends with OP_Yield or OP_Return then continue |
| 68433 | ** to the next instruction. But if the co-routine ends with |
| 68434 | ** OP_EndCoroutine, jump immediately to P2. |
| 68435 | */ |
| 68436 | case OP_Yield: { /* in1, jump */ |
| 68437 | int pcDest; |
| 68438 | pIn1 = &aMem[pOp->p1]; |
| 68439 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | |
| 69814 | break; |
| 69815 | } |
| 69816 | |
| 69817 | /* Opcode: Once P1 P2 * * * |
| 69818 | ** |
| 69819 | ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, |
| 69820 | ** set the flag and fall through to the next instruction. In other words, |
| 69821 | ** this opcode causes all following opcodes up through P2 (but not including |
| 69822 | ** P2) to run just once and to be skipped on subsequent times through the loop. |
| 69823 | */ |
| 69824 | case OP_Once: { /* jump */ |
| 69825 | assert( pOp->p1<p->nOnceFlag ); |
| 69826 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 69827 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | |
| 70652 | int iGen; |
| 70653 | |
| 70654 | assert( p->bIsReader ); |
| 70655 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 70656 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70657 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 70658 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 70659 | rc = SQLITE_READONLY; |
| 70660 | goto abort_due_to_error; |
| 70661 | } |
| 70662 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | |
| 70747 | iDb = pOp->p1; |
| 70748 | iCookie = pOp->p3; |
| 70749 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 70750 | assert( iDb>=0 && iDb<db->nDb ); |
| 70751 | assert( db->aDb[iDb].pBt!=0 ); |
| 70752 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 70753 | |
| 70754 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 70755 | pOut->u.i = iMeta; |
| 70756 | break; |
| 70757 | } |
| @@ -70768,11 +71141,11 @@ | |
| 70768 | */ |
| 70769 | case OP_SetCookie: { /* in3 */ |
| 70770 | Db *pDb; |
| 70771 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 70772 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70773 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 70774 | assert( p->readOnly==0 ); |
| 70775 | pDb = &db->aDb[pOp->p1]; |
| 70776 | assert( pDb->pBt!=0 ); |
| 70777 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 70778 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | |
| 70823 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 70824 | ** structure, then said structure defines the content and collating |
| 70825 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 70826 | ** value, it is set to the number of columns in the table. |
| 70827 | ** |
| 70828 | ** See also OpenWrite. |
| 70829 | */ |
| 70830 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 70831 | ** Synopsis: root=P2 iDb=P3 |
| 70832 | ** |
| 70833 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | |
| 70845 | ** in read/write mode. For a given table, there can be one or more read-only |
| 70846 | ** cursors or a single read/write cursor but not both. |
| 70847 | ** |
| 70848 | ** See also OpenRead. |
| 70849 | */ |
| 70850 | case OP_OpenRead: |
| 70851 | case OP_OpenWrite: { |
| 70852 | int nField; |
| 70853 | KeyInfo *pKeyInfo; |
| 70854 | int p2; |
| @@ -70859,11 +71259,12 @@ | |
| 70859 | Db *pDb; |
| 70860 | |
| 70861 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 70862 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 70863 | assert( p->bIsReader ); |
| 70864 | assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); |
| 70865 | |
| 70866 | if( p->expired ){ |
| 70867 | rc = SQLITE_ABORT; |
| 70868 | break; |
| 70869 | } |
| @@ -70871,11 +71272,11 @@ | |
| 70871 | nField = 0; |
| 70872 | pKeyInfo = 0; |
| 70873 | p2 = pOp->p2; |
| 70874 | iDb = pOp->p3; |
| 70875 | assert( iDb>=0 && iDb<db->nDb ); |
| 70876 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 70877 | pDb = &db->aDb[iDb]; |
| 70878 | pX = pDb->pBt; |
| 70879 | assert( pX!=0 ); |
| 70880 | if( pOp->opcode==OP_OpenWrite ){ |
| 70881 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | |
| 70916 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 70917 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 70918 | if( pCur==0 ) goto no_mem; |
| 70919 | pCur->nullRow = 1; |
| 70920 | pCur->isOrdered = 1; |
| 70921 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 70922 | pCur->pKeyInfo = pKeyInfo; |
| 70923 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 70924 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 70925 | |
| @@ -71070,11 +71472,11 @@ | |
| 71070 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71071 | p->apCsr[pOp->p1] = 0; |
| 71072 | break; |
| 71073 | } |
| 71074 | |
| 71075 | /* Opcode: SeekGe P1 P2 P3 P4 * |
| 71076 | ** Synopsis: key=r[P3@P4] |
| 71077 | ** |
| 71078 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71079 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71080 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | |
| 71081 | ** that are used as an unpacked index key. |
| 71082 | ** |
| 71083 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71084 | ** is greater than or equal to the key value. If there are no records |
| 71085 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71086 | ** |
| 71087 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71088 | */ |
| 71089 | /* Opcode: SeekGt P1 P2 P3 P4 * |
| 71090 | ** Synopsis: key=r[P3@P4] |
| 71091 | ** |
| 71092 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71093 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71094 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | |
| 71095 | ** that are used as an unpacked index key. |
| 71096 | ** |
| 71097 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71098 | ** is greater than the key value. If there are no records greater than |
| 71099 | ** the key and P2 is not zero, then jump to P2. |
| 71100 | ** |
| 71101 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71102 | */ |
| 71103 | /* Opcode: SeekLt P1 P2 P3 P4 * |
| 71104 | ** Synopsis: key=r[P3@P4] |
| 71105 | ** |
| 71106 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71107 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71108 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | |
| 71109 | ** that are used as an unpacked index key. |
| 71110 | ** |
| 71111 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71112 | ** is less than the key value. If there are no records less than |
| 71113 | ** the key and P2 is not zero, then jump to P2. |
| 71114 | ** |
| 71115 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71116 | */ |
| 71117 | /* Opcode: SeekLe P1 P2 P3 P4 * |
| 71118 | ** Synopsis: key=r[P3@P4] |
| 71119 | ** |
| 71120 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71121 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71122 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | |
| 71123 | ** that are used as an unpacked index key. |
| 71124 | ** |
| 71125 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71126 | ** is less than or equal to the key value. If there are no records |
| 71127 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71128 | ** |
| 71129 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71130 | */ |
| 71131 | case OP_SeekLT: /* jump, in3 */ |
| 71132 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | |
| 71149 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71150 | assert( pC->isOrdered ); |
| 71151 | assert( pC->pCursor!=0 ); |
| 71152 | oc = pOp->opcode; |
| 71153 | pC->nullRow = 0; |
| 71154 | if( pC->isTable ){ |
| 71155 | /* The input value in P3 might be of any type: integer, real, string, |
| 71156 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71157 | ** the seek, so covert it. */ |
| 71158 | pIn3 = &aMem[pOp->p3]; |
| 71159 | applyNumericAffinity(pIn3); |
| 71160 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71161 | pC->rowidIsValid = 0; |
| 71162 | |
| 71163 | /* If the P3 value could not be converted into an integer without |
| 71164 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | |
| 71303 | ** record. |
| 71304 | ** |
| 71305 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71306 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71307 | ** P1 is left pointing at the matching entry. |
| 71308 | ** |
| 71309 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71310 | */ |
| 71311 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71312 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | |
| 71318 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71319 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71320 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71321 | ** falls through to the next instruction and P1 is left pointing at the |
| 71322 | ** matching entry. |
| 71323 | ** |
| 71324 | ** See also: Found, NotExists, NoConflict |
| 71325 | */ |
| 71326 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71327 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | |
| 71337 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71338 | ** cursor pointing to the matching row. |
| 71339 | ** |
| 71340 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71341 | ** branch is always taken if any part of the search key input is NULL. |
| 71342 | ** |
| 71343 | ** See also: NotFound, Found, NotExists |
| 71344 | */ |
| 71345 | case OP_NoConflict: /* jump, in3 */ |
| 71346 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | |
| 71360 | |
| 71361 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71362 | assert( pOp->p4type==P4_INT32 ); |
| 71363 | pC = p->apCsr[pOp->p1]; |
| 71364 | assert( pC!=0 ); |
| 71365 | pIn3 = &aMem[pOp->p3]; |
| 71366 | assert( pC->pCursor!=0 ); |
| 71367 | assert( pC->isTable==0 ); |
| 71368 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71369 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | |
| 71430 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71431 | ** through to the next instruction. |
| 71432 | ** |
| 71433 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71434 | ** (with arbitrary multi-value keys). |
| 71435 | ** |
| 71436 | ** See also: Found, NotFound, NoConflict |
| 71437 | */ |
| 71438 | case OP_NotExists: { /* jump, in3 */ |
| 71439 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | |
| 71444 | pIn3 = &aMem[pOp->p3]; |
| 71445 | assert( pIn3->flags & MEM_Int ); |
| 71446 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71447 | pC = p->apCsr[pOp->p1]; |
| 71448 | assert( pC!=0 ); |
| 71449 | assert( pC->isTable ); |
| 71450 | assert( pC->pseudoTableReg==0 ); |
| 71451 | pCrsr = pC->pCursor; |
| 71452 | assert( pCrsr!=0 ); |
| 71453 | res = 0; |
| @@ -71806,16 +72249,16 @@ | |
| 71806 | p->nChange = 0; |
| 71807 | break; |
| 71808 | } |
| 71809 | |
| 71810 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 71811 | ** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 |
| 71812 | ** |
| 71813 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 71814 | ** the record blob in register P3 against a prefix of the entry that |
| 71815 | ** the sorter cursor currently points to. The final P4 fields of both |
| 71816 | ** the P3 and sorter record are ignored. |
| 71817 | ** |
| 71818 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 71819 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 71820 | ** the comparison is assumed to be equal. |
| 71821 | ** |
| @@ -71823,18 +72266,18 @@ | |
| 71823 | ** each other. Jump to P2 if they are different. |
| 71824 | */ |
| 71825 | case OP_SorterCompare: { |
| 71826 | VdbeCursor *pC; |
| 71827 | int res; |
| 71828 | int nIgnore; |
| 71829 | |
| 71830 | pC = p->apCsr[pOp->p1]; |
| 71831 | assert( isSorter(pC) ); |
| 71832 | assert( pOp->p4type==P4_INT32 ); |
| 71833 | pIn3 = &aMem[pOp->p3]; |
| 71834 | nIgnore = pOp->p4.i; |
| 71835 | rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); |
| 71836 | VdbeBranchTaken(res!=0,2); |
| 71837 | if( res ){ |
| 71838 | pc = pOp->p2-1; |
| 71839 | } |
| 71840 | break; |
| @@ -72010,15 +72453,19 @@ | |
| 72010 | break; |
| 72011 | } |
| 72012 | |
| 72013 | /* Opcode: Last P1 P2 * * * |
| 72014 | ** |
| 72015 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72016 | ** will refer to the last entry in the database table or index. |
| 72017 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72018 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72019 | ** to the following instruction. |
| 72020 | */ |
| 72021 | case OP_Last: { /* jump */ |
| 72022 | VdbeCursor *pC; |
| 72023 | BtCursor *pCrsr; |
| 72024 | int res; |
| @@ -72032,10 +72479,13 @@ | |
| 72032 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72033 | pC->nullRow = (u8)res; |
| 72034 | pC->deferredMoveto = 0; |
| 72035 | pC->rowidIsValid = 0; |
| 72036 | pC->cacheStatus = CACHE_STALE; |
| 72037 | if( pOp->p2>0 ){ |
| 72038 | VdbeBranchTaken(res!=0,2); |
| 72039 | if( res ) pc = pOp->p2 - 1; |
| 72040 | } |
| 72041 | break; |
| @@ -72068,10 +72518,14 @@ | |
| 72068 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72069 | ** will refer to the first entry in the database table or index. |
| 72070 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72071 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72072 | ** to the following instruction. |
| 72073 | */ |
| 72074 | case OP_Rewind: { /* jump */ |
| 72075 | VdbeCursor *pC; |
| 72076 | BtCursor *pCrsr; |
| 72077 | int res; |
| @@ -72079,10 +72533,13 @@ | |
| 72079 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72080 | pC = p->apCsr[pOp->p1]; |
| 72081 | assert( pC!=0 ); |
| 72082 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72083 | res = 1; |
| 72084 | if( isSorter(pC) ){ |
| 72085 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72086 | }else{ |
| 72087 | pCrsr = pC->pCursor; |
| 72088 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | |
| 72104 | ** |
| 72105 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72106 | ** table or index. If there are no more key/value pairs then fall through |
| 72107 | ** to the following instruction. But if the cursor advance was successful, |
| 72108 | ** jump immediately to P2. |
| 72109 | ** |
| 72110 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72111 | ** been opened prior to this opcode or the program will segfault. |
| 72112 | ** |
| 72113 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | |
| 72123 | ** |
| 72124 | ** See also: Prev, NextIfOpen |
| 72125 | */ |
| 72126 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72127 | ** |
| 72128 | ** This opcode works just like OP_Next except that if cursor P1 is not |
| 72129 | ** open it behaves a no-op. |
| 72130 | */ |
| 72131 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72132 | ** |
| 72133 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72134 | ** table or index. If there is no previous key/value pairs then fall through |
| 72135 | ** to the following instruction. But if the cursor backup was successful, |
| 72136 | ** jump immediately to P2. |
| 72137 | ** |
| 72138 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72139 | ** not open then the behavior is undefined. |
| 72140 | ** |
| 72141 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72142 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | |
| 72149 | ** If P5 is positive and the jump is taken, then event counter |
| 72150 | ** number P5-1 in the prepared statement is incremented. |
| 72151 | */ |
| 72152 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72153 | ** |
| 72154 | ** This opcode works just like OP_Prev except that if cursor P1 is not |
| 72155 | ** open it behaves a no-op. |
| 72156 | */ |
| 72157 | case OP_SorterNext: { /* jump */ |
| 72158 | VdbeCursor *pC; |
| 72159 | int res; |
| @@ -72180,10 +72646,20 @@ | |
| 72180 | testcase( res==1 ); |
| 72181 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72182 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72183 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72184 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72185 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72186 | next_tail: |
| 72187 | pC->cacheStatus = CACHE_STALE; |
| 72188 | VdbeBranchTaken(res==0,2); |
| 72189 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | |
| 72462 | rc = SQLITE_LOCKED; |
| 72463 | p->errorAction = OE_Abort; |
| 72464 | }else{ |
| 72465 | iDb = pOp->p3; |
| 72466 | assert( iCnt==1 ); |
| 72467 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 72468 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72469 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72470 | pOut->flags = MEM_Int; |
| 72471 | pOut->u.i = iMoved; |
| 72472 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | |
| 72502 | case OP_Clear: { |
| 72503 | int nChange; |
| 72504 | |
| 72505 | nChange = 0; |
| 72506 | assert( p->readOnly==0 ); |
| 72507 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 72508 | rc = sqlite3BtreeClearTable( |
| 72509 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72510 | ); |
| 72511 | if( pOp->p3 ){ |
| 72512 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | |
| 72572 | int flags; |
| 72573 | Db *pDb; |
| 72574 | |
| 72575 | pgno = 0; |
| 72576 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72577 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 72578 | assert( p->readOnly==0 ); |
| 72579 | pDb = &db->aDb[pOp->p1]; |
| 72580 | assert( pDb->pBt!=0 ); |
| 72581 | if( pOp->opcode==OP_CreateTable ){ |
| 72582 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | |
| 72660 | |
| 72661 | /* Opcode: DropTable P1 * * P4 * |
| 72662 | ** |
| 72663 | ** Remove the internal (in-memory) data structures that describe |
| 72664 | ** the table named P4 in database P1. This is called after a table |
| 72665 | ** is dropped in order to keep the internal representation of the |
| 72666 | ** schema consistent with what is on disk. |
| 72667 | */ |
| 72668 | case OP_DropTable: { |
| 72669 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 72670 | break; |
| @@ -72672,11 +73149,12 @@ | |
| 72672 | |
| 72673 | /* Opcode: DropIndex P1 * * P4 * |
| 72674 | ** |
| 72675 | ** Remove the internal (in-memory) data structures that describe |
| 72676 | ** the index named P4 in database P1. This is called after an index |
| 72677 | ** is dropped in order to keep the internal representation of the |
| 72678 | ** schema consistent with what is on disk. |
| 72679 | */ |
| 72680 | case OP_DropIndex: { |
| 72681 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 72682 | break; |
| @@ -72684,11 +73162,12 @@ | |
| 72684 | |
| 72685 | /* Opcode: DropTrigger P1 * * P4 * |
| 72686 | ** |
| 72687 | ** Remove the internal (in-memory) data structures that describe |
| 72688 | ** the trigger named P4 in database P1. This is called after a trigger |
| 72689 | ** is dropped in order to keep the internal representation of the |
| 72690 | ** schema consistent with what is on disk. |
| 72691 | */ |
| 72692 | case OP_DropTrigger: { |
| 72693 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 72694 | break; |
| @@ -72737,11 +73216,11 @@ | |
| 72737 | for(j=0; j<nRoot; j++){ |
| 72738 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 72739 | } |
| 72740 | aRoot[j] = 0; |
| 72741 | assert( pOp->p5<db->nDb ); |
| 72742 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 72743 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 72744 | (int)pnErr->u.i, &nErr); |
| 72745 | sqlite3DbFree(db, aRoot); |
| 72746 | pnErr->u.i -= nErr; |
| 72747 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | |
| 73397 | */ |
| 73398 | case OP_IncrVacuum: { /* jump */ |
| 73399 | Btree *pBt; |
| 73400 | |
| 73401 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73402 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 73403 | assert( p->readOnly==0 ); |
| 73404 | pBt = db->aDb[pOp->p1].pBt; |
| 73405 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73406 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73407 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | |
| 73412 | } |
| 73413 | #endif |
| 73414 | |
| 73415 | /* Opcode: Expire P1 * * * * |
| 73416 | ** |
| 73417 | ** Cause precompiled statements to become expired. An expired statement |
| 73418 | ** fails with an error code of SQLITE_SCHEMA if it is ever executed |
| 73419 | ** (via sqlite3_step()). |
| 73420 | ** |
| 73421 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73422 | ** then only the currently executing statement is affected. |
| 73423 | */ |
| 73424 | case OP_Expire: { |
| 73425 | if( !pOp->p1 ){ |
| 73426 | sqlite3ExpirePreparedStatements(db); |
| 73427 | }else{ |
| @@ -73449,11 +73929,11 @@ | |
| 73449 | case OP_TableLock: { |
| 73450 | u8 isWriteLock = (u8)pOp->p3; |
| 73451 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73452 | int p1 = pOp->p1; |
| 73453 | assert( p1>=0 && p1<db->nDb ); |
| 73454 | assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); |
| 73455 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73456 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73457 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73458 | const char *z = pOp->p4.z; |
| 73459 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | |
| 73899 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 73900 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 73901 | if( zTrace ){ |
| 73902 | int i; |
| 73903 | for(i=0; i<db->nDb; i++){ |
| 73904 | if( (MASKBIT(i) & p->btreeMask)==0 ) continue; |
| 73905 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 73906 | } |
| 73907 | } |
| 73908 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 73909 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | |
| 74889 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 74890 | ** has been allocated and contains an unpacked record that is used as key2. |
| 74891 | */ |
| 74892 | static void vdbeSorterCompare( |
| 74893 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 74894 | int nIgnore, /* Ignore the last nIgnore fields */ |
| 74895 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 74896 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 74897 | int *pRes /* OUT: Result of comparison */ |
| 74898 | ){ |
| 74899 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | |
| 74903 | |
| 74904 | if( pKey2 ){ |
| 74905 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 74906 | } |
| 74907 | |
| 74908 | if( nIgnore ){ |
| 74909 | r2->nField = pKeyInfo->nField - nIgnore; |
| 74910 | assert( r2->nField>0 ); |
| 74911 | for(i=0; i<r2->nField; i++){ |
| 74912 | if( r2->aMem[i].flags & MEM_Null ){ |
| 74913 | *pRes = -1; |
| 74914 | return; |
| 74915 | } |
| 74916 | } |
| @@ -75588,18 +76067,18 @@ | |
| 75588 | ** key. |
| 75589 | */ |
| 75590 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 75591 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 75592 | Mem *pVal, /* Value to compare to current sorter key */ |
| 75593 | int nIgnore, /* Ignore this many fields at the end */ |
| 75594 | int *pRes /* OUT: Result of comparison */ |
| 75595 | ){ |
| 75596 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75597 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 75598 | |
| 75599 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 75600 | vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes); |
| 75601 | return SQLITE_OK; |
| 75602 | } |
| 75603 | |
| 75604 | /************** End of vdbesort.c ********************************************/ |
| 75605 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | |
| 79352 | } |
| 79353 | } |
| 79354 | } |
| 79355 | |
| 79356 | if( eType==0 ){ |
| 79357 | /* Could not found an existing table or index to use as the RHS b-tree. |
| 79358 | ** We will have to generate an ephemeral table to do the job. |
| 79359 | */ |
| 79360 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79361 | int rMayHaveNull = 0; |
| 79362 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | |
| 79482 | /* Case 1: expr IN (SELECT ...) |
| 79483 | ** |
| 79484 | ** Generate code to write the results of the select into the temporary |
| 79485 | ** table allocated and opened above. |
| 79486 | */ |
| 79487 | SelectDest dest; |
| 79488 | ExprList *pEList; |
| 79489 | |
| 79490 | assert( !isRowid ); |
| 79491 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79492 | dest.affSdst = (u8)affinity; |
| 79493 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79494 | pExpr->x.pSelect->iLimit = 0; |
| 79495 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79496 | if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ |
| 79497 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79498 | return 0; |
| 79499 | } |
| 79500 | pEList = pExpr->x.pSelect->pEList; |
| 79501 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79502 | assert( pEList!=0 ); |
| 79503 | assert( pEList->nExpr>0 ); |
| 79504 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79505 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | |
| 79803 | }else{ |
| 79804 | int c; |
| 79805 | i64 value; |
| 79806 | const char *z = pExpr->u.zToken; |
| 79807 | assert( z!=0 ); |
| 79808 | c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); |
| 79809 | if( c==0 || (c==2 && negFlag) ){ |
| 79810 | char *zV; |
| 79811 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 79812 | zV = dup8bytes(v, (char*)&value); |
| 79813 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 79814 | }else{ |
| 79815 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 79816 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 79817 | #else |
| 79818 | codeReal(v, z, negFlag, iMem); |
| 79819 | #endif |
| 79820 | } |
| 79821 | } |
| 79822 | } |
| 79823 | |
| @@ -83186,19 +83675,24 @@ | |
| 83186 | } |
| 83187 | |
| 83188 | /* |
| 83189 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83190 | ** are: |
| 83191 | ** N: The number of columns in the index including the rowid/pk |
| 83192 | ** K: The number of columns in the index excluding the rowid/pk |
| 83193 | ** C: The number of rows in the index |
| 83194 | ** |
| 83195 | ** C is only used for STAT3 and STAT4. |
| 83196 | ** |
| 83197 | ** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables, |
| 83198 | ** N=K+P where P is the number of columns in the primary key. For the |
| 83199 | ** covering index that implements the original WITHOUT ROWID table, N==K. |
| 83200 | ** |
| 83201 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83202 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83203 | ** the size of the blob is sizeof(void*) bytes). |
| 83204 | */ |
| @@ -83504,11 +83998,14 @@ | |
| 83504 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83505 | ** C Index of left-most column to differ from previous row |
| 83506 | ** R Rowid for the current row. Might be a key record for |
| 83507 | ** WITHOUT ROWID tables. |
| 83508 | ** |
| 83509 | ** The SQL function always returns NULL. |
| 83510 | ** |
| 83511 | ** The R parameter is only used for STAT3 and STAT4 |
| 83512 | */ |
| 83513 | static void statPush( |
| 83514 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | |
| 83598 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 83599 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 83600 | |
| 83601 | /* |
| 83602 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 83603 | ** used to query the results. Content is returned for parameter J |
| 83604 | ** which is one of the STAT_GET_xxxx values defined above. |
| 83605 | ** |
| 83606 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 83607 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 83608 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | |
| 83817 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 83818 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 83819 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 83820 | |
| 83821 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 83822 | int nCol; /* Number of columns indexed by pIdx */ |
| 83823 | int *aGotoChng; /* Array of jump instruction addresses */ |
| 83824 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 83825 | int addrGotoChng0; /* Address of "Goto addr_chng_0" */ |
| 83826 | int addrNextRow; /* Address of "next_row:" */ |
| 83827 | const char *zIdxName; /* Name of the index */ |
| 83828 | |
| 83829 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 83830 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 83831 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 83832 | nCol = pIdx->nKeyCol; |
| 83833 | zIdxName = pTab->zName; |
| 83834 | }else{ |
| 83835 | nCol = pIdx->nColumn; |
| 83836 | zIdxName = pIdx->zName; |
| 83837 | } |
| 83838 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 83839 | if( aGotoChng==0 ) continue; |
| 83840 | |
| 83841 | /* Populate the register containing the index name. */ |
| 83842 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 83843 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 83844 | |
| @@ -83863,11 +84362,11 @@ | |
| 83863 | ** regPrev(0) = idx(0) |
| 83864 | ** chng_addr_1: |
| 83865 | ** regPrev(1) = idx(1) |
| 83866 | ** ... |
| 83867 | ** |
| 83868 | ** chng_addr_N: |
| 83869 | ** regRowid = idx(rowid) |
| 83870 | ** stat_push(P, regChng, regRowid) |
| 83871 | ** Next csr |
| 83872 | ** if !eof(csr) goto next_row; |
| 83873 | ** |
| @@ -83876,24 +84375,27 @@ | |
| 83876 | |
| 83877 | /* Make sure there are enough memory cells allocated to accommodate |
| 83878 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 83879 | ** when building a record to insert into the sample column of |
| 83880 | ** the sqlite_stat4 table. */ |
| 83881 | pParse->nMem = MAX(pParse->nMem, regPrev+nCol); |
| 83882 | |
| 83883 | /* Open a read-only cursor on the index being analyzed. */ |
| 83884 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 83885 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 83886 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 83887 | VdbeComment((v, "%s", pIdx->zName)); |
| 83888 | |
| 83889 | /* Invoke the stat_init() function. The arguments are: |
| 83890 | ** |
| 83891 | ** (1) the number of columns in the index including the rowid, |
| 83892 | ** (2) the number of rows in the index, |
| 83893 | ** |
| 83894 | ** The second argument is only used for STAT3 and STAT4 |
| 83895 | */ |
| 83896 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83897 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 83898 | #endif |
| 83899 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | |
| 83911 | ** |
| 83912 | */ |
| 83913 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 83914 | VdbeCoverage(v); |
| 83915 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 83916 | addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 83917 | |
| 83918 | /* |
| 83919 | ** next_row: |
| 83920 | ** regChng = 0 |
| 83921 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 83922 | ** regChng = 1 |
| 83923 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 83924 | ** ... |
| 83925 | ** regChng = N |
| 83926 | ** goto chng_addr_N |
| 83927 | */ |
| 83928 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 83929 | for(i=0; i<nCol; i++){ |
| 83930 | char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 83931 | sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 83932 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 83933 | aGotoChng[i] = |
| 83934 | sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 83935 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 83936 | VdbeCoverage(v); |
| 83937 | } |
| 83938 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); |
| 83939 | aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); |
| 83940 | |
| 83941 | /* |
| 83942 | ** chng_addr_0: |
| 83943 | ** regPrev(0) = idx(0) |
| 83944 | ** chng_addr_1: |
| 83945 | ** regPrev(1) = idx(1) |
| 83946 | ** ... |
| 83947 | */ |
| 83948 | sqlite3VdbeJumpHere(v, addrGotoChng0); |
| 83949 | for(i=0; i<nCol; i++){ |
| 83950 | sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 83951 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 83952 | } |
| 83953 | |
| 83954 | /* |
| 83955 | ** chng_addr_N: |
| 83956 | ** regRowid = idx(rowid) // STAT34 only |
| 83957 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 83958 | ** Next csr |
| 83959 | ** if !eof(csr) goto next_row; |
| 83960 | */ |
| 83961 | sqlite3VdbeJumpHere(v, aGotoChng[nCol]); |
| 83962 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83963 | assert( regRowid==(regStat4+2) ); |
| 83964 | if( HasRowid(pTab) ){ |
| 83965 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 83966 | }else{ |
| @@ -84034,11 +84553,10 @@ | |
| 84034 | } |
| 84035 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84036 | |
| 84037 | /* End of analysis */ |
| 84038 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84039 | sqlite3DbFree(db, aGotoChng); |
| 84040 | } |
| 84041 | |
| 84042 | |
| 84043 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84044 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | |
| 84135 | int i; |
| 84136 | char *z, *zDb; |
| 84137 | Table *pTab; |
| 84138 | Index *pIdx; |
| 84139 | Token *pTableName; |
| 84140 | |
| 84141 | /* Read the database schema. If an error occurs, leave an error message |
| 84142 | ** and code in pParse and return NULL. */ |
| 84143 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84144 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | |
| 84182 | } |
| 84183 | sqlite3DbFree(db, z); |
| 84184 | } |
| 84185 | } |
| 84186 | } |
| 84187 | } |
| 84188 | |
| 84189 | /* |
| 84190 | ** Used to pass information from the analyzer reader through to the |
| 84191 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | |
| 84240 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84241 | assert( pIndex!=0 ); |
| 84242 | #else |
| 84243 | if( pIndex ) |
| 84244 | #endif |
| 84245 | { |
| 84246 | if( strcmp(z, "unordered")==0 ){ |
| 84247 | pIndex->bUnordered = 1; |
| 84248 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84249 | int v32 = 0; |
| 84250 | sqlite3GetInt32(z+3, &v32); |
| 84251 | pIndex->szIdxRow = sqlite3LogEst(v32); |
| 84252 | } |
| 84253 | } |
| 84254 | } |
| 84255 | |
| 84256 | /* |
| 84257 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | |
| 84288 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84289 | } |
| 84290 | z = argv[2]; |
| 84291 | |
| 84292 | if( pIndex ){ |
| 84293 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84294 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84295 | }else{ |
| 84296 | Index fakeIdx; |
| 84297 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84298 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84299 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84300 | } |
| 84301 | |
| 84302 | return 0; |
| @@ -85568,10 +86098,23 @@ | |
| 85568 | } |
| 85569 | #else |
| 85570 | #define codeTableLocks(x) |
| 85571 | #endif |
| 85572 | |
| 85573 | /* |
| 85574 | ** This routine is called after a single SQL statement has been |
| 85575 | ** parsed and a VDBE program to execute that statement has been |
| 85576 | ** prepared. This routine puts the finishing touches on the |
| 85577 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | |
| 85604 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 85605 | ** set for each database that is used. Generate code to start a |
| 85606 | ** transaction on each used database and to verify the schema cookie |
| 85607 | ** on each used database. |
| 85608 | */ |
| 85609 | if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ |
| 85610 | yDbMask mask; |
| 85611 | int iDb, i; |
| 85612 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 85613 | sqlite3VdbeJumpHere(v, 0); |
| 85614 | for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ |
| 85615 | if( (mask & pParse->cookieMask)==0 ) continue; |
| 85616 | sqlite3VdbeUsesBtree(v, iDb); |
| 85617 | sqlite3VdbeAddOp4Int(v, |
| 85618 | OP_Transaction, /* Opcode */ |
| 85619 | iDb, /* P1 */ |
| 85620 | (mask & pParse->writeMask)!=0, /* P2 */ |
| 85621 | pParse->cookieValue[iDb], /* P3 */ |
| 85622 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 85623 | ); |
| 85624 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 85625 | } |
| @@ -85671,11 +86215,11 @@ | |
| 85671 | } |
| 85672 | pParse->nTab = 0; |
| 85673 | pParse->nMem = 0; |
| 85674 | pParse->nSet = 0; |
| 85675 | pParse->nVar = 0; |
| 85676 | pParse->cookieMask = 0; |
| 85677 | } |
| 85678 | |
| 85679 | /* |
| 85680 | ** Run the parser and code generator recursively in order to generate |
| 85681 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | |
| 88153 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88154 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88155 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88156 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88157 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88158 | pKey->nField - pIndex->nKeyCol); VdbeCoverage(v); |
| 88159 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88160 | }else{ |
| 88161 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88162 | } |
| 88163 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | |
| 89298 | ** later, by sqlite3FinishCoding(). |
| 89299 | */ |
| 89300 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89301 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89302 | sqlite3 *db = pToplevel->db; |
| 89303 | yDbMask mask; |
| 89304 | |
| 89305 | assert( iDb>=0 && iDb<db->nDb ); |
| 89306 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89307 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89308 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89309 | mask = ((yDbMask)1)<<iDb; |
| 89310 | if( (pToplevel->cookieMask & mask)==0 ){ |
| 89311 | pToplevel->cookieMask |= mask; |
| 89312 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89313 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89314 | sqlite3OpenTempDatabase(pToplevel); |
| 89315 | } |
| 89316 | } |
| @@ -89345,11 +89887,11 @@ | |
| 89345 | ** necessary to undo a write and the checkpoint should not be set. |
| 89346 | */ |
| 89347 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89348 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89349 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89350 | pToplevel->writeMask |= ((yDbMask)1)<<iDb; |
| 89351 | pToplevel->isMultiWrite |= setStatement; |
| 89352 | } |
| 89353 | |
| 89354 | /* |
| 89355 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | |
| 98033 | ** Note that the values returned are one less that the values that |
| 98034 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98035 | ** to support legacy SQL code. The safety level used to be boolean |
| 98036 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98037 | */ |
| 98038 | static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ |
| 98039 | /* 123456789 123456789 */ |
| 98040 | static const char zText[] = "onoffalseyestruefull"; |
| 98041 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98042 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98043 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | |
| 98055 | } |
| 98056 | |
| 98057 | /* |
| 98058 | ** Interpret the given string as a boolean value. |
| 98059 | */ |
| 98060 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){ |
| 98061 | return getSafetyLevel(z,1,dflt)!=0; |
| 98062 | } |
| 98063 | |
| 98064 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98065 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | |
| 98601 | */ |
| 98602 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 98603 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 98604 | i64 iLimit = -2; |
| 98605 | if( zRight ){ |
| 98606 | sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 98607 | if( iLimit<-1 ) iLimit = -1; |
| 98608 | } |
| 98609 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 98610 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 98611 | break; |
| @@ -98729,11 +99271,11 @@ | |
| 98729 | sqlite3_int64 sz; |
| 98730 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 98731 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 98732 | if( zRight ){ |
| 98733 | int ii; |
| 98734 | sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 98735 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 98736 | if( pId2->n==0 ) db->szMmap = sz; |
| 98737 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 98738 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 98739 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | |
| 99772 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 99773 | ** use -1. |
| 99774 | */ |
| 99775 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 99776 | sqlite3_int64 N; |
| 99777 | if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ |
| 99778 | sqlite3_soft_heap_limit64(N); |
| 99779 | } |
| 99780 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 99781 | break; |
| 99782 | } |
| @@ -112245,11 +112787,12 @@ | |
| 112245 | int nEq = pLoop->u.btree.nEq; |
| 112246 | sqlite3 *db = pParse->db; |
| 112247 | int nLower = -1; |
| 112248 | int nUpper = p->nSample+1; |
| 112249 | int rc = SQLITE_OK; |
| 112250 | u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity; |
| 112251 | CollSeq *pColl; |
| 112252 | |
| 112253 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112254 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112255 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | |
| 113620 | int regRowid = 0; /* Register holding rowid */ |
| 113621 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 113622 | int iRetInit; /* Address of regReturn init */ |
| 113623 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 113624 | int ii; /* Loop counter */ |
| 113625 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 113626 | Table *pTab = pTabItem->pTab; |
| 113627 | |
| 113628 | pTerm = pLoop->aLTerm[0]; |
| 113629 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | |
| 113715 | |
| 113716 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 113717 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 113718 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 113719 | */ |
| 113720 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 113721 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 113722 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 113723 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113724 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | |
| 113727 | pAndExpr->pLeft = pOrExpr; |
| 113728 | pOrExpr = pAndExpr; |
| 113729 | } |
| 113730 | /* Loop through table entries that match term pOrTerm. */ |
| 113731 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 113732 | WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | |
| 113733 | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); |
| 113734 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 113735 | if( pSubWInfo ){ |
| 113736 | WhereLoop *pSubLoop; |
| 113737 | explainOneScan( |
| 113738 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | |
| 113819 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 113820 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 113821 | ){ |
| 113822 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 113823 | pCov = pSubLoop->u.btree.pIndex; |
| 113824 | }else{ |
| 113825 | pCov = 0; |
| 113826 | } |
| 113827 | |
| 113828 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | |
| 114425 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114426 | } |
| 114427 | } |
| 114428 | } |
| 114429 | |
| 114430 | /* |
| 114431 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114432 | ** index pIndex. Try to match one more. |
| 114433 | ** |
| 114434 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | |
| 114621 | testcase( eOp & WO_ISNULL ); |
| 114622 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 114623 | }else{ |
| 114624 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 114625 | } |
| 114626 | assert( rc!=SQLITE_OK || nOut>0 ); |
| 114627 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 114628 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 114629 | if( nOut ){ |
| 114630 | pNew->nOut = sqlite3LogEst(nOut); |
| 114631 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | |
| 114653 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 114654 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 114655 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 114656 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 114657 | } |
| 114658 | |
| 114659 | nOutUnadjusted = pNew->nOut; |
| 114660 | pNew->rRun += nInMul + nIn; |
| 114661 | pNew->nOut += nInMul + nIn; |
| 114662 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | |
| 114772 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 114773 | ** |
| 114774 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 114775 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 114776 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 114777 | */ |
| 114778 | static int whereLoopAddBtree( |
| 114779 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114780 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114781 | ){ |
| @@ -114859,10 +115423,11 @@ | |
| 114859 | pNew->aLTerm[0] = pTerm; |
| 114860 | /* TUNING: One-time cost for computing the automatic index is |
| 114861 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 114862 | ** the table being indexed. */ |
| 114863 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 114864 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 114865 | ** is more than the usual guess of 10 rows, since we have no way |
| 114866 | ** of knowning how selective the index will ultimately be. It would |
| 114867 | ** not be unreasonable to make this value much larger. */ |
| 114868 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | |
| 114900 | |
| 114901 | /* Full table scan */ |
| 114902 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114903 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 114904 | pNew->rRun = rSize + 16; |
| 114905 | whereLoopOutputAdjust(pWC, pNew); |
| 114906 | rc = whereLoopInsert(pBuilder, pNew); |
| 114907 | pNew->nOut = rSize; |
| 114908 | if( rc ) break; |
| 114909 | }else{ |
| @@ -114935,11 +115501,11 @@ | |
| 114935 | ** also add the cost of visiting table rows (N*3.0). */ |
| 114936 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114937 | if( m!=0 ){ |
| 114938 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 114939 | } |
| 114940 | |
| 114941 | whereLoopOutputAdjust(pWC, pNew); |
| 114942 | rc = whereLoopInsert(pBuilder, pNew); |
| 114943 | pNew->nOut = rSize; |
| 114944 | if( rc ) break; |
| 114945 | } |
| @@ -116410,10 +116976,11 @@ | |
| 116410 | } |
| 116411 | op = OP_OpenWrite; |
| 116412 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116413 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116414 | iIndexCur = iIdxCur; |
| 116415 | }else{ |
| 116416 | iIndexCur = pParse->nTab++; |
| 116417 | } |
| 116418 | pLevel->iIdxCur = iIndexCur; |
| 116419 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | |
| 120734 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 120735 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 120736 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 120737 | testcase( z[0]=='9' ); |
| 120738 | *tokenType = TK_INTEGER; |
| 120739 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 120740 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 120741 | if( z[i]=='.' ){ |
| 120742 | i++; |
| 120743 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | |
| 122410 | |
| 122411 | /* |
| 122412 | ** Return a static string containing the name corresponding to the error code |
| 122413 | ** specified in the argument. |
| 122414 | */ |
| 122415 | #if defined(SQLITE_TEST) |
| 122416 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122417 | const char *zName = 0; |
| 122418 | int i, origRc = rc; |
| 122419 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122420 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | |
| 123455 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 123456 | #endif |
| 123457 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 123458 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 123459 | #endif |
| 123460 | #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 |
| 123461 | # error SQLITE_MAX_ATTACHED must be between 0 and 62 |
| 123462 | #endif |
| 123463 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 123464 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 123465 | #endif |
| 123466 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | |
| 124715 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 124716 | #endif |
| 124717 | break; |
| 124718 | } |
| 124719 | |
| 124720 | } |
| 124721 | va_end(ap); |
| 124722 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 124723 | return rc; |
| 124724 | } |
| @@ -124763,11 +125346,11 @@ | |
| 124763 | const char *zParam, /* URI parameter sought */ |
| 124764 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 124765 | ){ |
| 124766 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 124767 | sqlite3_int64 v; |
| 124768 | if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ |
| 124769 | bDflt = v; |
| 124770 | } |
| 124771 | return bDflt; |
| 124772 | } |
| 124773 | |
| @@ -126294,11 +126877,11 @@ | |
| 126294 | |
| 126295 | /* fts3_tokenize_vtab.c */ |
| 126296 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126297 | |
| 126298 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126299 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 126300 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126301 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126302 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126303 | #endif |
| 126304 | |
| @@ -129764,11 +130347,11 @@ | |
| 129764 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 129765 | ** And so on. |
| 129766 | */ |
| 129767 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129768 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129769 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129770 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 129771 | #endif |
| 129772 | #ifdef SQLITE_ENABLE_ICU |
| 129773 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129774 | #endif |
| @@ -129782,20 +130365,20 @@ | |
| 129782 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 129783 | int rc = SQLITE_OK; |
| 129784 | Fts3Hash *pHash = 0; |
| 129785 | const sqlite3_tokenizer_module *pSimple = 0; |
| 129786 | const sqlite3_tokenizer_module *pPorter = 0; |
| 129787 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129788 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 129789 | #endif |
| 129790 | |
| 129791 | #ifdef SQLITE_ENABLE_ICU |
| 129792 | const sqlite3_tokenizer_module *pIcu = 0; |
| 129793 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 129794 | #endif |
| 129795 | |
| 129796 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129797 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 129798 | #endif |
| 129799 | |
| 129800 | #ifdef SQLITE_TEST |
| 129801 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | |
| 129819 | /* Load the built-in tokenizers into the hash table */ |
| 129820 | if( rc==SQLITE_OK ){ |
| 129821 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 129822 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 129823 | |
| 129824 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129825 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 129826 | #endif |
| 129827 | #ifdef SQLITE_ENABLE_ICU |
| 129828 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 129829 | #endif |
| @@ -143079,11 +143662,11 @@ | |
| 143079 | ****************************************************************************** |
| 143080 | ** |
| 143081 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143082 | */ |
| 143083 | |
| 143084 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 143085 | |
| 143086 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143087 | |
| 143088 | /* #include <assert.h> */ |
| 143089 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | |
| 143295 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143296 | pNew->bRemoveDiacritic = 1; |
| 143297 | |
| 143298 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143299 | const char *z = azArg[i]; |
| 143300 | int n = strlen(z); |
| 143301 | |
| 143302 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143303 | pNew->bRemoveDiacritic = 1; |
| 143304 | } |
| 143305 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | |
| 143427 | }while( unicodeIsAlnum(p, iCode) |
| 143428 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 143429 | ); |
| 143430 | |
| 143431 | /* Set the output variables and return. */ |
| 143432 | pCsr->iOff = (z - pCsr->aInput); |
| 143433 | *paToken = pCsr->zToken; |
| 143434 | *pnToken = zOut - pCsr->zToken; |
| 143435 | *piStart = (zStart - pCsr->aInput); |
| 143436 | *piEnd = (zEnd - pCsr->aInput); |
| 143437 | *piPos = pCsr->iToken++; |
| 143438 | return SQLITE_OK; |
| 143439 | } |
| 143440 | |
| 143441 | /* |
| @@ -143454,11 +144037,11 @@ | |
| 143454 | }; |
| 143455 | *ppModule = &module; |
| 143456 | } |
| 143457 | |
| 143458 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 143459 | #endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ |
| 143460 | |
| 143461 | /************** End of fts3_unicode.c ****************************************/ |
| 143462 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 143463 | /* |
| 143464 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | |
| 143475 | |
| 143476 | /* |
| 143477 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 143478 | */ |
| 143479 | |
| 143480 | #if defined(SQLITE_ENABLE_FTS4_UNICODE61) |
| 143481 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 143482 | |
| 143483 | /* #include <assert.h> */ |
| 143484 | |
| 143485 | /* |
| @@ -143822,11 +144405,11 @@ | |
| 143822 | } |
| 143823 | |
| 143824 | return ret; |
| 143825 | } |
| 143826 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 143827 | #endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ |
| 143828 | |
| 143829 | /************** End of fts3_unicode2.c ***************************************/ |
| 143830 | /************** Begin file rtree.c *******************************************/ |
| 143831 | /* |
| 143832 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | |
| 145359 | int rc = SQLITE_OK; |
| 145360 | int iCell = 0; |
| 145361 | |
| 145362 | rtreeReference(pRtree); |
| 145363 | |
| 145364 | freeCursorConstraints(pCsr); |
| 145365 | pCsr->iStrategy = idxNum; |
| 145366 | |
| 145367 | if( idxNum==1 ){ |
| 145368 | /* Special case - lookup by rowid. */ |
| 145369 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145370 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145371 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145372 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -2150,31 +2150,37 @@ | |
| 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | |
| 2152 | /* |
| 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | ** |
| 2155 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2156 | ** that might be invoked with argument P whenever |
| 2157 | ** an attempt is made to access a database table associated with |
| 2158 | ** [database connection] D when another thread |
| 2159 | ** or process has the table locked. |
| 2160 | ** The sqlite3_busy_handler() interface is used to implement |
| 2161 | ** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. |
| 2162 | ** |
| 2163 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2164 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2165 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2166 | ** |
| 2167 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2168 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2169 | ** the busy handler callback is the number of times that the busy handler has |
| 2170 | ** been invoked for the same locking event. ^If the |
| 2171 | ** busy callback returns 0, then no additional attempts are made to |
| 2172 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned |
| 2173 | ** to the application. |
| 2174 | ** ^If the callback returns non-zero, then another attempt |
| 2175 | ** is made to access the database and the cycle repeats. |
| 2176 | ** |
| 2177 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2178 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2179 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2180 | ** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the |
| 2181 | ** busy handler. |
| 2182 | ** Consider a scenario where one process is holding a read lock that |
| 2183 | ** it is trying to promote to a reserved lock and |
| 2184 | ** a second process is holding a reserved lock that it is trying |
| 2185 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2186 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | |
| 2208 | ** this is important. |
| 2209 | ** |
| 2210 | ** ^(There can only be a single busy handler defined for each |
| 2211 | ** [database connection]. Setting a new busy handler clears any |
| 2212 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2213 | ** or evaluating [PRAGMA busy_timeout=N] will change the |
| 2214 | ** busy handler and thus clear any previously set busy handler. |
| 2215 | ** |
| 2216 | ** The busy callback should not take any actions which modify the |
| 2217 | ** database connection that invoked the busy handler. In other words, |
| 2218 | ** the busy handler is not reentrant. Any such actions |
| 2219 | ** result in undefined behavior. |
| 2220 | ** |
| 2221 | ** A busy handler must not close the database connection |
| 2222 | ** or [prepared statement] that invoked the busy handler. |
| 2223 | */ |
| @@ -2230,10 +2238,12 @@ | |
| 2238 | ** |
| 2239 | ** ^(There can only be a single busy handler for a particular |
| 2240 | ** [database connection] any any given moment. If another busy handler |
| 2241 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2242 | ** this routine, that other busy handler is cleared.)^ |
| 2243 | ** |
| 2244 | ** See also: [PRAGMA busy_timeout] |
| 2245 | */ |
| 2246 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2247 | |
| 2248 | /* |
| 2249 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | |
| 4828 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4829 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4830 | ** will be placed in that directory.)^ ^If this variable |
| 4831 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4832 | ** temporary file directory. |
| 4833 | ** |
| 4834 | ** Applications are strongly discouraged from using this global variable. |
| 4835 | ** It is required to set a temporary folder on Windows Runtime (WinRT). |
| 4836 | ** But for all other platforms, it is highly recommended that applications |
| 4837 | ** neither read nor write this variable. This global variable is a relic |
| 4838 | ** that exists for backwards compatibility of legacy applications and should |
| 4839 | ** be avoided in new projects. |
| 4840 | ** |
| 4841 | ** It is not safe to read or modify this variable in more than one |
| 4842 | ** thread at a time. It is not safe to read or modify this variable |
| 4843 | ** if a [database connection] is being used at the same time in a separate |
| 4844 | ** thread. |
| @@ -4837,10 +4854,15 @@ | |
| 4854 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4855 | ** using [sqlite3_free]. |
| 4856 | ** Hence, if this variable is modified directly, either it should be |
| 4857 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4858 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4859 | ** Except when requested by the [temp_store_directory pragma], SQLite |
| 4860 | ** does not free the memory that sqlite3_temp_directory points to. If |
| 4861 | ** the application wants that memory to be freed, it must do |
| 4862 | ** so itself, taking care to only do so after all [database connection] |
| 4863 | ** objects have been destroyed. |
| 4864 | ** |
| 4865 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4866 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4867 | ** features that require the use of temporary files may fail. Here is an |
| 4868 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | |
| 5993 | ** <ul> |
| 5994 | ** <li> SQLITE_MUTEX_FAST |
| 5995 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5996 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5997 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5998 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 5999 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 6000 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 6001 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 6002 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 6003 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 6004 | ** </ul>)^ |
| 6005 | ** |
| 6006 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 6007 | ** cause sqlite3_mutex_alloc() to create |
| 6008 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | |
| 6202 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6203 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6204 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6205 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6206 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6207 | #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ |
| 6208 | #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ |
| 6209 | #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ |
| 6210 | |
| 6211 | /* |
| 6212 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6213 | ** |
| 6214 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | |
| 6300 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6301 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6302 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6303 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6304 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6305 | #define SQLITE_TESTCTRL_ISINIT 23 |
| 6306 | #define SQLITE_TESTCTRL_LAST 23 |
| 6307 | |
| 6308 | /* |
| 6309 | ** CAPI3REF: SQLite Runtime Status |
| 6310 | ** |
| 6311 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | |
| 7284 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7285 | ** configured by this function. |
| 7286 | ** |
| 7287 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7288 | ** from SQL. |
| 7289 | ** |
| 7290 | ** ^Checkpoints initiated by this mechanism are |
| 7291 | ** [sqlite3_wal_checkpoint_v2|PASSIVE]. |
| 7292 | ** |
| 7293 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7294 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7295 | ** pages. The use of this interface |
| 7296 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | |
| 7304 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7305 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7306 | ** empty string, then a checkpoint is run on all databases of |
| 7307 | ** connection D. ^If the database connection D is not in |
| 7308 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7309 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a |
| 7310 | ** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. |
| 7311 | ** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL |
| 7312 | ** or RESET checkpoint. |
| 7313 | ** |
| 7314 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7315 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7316 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7317 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | |
| 7330 | ** <dl> |
| 7331 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7332 | ** Checkpoint as many frames as possible without waiting for any database |
| 7333 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7334 | ** are checkpointed. This mode is the same as calling |
| 7335 | ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] |
| 7336 | ** is never invoked. |
| 7337 | ** |
| 7338 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7339 | ** This mode blocks (it invokes the |
| 7340 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7341 | ** database writer and all readers are reading from the most recent database |
| 7342 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7343 | ** database file. This call blocks database writers while it is running, |
| 7344 | ** but not database readers. |
| 7345 | ** |
| 7346 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7347 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7348 | ** checkpointing the log file it blocks (calls the |
| 7349 | ** [sqlite3_busy_handler|busy-handler callback]) |
| 7350 | ** until all readers are reading from the database file only. This ensures |
| 7351 | ** that the next client to write to the database file restarts the log file |
| 7352 | ** from the beginning. This call blocks database writers while it is running, |
| 7353 | ** but not database readers. |
| 7354 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | |
| 9323 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9324 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9325 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9326 | #define OP_ReadCookie 50 |
| 9327 | #define OP_SetCookie 51 |
| 9328 | #define OP_ReopenIdx 52 /* synopsis: root=P2 iDb=P3 */ |
| 9329 | #define OP_OpenRead 53 /* synopsis: root=P2 iDb=P3 */ |
| 9330 | #define OP_OpenWrite 54 /* synopsis: root=P2 iDb=P3 */ |
| 9331 | #define OP_OpenAutoindex 55 /* synopsis: nColumn=P2 */ |
| 9332 | #define OP_OpenEphemeral 56 /* synopsis: nColumn=P2 */ |
| 9333 | #define OP_SorterOpen 57 |
| 9334 | #define OP_OpenPseudo 58 /* synopsis: P3 columns in r[P2] */ |
| 9335 | #define OP_Close 59 |
| 9336 | #define OP_SeekLT 60 /* synopsis: key=r[P3@P4] */ |
| 9337 | #define OP_SeekLE 61 /* synopsis: key=r[P3@P4] */ |
| 9338 | #define OP_SeekGE 62 /* synopsis: key=r[P3@P4] */ |
| 9339 | #define OP_SeekGT 63 /* synopsis: key=r[P3@P4] */ |
| 9340 | #define OP_Seek 64 /* synopsis: intkey=r[P2] */ |
| 9341 | #define OP_NoConflict 65 /* synopsis: key=r[P3@P4] */ |
| 9342 | #define OP_NotFound 66 /* synopsis: key=r[P3@P4] */ |
| 9343 | #define OP_Found 67 /* synopsis: key=r[P3@P4] */ |
| 9344 | #define OP_NotExists 68 /* synopsis: intkey=r[P3] */ |
| 9345 | #define OP_Sequence 69 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9346 | #define OP_NewRowid 70 /* synopsis: r[P2]=rowid */ |
| 9347 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9348 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9349 | #define OP_Insert 73 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9350 | #define OP_InsertInt 74 /* synopsis: intkey=P3 data=r[P2] */ |
| 9351 | #define OP_Delete 75 |
| 9352 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9353 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9354 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9355 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9356 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9357 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9358 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9359 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9360 | #define OP_ResetCount 84 |
| 9361 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9362 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9363 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9364 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9365 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | |
| 9366 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9367 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9368 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9369 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9370 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9371 | #define OP_SorterCompare 95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 9372 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9373 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9374 | #define OP_SorterData 98 /* synopsis: r[P2]=data */ |
| 9375 | #define OP_RowKey 99 /* synopsis: r[P2]=key */ |
| 9376 | #define OP_RowData 100 /* synopsis: r[P2]=data */ |
| 9377 | #define OP_Rowid 101 /* synopsis: r[P2]=rowid */ |
| 9378 | #define OP_NullRow 102 |
| 9379 | #define OP_Last 103 |
| 9380 | #define OP_SorterSort 104 |
| 9381 | #define OP_Sort 105 |
| 9382 | #define OP_Rewind 106 |
| 9383 | #define OP_SorterInsert 107 |
| 9384 | #define OP_IdxInsert 108 /* synopsis: key=r[P2] */ |
| 9385 | #define OP_IdxDelete 109 /* synopsis: key=r[P2@P3] */ |
| 9386 | #define OP_IdxRowid 110 /* synopsis: r[P2]=rowid */ |
| 9387 | #define OP_IdxLE 111 /* synopsis: key=r[P3@P4] */ |
| 9388 | #define OP_IdxGT 112 /* synopsis: key=r[P3@P4] */ |
| 9389 | #define OP_IdxLT 113 /* synopsis: key=r[P3@P4] */ |
| 9390 | #define OP_IdxGE 114 /* synopsis: key=r[P3@P4] */ |
| 9391 | #define OP_Destroy 115 |
| 9392 | #define OP_Clear 116 |
| 9393 | #define OP_ResetSorter 117 |
| 9394 | #define OP_CreateIndex 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9395 | #define OP_CreateTable 119 /* synopsis: r[P2]=root iDb=P1 */ |
| 9396 | #define OP_ParseSchema 120 |
| 9397 | #define OP_LoadAnalysis 121 |
| 9398 | #define OP_DropTable 122 |
| 9399 | #define OP_DropIndex 123 |
| 9400 | #define OP_DropTrigger 124 |
| 9401 | #define OP_IntegrityCk 125 |
| 9402 | #define OP_RowSetAdd 126 /* synopsis: rowset(P1)=r[P2] */ |
| 9403 | #define OP_RowSetRead 127 /* synopsis: r[P3]=rowset(P1) */ |
| 9404 | #define OP_RowSetTest 128 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9405 | #define OP_Program 129 |
| 9406 | #define OP_Param 130 |
| 9407 | #define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9408 | #define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9410 | #define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9411 | #define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9412 | #define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ |
| 9413 | #define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9414 | #define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9415 | #define OP_IncrVacuum 139 |
| 9416 | #define OP_Expire 140 |
| 9417 | #define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9418 | #define OP_VBegin 142 |
| 9419 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9420 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9421 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9422 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9423 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9424 | #define OP_VCreate 148 |
| 9425 | #define OP_VDestroy 149 |
| 9426 | #define OP_VOpen 150 |
| 9427 | #define OP_VColumn 151 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9428 | #define OP_VNext 152 |
| 9429 | #define OP_VRename 153 |
| 9430 | #define OP_Pagecount 154 |
| 9431 | #define OP_MaxPgcnt 155 |
| 9432 | #define OP_Init 156 /* synopsis: Start at P2 */ |
| 9433 | #define OP_Noop 157 |
| 9434 | #define OP_Explain 158 |
| 9435 | |
| 9436 | |
| 9437 | /* Properties such as "out2" or "jump" that are specified in |
| 9438 | ** comments following the "case" for each opcode in the vdbe.c |
| 9439 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | |
| 9451 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9452 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9453 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9454 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9455 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9456 | /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\ |
| 9457 | /* 64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\ |
| 9458 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9459 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9460 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9461 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ |
| 9462 | /* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\ |
| 9463 | /* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\ |
| 9464 | /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ |
| 9465 | /* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\ |
| 9466 | /* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\ |
| 9467 | /* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\ |
| 9468 | /* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9469 | |
| 9470 | /************** End of opcodes.h *********************************************/ |
| 9471 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9472 | |
| 9473 | /* |
| @@ -10932,10 +10971,13 @@ | |
| 10971 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10972 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10973 | i16 nCol; /* Number of columns in this table */ |
| 10974 | u16 nRef; /* Number of pointers to this Table */ |
| 10975 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10976 | #ifdef SQLITE_ENABLE_COSTMULT |
| 10977 | LogEst costMult; /* Cost multiplier for using this table */ |
| 10978 | #endif |
| 10979 | u8 tabFlags; /* Mask of TF_* values */ |
| 10980 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10981 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10982 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10983 | #endif |
| @@ -11591,10 +11633,11 @@ | |
| 11633 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11634 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11635 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11636 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11637 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11638 | #define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ |
| 11639 | |
| 11640 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11641 | */ |
| 11642 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11643 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | |
| 11890 | |
| 11891 | /* |
| 11892 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11893 | */ |
| 11894 | #if SQLITE_MAX_ATTACHED>30 |
| 11895 | typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; |
| 11896 | # define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) |
| 11897 | # define DbMaskZero(M) memset((M),0,sizeof(M)) |
| 11898 | # define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) |
| 11899 | # define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) |
| 11900 | # define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) |
| 11901 | #else |
| 11902 | typedef unsigned int yDbMask; |
| 11903 | # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) |
| 11904 | # define DbMaskZero(M) (M)=0 |
| 11905 | # define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) |
| 11906 | # define DbMaskAllZero(M) (M)==0 |
| 11907 | # define DbMaskNonZero(M) (M)!=0 |
| 11908 | #endif |
| 11909 | |
| 11910 | /* |
| 11911 | ** An SQL parser context. A copy of this structure is passed through |
| 11912 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | |
| 12575 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12576 | #else |
| 12577 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12578 | #endif |
| 12579 | |
| 12580 | #if SQLITE_MAX_ATTACHED>30 |
| 12581 | SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); |
| 12582 | #endif |
| 12583 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12584 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12585 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12586 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12587 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | |
| 12828 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12829 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12830 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12831 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12832 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12833 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 12834 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12835 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12836 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12837 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12838 | |
| @@ -12801,11 +12858,11 @@ | |
| 12858 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12859 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12860 | #else |
| 12861 | # define sqlite3FileSuffix3(X,Y) |
| 12862 | #endif |
| 12863 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); |
| 12864 | |
| 12865 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12866 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12867 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12868 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | |
| 13933 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13934 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13935 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13936 | i16 nField; /* Number of fields in the header */ |
| 13937 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13938 | #ifdef SQLITE_DEBUG |
| 13939 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| 13940 | #endif |
| 13941 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13942 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13943 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13944 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13945 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13946 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13947 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13948 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13949 | Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 13950 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13951 | i64 seqCount; /* Sequence counter */ |
| 13952 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13953 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13954 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | |
| 18457 | /* |
| 18458 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18459 | */ |
| 18460 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18461 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18462 | if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; |
| 18463 | #endif |
| 18464 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18465 | } |
| 18466 | |
| 18467 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | |
| 18638 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18639 | ** mutex and returns a pointer to it. If it returns NULL |
| 18640 | ** that means that a mutex could not be allocated. |
| 18641 | */ |
| 18642 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18643 | static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1]; |
| 18644 | sqlite3_debug_mutex *pNew = 0; |
| 18645 | switch( id ){ |
| 18646 | case SQLITE_MUTEX_FAST: |
| 18647 | case SQLITE_MUTEX_RECURSIVE: { |
| 18648 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | |
| 18835 | ** <ul> |
| 18836 | ** <li> SQLITE_MUTEX_FAST |
| 18837 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18838 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18839 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18840 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 18841 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18842 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18843 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18844 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 18845 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 18846 | ** <li> SQLITE_MUTEX_STATIC_APP3 |
| 18847 | ** </ul> |
| 18848 | ** |
| 18849 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18850 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18851 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | |
| 18870 | ** mutex types, the same mutex is returned on every call that has |
| 18871 | ** the same type number. |
| 18872 | */ |
| 18873 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18874 | static sqlite3_mutex staticMutexes[] = { |
| 18875 | SQLITE3_MUTEX_INITIALIZER, |
| 18876 | SQLITE3_MUTEX_INITIALIZER, |
| 18877 | SQLITE3_MUTEX_INITIALIZER, |
| 18878 | SQLITE3_MUTEX_INITIALIZER, |
| 18879 | SQLITE3_MUTEX_INITIALIZER, |
| 18880 | SQLITE3_MUTEX_INITIALIZER, |
| 18881 | SQLITE3_MUTEX_INITIALIZER, |
| 18882 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | |
| 19108 | ** May you do good and not evil. |
| 19109 | ** May you find forgiveness for yourself and forgive others. |
| 19110 | ** May you share freely, never taking more than you give. |
| 19111 | ** |
| 19112 | ************************************************************************* |
| 19113 | ** This file contains the C functions that implement mutexes for Win32. |
| 19114 | */ |
| 19115 | |
| 19116 | #if SQLITE_OS_WIN |
| 19117 | /* |
| 19118 | ** Include code that is common to all os_*.c files |
| 19119 | */ |
| 19120 | /************** Include os_common.h in the middle of mutex_w32.c *************/ |
| 19121 | /************** Begin file os_common.h ***************************************/ |
| 19122 | /* |
| 19123 | ** 2004 May 22 |
| 19124 | ** |
| 19125 | ** The author disclaims copyright to this source code. In place of |
| 19126 | ** a legal notice, here is a blessing: |
| 19127 | ** |
| 19128 | ** May you do good and not evil. |
| 19129 | ** May you find forgiveness for yourself and forgive others. |
| 19130 | ** May you share freely, never taking more than you give. |
| 19131 | ** |
| 19132 | ****************************************************************************** |
| 19133 | ** |
| 19134 | ** This file contains macros and a little bit of code that is common to |
| 19135 | ** all of the platform-specific files (os_*.c) and is #included into those |
| 19136 | ** files. |
| 19137 | ** |
| 19138 | ** This file should be #included by the os_*.c files only. It is not a |
| 19139 | ** general purpose header file. |
| 19140 | */ |
| 19141 | #ifndef _OS_COMMON_H_ |
| 19142 | #define _OS_COMMON_H_ |
| 19143 | |
| 19144 | /* |
| 19145 | ** At least two bugs have slipped in because we changed the MEMORY_DEBUG |
| 19146 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the |
| 19147 | ** switch. The following code should catch this problem at compile-time. |
| 19148 | */ |
| 19149 | #ifdef MEMORY_DEBUG |
| 19150 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 19151 | #endif |
| 19152 | |
| 19153 | #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 19154 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 19155 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 19156 | # endif |
| 19157 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 19158 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| 19159 | #else |
| 19160 | # define OSTRACE(X) |
| 19161 | #endif |
| 19162 | |
| 19163 | /* |
| 19164 | ** Macros for performance tracing. Normally turned off. Only works |
| 19165 | ** on i486 hardware. |
| 19166 | */ |
| 19167 | #ifdef SQLITE_PERFORMANCE_TRACE |
| 19168 | |
| 19169 | /* |
| 19170 | ** hwtime.h contains inline assembler code for implementing |
| 19171 | ** high-performance timing routines. |
| 19172 | */ |
| 19173 | /************** Include hwtime.h in the middle of os_common.h ****************/ |
| 19174 | /************** Begin file hwtime.h ******************************************/ |
| 19175 | /* |
| 19176 | ** 2008 May 27 |
| 19177 | ** |
| 19178 | ** The author disclaims copyright to this source code. In place of |
| 19179 | ** a legal notice, here is a blessing: |
| 19180 | ** |
| 19181 | ** May you do good and not evil. |
| 19182 | ** May you find forgiveness for yourself and forgive others. |
| 19183 | ** May you share freely, never taking more than you give. |
| 19184 | ** |
| 19185 | ****************************************************************************** |
| 19186 | ** |
| 19187 | ** This file contains inline asm code for retrieving "high-performance" |
| 19188 | ** counters for x86 class CPUs. |
| 19189 | */ |
| 19190 | #ifndef _HWTIME_H_ |
| 19191 | #define _HWTIME_H_ |
| 19192 | |
| 19193 | /* |
| 19194 | ** The following routine only works on pentium-class (or newer) processors. |
| 19195 | ** It uses the RDTSC opcode to read the cycle count value out of the |
| 19196 | ** processor and returns that value. This can be used for high-res |
| 19197 | ** profiling. |
| 19198 | */ |
| 19199 | #if (defined(__GNUC__) || defined(_MSC_VER)) && \ |
| 19200 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) |
| 19201 | |
| 19202 | #if defined(__GNUC__) |
| 19203 | |
| 19204 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19205 | unsigned int lo, hi; |
| 19206 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); |
| 19207 | return (sqlite_uint64)hi << 32 | lo; |
| 19208 | } |
| 19209 | |
| 19210 | #elif defined(_MSC_VER) |
| 19211 | |
| 19212 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ |
| 19213 | __asm { |
| 19214 | rdtsc |
| 19215 | ret ; return value at EDX:EAX |
| 19216 | } |
| 19217 | } |
| 19218 | |
| 19219 | #endif |
| 19220 | |
| 19221 | #elif (defined(__GNUC__) && defined(__x86_64__)) |
| 19222 | |
| 19223 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19224 | unsigned long val; |
| 19225 | __asm__ __volatile__ ("rdtsc" : "=A" (val)); |
| 19226 | return val; |
| 19227 | } |
| 19228 | |
| 19229 | #elif (defined(__GNUC__) && defined(__ppc__)) |
| 19230 | |
| 19231 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19232 | unsigned long long retval; |
| 19233 | unsigned long junk; |
| 19234 | __asm__ __volatile__ ("\n\ |
| 19235 | 1: mftbu %1\n\ |
| 19236 | mftb %L0\n\ |
| 19237 | mftbu %0\n\ |
| 19238 | cmpw %0,%1\n\ |
| 19239 | bne 1b" |
| 19240 | : "=r" (retval), "=r" (junk)); |
| 19241 | return retval; |
| 19242 | } |
| 19243 | |
| 19244 | #else |
| 19245 | |
| 19246 | #error Need implementation of sqlite3Hwtime() for your platform. |
| 19247 | |
| 19248 | /* |
| 19249 | ** To compile without implementing sqlite3Hwtime() for your platform, |
| 19250 | ** you can remove the above #error and use the following |
| 19251 | ** stub function. You will lose timing support for many |
| 19252 | ** of the debugging and testing utilities, but it should at |
| 19253 | ** least compile and run. |
| 19254 | */ |
| 19255 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } |
| 19256 | |
| 19257 | #endif |
| 19258 | |
| 19259 | #endif /* !defined(_HWTIME_H_) */ |
| 19260 | |
| 19261 | /************** End of hwtime.h **********************************************/ |
| 19262 | /************** Continuing where we left off in os_common.h ******************/ |
| 19263 | |
| 19264 | static sqlite_uint64 g_start; |
| 19265 | static sqlite_uint64 g_elapsed; |
| 19266 | #define TIMER_START g_start=sqlite3Hwtime() |
| 19267 | #define TIMER_END g_elapsed=sqlite3Hwtime()-g_start |
| 19268 | #define TIMER_ELAPSED g_elapsed |
| 19269 | #else |
| 19270 | #define TIMER_START |
| 19271 | #define TIMER_END |
| 19272 | #define TIMER_ELAPSED ((sqlite_uint64)0) |
| 19273 | #endif |
| 19274 | |
| 19275 | /* |
| 19276 | ** If we compile with the SQLITE_TEST macro set, then the following block |
| 19277 | ** of code will give us the ability to simulate a disk I/O error. This |
| 19278 | ** is used for testing the I/O recovery logic. |
| 19279 | */ |
| 19280 | #ifdef SQLITE_TEST |
| 19281 | SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ |
| 19282 | SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ |
| 19283 | SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ |
| 19284 | SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ |
| 19285 | SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ |
| 19286 | SQLITE_API int sqlite3_diskfull_pending = 0; |
| 19287 | SQLITE_API int sqlite3_diskfull = 0; |
| 19288 | #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) |
| 19289 | #define SimulateIOError(CODE) \ |
| 19290 | if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ |
| 19291 | || sqlite3_io_error_pending-- == 1 ) \ |
| 19292 | { local_ioerr(); CODE; } |
| 19293 | static void local_ioerr(){ |
| 19294 | IOTRACE(("IOERR\n")); |
| 19295 | sqlite3_io_error_hit++; |
| 19296 | if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; |
| 19297 | } |
| 19298 | #define SimulateDiskfullError(CODE) \ |
| 19299 | if( sqlite3_diskfull_pending ){ \ |
| 19300 | if( sqlite3_diskfull_pending == 1 ){ \ |
| 19301 | local_ioerr(); \ |
| 19302 | sqlite3_diskfull = 1; \ |
| 19303 | sqlite3_io_error_hit = 1; \ |
| 19304 | CODE; \ |
| 19305 | }else{ \ |
| 19306 | sqlite3_diskfull_pending--; \ |
| 19307 | } \ |
| 19308 | } |
| 19309 | #else |
| 19310 | #define SimulateIOErrorBenign(X) |
| 19311 | #define SimulateIOError(A) |
| 19312 | #define SimulateDiskfullError(A) |
| 19313 | #endif |
| 19314 | |
| 19315 | /* |
| 19316 | ** When testing, keep a count of the number of open files. |
| 19317 | */ |
| 19318 | #ifdef SQLITE_TEST |
| 19319 | SQLITE_API int sqlite3_open_file_count = 0; |
| 19320 | #define OpenCounter(X) sqlite3_open_file_count+=(X) |
| 19321 | #else |
| 19322 | #define OpenCounter(X) |
| 19323 | #endif |
| 19324 | |
| 19325 | #endif /* !defined(_OS_COMMON_H_) */ |
| 19326 | |
| 19327 | /************** End of os_common.h *******************************************/ |
| 19328 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19329 | |
| 19330 | /* |
| 19331 | ** Include the header file for the Windows VFS. |
| 19332 | */ |
| 19333 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19334 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | |
| 19404 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19405 | #endif |
| 19406 | |
| 19407 | /* |
| 19408 | ** The code in this file is only used if we are compiling multithreaded |
| 19409 | ** on a Win32 system. |
| 19410 | */ |
| 19411 | #ifdef SQLITE_MUTEX_W32 |
| 19412 | |
| 19413 | /* |
| 19414 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | |
| 19417 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19418 | int id; /* Mutex type */ |
| 19419 | #ifdef SQLITE_DEBUG |
| 19420 | volatile int nRef; /* Number of enterances */ |
| 19421 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19422 | volatile int trace; /* True to trace changes */ |
| 19423 | #endif |
| 19424 | }; |
| 19425 | |
| 19426 | /* |
| 19427 | ** These are the initializer values used when declaring a "static" mutex |
| 19428 | ** on Win32. It should be noted that all mutexes require initialization |
| 19429 | ** on the Win32 platform. |
| 19430 | */ |
| 19431 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19432 | |
| 19433 | #ifdef SQLITE_DEBUG |
| 19434 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ |
| 19435 | 0L, (DWORD)0, 0 } |
| 19436 | #else |
| 19437 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19438 | #endif |
| 19439 | |
| 19440 | #ifdef SQLITE_DEBUG |
| 19441 | /* |
| 19442 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19443 | ** intended for use only inside assert() statements. |
| 19444 | */ |
| 19445 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19446 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19447 | } |
| 19448 | |
| 19449 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19450 | return p->nRef==0 || p->owner!=tid; |
| 19451 | } |
| 19452 | |
| 19453 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19454 | DWORD tid = GetCurrentThreadId(); |
| 19455 | return winMutexNotheld2(p, tid); |
| 19456 | } |
| 19457 | #endif |
| 19458 | |
| 19459 | /* |
| 19460 | ** Initialize and deinitialize the mutex subsystem. |
| 19461 | */ |
| 19462 | static sqlite3_mutex winMutex_staticMutexes[] = { |
| 19463 | SQLITE3_MUTEX_INITIALIZER, |
| 19464 | SQLITE3_MUTEX_INITIALIZER, |
| 19465 | SQLITE3_MUTEX_INITIALIZER, |
| 19466 | SQLITE3_MUTEX_INITIALIZER, |
| 19467 | SQLITE3_MUTEX_INITIALIZER, |
| 19468 | SQLITE3_MUTEX_INITIALIZER, |
| 19469 | SQLITE3_MUTEX_INITIALIZER, |
| 19470 | SQLITE3_MUTEX_INITIALIZER, |
| 19471 | SQLITE3_MUTEX_INITIALIZER |
| 19472 | }; |
| 19473 | |
| 19474 | static int winMutex_isInit = 0; |
| 19475 | static int winMutex_isNt = -1; /* <0 means "need to query" */ |
| 19476 | |
| 19477 | /* As the winMutexInit() and winMutexEnd() functions are called as part |
| 19478 | ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the |
| 19479 | ** "interlocked" magic used here is probably not strictly necessary. |
| 19480 | */ |
| 19481 | static LONG volatile winMutex_lock = 0; |
| 19482 | |
| 19483 | SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ |
| 19484 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19485 | |
| 19486 | static int winMutexInit(void){ |
| 19487 | /* The first to increment to 1 does actual initialization */ |
| 19488 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19489 | int i; |
| 19490 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19491 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | |
| 19494 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19495 | #endif |
| 19496 | } |
| 19497 | winMutex_isInit = 1; |
| 19498 | }else{ |
| 19499 | /* Another thread is (in the process of) initializing the static |
| 19500 | ** mutexes */ |
| 19501 | while( !winMutex_isInit ){ |
| 19502 | sqlite3_win32_sleep(1); |
| 19503 | } |
| 19504 | } |
| 19505 | return SQLITE_OK; |
| 19506 | } |
| 19507 | |
| 19508 | static int winMutexEnd(void){ |
| 19509 | /* The first to decrement to 0 does actual shutdown |
| 19510 | ** (which should be the last to shutdown.) */ |
| 19511 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19512 | if( winMutex_isInit==1 ){ |
| 19513 | int i; |
| 19514 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | |
| 19515 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19516 | } |
| 19517 | winMutex_isInit = 0; |
| 19518 | } |
| 19519 | } |
| 19520 | return SQLITE_OK; |
| 19521 | } |
| 19522 | |
| 19523 | /* |
| 19524 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19525 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | |
| 19530 | ** <ul> |
| 19531 | ** <li> SQLITE_MUTEX_FAST |
| 19532 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19533 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19534 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19535 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 19536 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19537 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19538 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19539 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 19540 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 19541 | ** <li> SQLITE_MUTEX_STATIC_APP3 |
| 19542 | ** </ul> |
| 19543 | ** |
| 19544 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19545 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19546 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | |
| 19559 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19560 | ** SQLITE_MUTEX_RECURSIVE. |
| 19561 | ** |
| 19562 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19563 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19564 | ** returns a different mutex on every call. But for the static |
| 19565 | ** mutex types, the same mutex is returned on every call that has |
| 19566 | ** the same type number. |
| 19567 | */ |
| 19568 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19569 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | |
| 19570 | |
| 19571 | switch( iType ){ |
| 19572 | case SQLITE_MUTEX_FAST: |
| 19573 | case SQLITE_MUTEX_RECURSIVE: { |
| 19574 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19575 | if( p ){ |
| 19576 | #ifdef SQLITE_DEBUG |
| 19577 | p->id = iType; |
| 19578 | #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC |
| 19579 | p->trace = 1; |
| 19580 | #endif |
| 19581 | #endif |
| 19582 | #if SQLITE_OS_WINRT |
| 19583 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19584 | #else |
| 19585 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | |
| 19586 | #endif |
| 19587 | } |
| 19588 | break; |
| 19589 | } |
| 19590 | default: { |
| 19591 | assert( iType-2 >= 0 ); |
| 19592 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19593 | assert( winMutex_isInit==1 ); |
| 19594 | p = &winMutex_staticMutexes[iType-2]; |
| 19595 | #ifdef SQLITE_DEBUG |
| 19596 | p->id = iType; |
| 19597 | #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC |
| 19598 | p->trace = 1; |
| 19599 | #endif |
| 19600 | #endif |
| 19601 | break; |
| 19602 | } |
| 19603 | } |
| 19604 | return p; |
| @@ -19339,12 +19610,15 @@ | |
| 19610 | ** allocated mutex. SQLite is careful to deallocate every |
| 19611 | ** mutex that it allocates. |
| 19612 | */ |
| 19613 | static void winMutexFree(sqlite3_mutex *p){ |
| 19614 | assert( p ); |
| 19615 | #ifdef SQLITE_DEBUG |
| 19616 | assert( p->nRef==0 && p->owner==0 ); |
| 19617 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19618 | #endif |
| 19619 | assert( winMutex_isInit==1 ); |
| 19620 | DeleteCriticalSection(&p->mutex); |
| 19621 | sqlite3_free(p); |
| 19622 | } |
| 19623 | |
| 19624 | /* |
| @@ -19357,53 +19631,71 @@ | |
| 19631 | ** mutex must be exited an equal number of times before another thread |
| 19632 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19633 | ** more than once, the behavior is undefined. |
| 19634 | */ |
| 19635 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19636 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19637 | DWORD tid = GetCurrentThreadId(); |
| 19638 | #endif |
| 19639 | #ifdef SQLITE_DEBUG |
| 19640 | assert( p ); |
| 19641 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19642 | #else |
| 19643 | assert( p ); |
| 19644 | #endif |
| 19645 | assert( winMutex_isInit==1 ); |
| 19646 | EnterCriticalSection(&p->mutex); |
| 19647 | #ifdef SQLITE_DEBUG |
| 19648 | assert( p->nRef>0 || p->owner==0 ); |
| 19649 | p->owner = tid; |
| 19650 | p->nRef++; |
| 19651 | if( p->trace ){ |
| 19652 | OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", |
| 19653 | tid, p, p->trace, p->nRef)); |
| 19654 | } |
| 19655 | #endif |
| 19656 | } |
| 19657 | |
| 19658 | static int winMutexTry(sqlite3_mutex *p){ |
| 19659 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19660 | DWORD tid = GetCurrentThreadId(); |
| 19661 | #endif |
| 19662 | int rc = SQLITE_BUSY; |
| 19663 | assert( p ); |
| 19664 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19665 | /* |
| 19666 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19667 | ** is used it is merely an optimization. So it is OK for it to always |
| 19668 | ** fail. |
| 19669 | ** |
| 19670 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19671 | ** And some windows compilers complain if you try to use it without |
| 19672 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19673 | ** For that reason, we will omit this optimization for now. See |
| 19674 | ** ticket #2685. |
| 19675 | */ |
| 19676 | #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 |
| 19677 | assert( winMutex_isInit==1 ); |
| 19678 | assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); |
| 19679 | if( winMutex_isNt<0 ){ |
| 19680 | winMutex_isNt = sqlite3_win32_is_nt(); |
| 19681 | } |
| 19682 | assert( winMutex_isNt==0 || winMutex_isNt==1 ); |
| 19683 | if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ |
| 19684 | #ifdef SQLITE_DEBUG |
| 19685 | p->owner = tid; |
| 19686 | p->nRef++; |
| 19687 | #endif |
| 19688 | rc = SQLITE_OK; |
| 19689 | } |
| 19690 | #else |
| 19691 | UNUSED_PARAMETER(p); |
| 19692 | #endif |
| 19693 | #ifdef SQLITE_DEBUG |
| 19694 | if( p->trace ){ |
| 19695 | OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", |
| 19696 | tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); |
| 19697 | } |
| 19698 | #endif |
| 19699 | return rc; |
| 19700 | } |
| 19701 | |
| @@ -19412,22 +19704,27 @@ | |
| 19704 | ** previously entered by the same thread. The behavior |
| 19705 | ** is undefined if the mutex is not currently entered or |
| 19706 | ** is not currently allocated. SQLite will never do either. |
| 19707 | */ |
| 19708 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19709 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19710 | DWORD tid = GetCurrentThreadId(); |
| 19711 | #endif |
| 19712 | assert( p ); |
| 19713 | #ifdef SQLITE_DEBUG |
| 19714 | assert( p->nRef>0 ); |
| 19715 | assert( p->owner==tid ); |
| 19716 | p->nRef--; |
| 19717 | if( p->nRef==0 ) p->owner = 0; |
| 19718 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19719 | #endif |
| 19720 | assert( winMutex_isInit==1 ); |
| 19721 | LeaveCriticalSection(&p->mutex); |
| 19722 | #ifdef SQLITE_DEBUG |
| 19723 | if( p->trace ){ |
| 19724 | OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", |
| 19725 | tid, p, p->trace, p->nRef)); |
| 19726 | } |
| 19727 | #endif |
| 19728 | } |
| 19729 | |
| 19730 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | |
| 19742 | #else |
| 19743 | 0, |
| 19744 | 0 |
| 19745 | #endif |
| 19746 | }; |
| 19747 | return &sMutex; |
| 19748 | } |
| 19749 | |
| 19750 | #endif /* SQLITE_MUTEX_W32 */ |
| 19751 | |
| 19752 | /************** End of mutex_w32.c *******************************************/ |
| 19753 | /************** Begin file malloc.c ******************************************/ |
| 19754 | /* |
| @@ -22422,13 +22719,13 @@ | |
| 22719 | testcase( c==(+1) ); |
| 22720 | } |
| 22721 | return c; |
| 22722 | } |
| 22723 | |
| 22724 | /* |
| 22725 | ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This |
| 22726 | ** routine does *not* accept hexadecimal notation. |
| 22727 | ** |
| 22728 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22729 | ** integer, then write that value into *pNum and return 0. |
| 22730 | ** |
| 22731 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | |
| 22808 | assert( u-1==LARGEST_INT64 ); |
| 22809 | return neg ? 0 : 2; |
| 22810 | } |
| 22811 | } |
| 22812 | } |
| 22813 | |
| 22814 | /* |
| 22815 | ** Transform a UTF-8 integer literal, in either decimal or hexadecimal, |
| 22816 | ** into a 64-bit signed integer. This routine accepts hexadecimal literals, |
| 22817 | ** whereas sqlite3Atoi64() does not. |
| 22818 | ** |
| 22819 | ** Returns: |
| 22820 | ** |
| 22821 | ** 0 Successful transformation. Fits in a 64-bit signed integer. |
| 22822 | ** 1 Integer too large for a 64-bit signed integer or is malformed |
| 22823 | ** 2 Special case of 9223372036854775808 |
| 22824 | */ |
| 22825 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ |
| 22826 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 22827 | if( z[0]=='0' |
| 22828 | && (z[1]=='x' || z[1]=='X') |
| 22829 | && sqlite3Isxdigit(z[2]) |
| 22830 | ){ |
| 22831 | u64 u = 0; |
| 22832 | int i, k; |
| 22833 | for(i=2; z[i]=='0'; i++){} |
| 22834 | for(k=i; sqlite3Isxdigit(z[k]); k++){ |
| 22835 | u = u*16 + sqlite3HexToInt(z[k]); |
| 22836 | } |
| 22837 | memcpy(pOut, &u, 8); |
| 22838 | return (z[k]==0 && k-i<=16) ? 0 : 1; |
| 22839 | }else |
| 22840 | #endif /* SQLITE_OMIT_HEX_INTEGER */ |
| 22841 | { |
| 22842 | return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); |
| 22843 | } |
| 22844 | } |
| 22845 | |
| 22846 | /* |
| 22847 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22848 | ** *pValue to that integer and return true. Otherwise return false. |
| 22849 | ** |
| 22850 | ** This routine accepts both decimal and hexadecimal notation for integers. |
| 22851 | ** |
| 22852 | ** Any non-numeric characters that following zNum are ignored. |
| 22853 | ** This is different from sqlite3Atoi64() which requires the |
| 22854 | ** input number to be zero-terminated. |
| 22855 | */ |
| @@ -22530,11 +22861,29 @@ | |
| 22861 | neg = 1; |
| 22862 | zNum++; |
| 22863 | }else if( zNum[0]=='+' ){ |
| 22864 | zNum++; |
| 22865 | } |
| 22866 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 22867 | else if( zNum[0]=='0' |
| 22868 | && (zNum[1]=='x' || zNum[1]=='X') |
| 22869 | && sqlite3Isxdigit(zNum[2]) |
| 22870 | ){ |
| 22871 | u32 u = 0; |
| 22872 | zNum += 2; |
| 22873 | while( zNum[0]=='0' ) zNum++; |
| 22874 | for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ |
| 22875 | u = u*16 + sqlite3HexToInt(zNum[i]); |
| 22876 | } |
| 22877 | if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ |
| 22878 | memcpy(pValue, &u, 4); |
| 22879 | return 1; |
| 22880 | }else{ |
| 22881 | return 0; |
| 22882 | } |
| 22883 | } |
| 22884 | #endif |
| 22885 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22886 | v = v*10 + c; |
| 22887 | } |
| 22888 | |
| 22889 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | |
| 23955 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23956 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23957 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23958 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23959 | /* 51 */ "SetCookie" OpHelp(""), |
| 23960 | /* 52 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 23961 | /* 53 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23962 | /* 54 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23963 | /* 55 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23964 | /* 56 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23965 | /* 57 */ "SorterOpen" OpHelp(""), |
| 23966 | /* 58 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 23967 | /* 59 */ "Close" OpHelp(""), |
| 23968 | /* 60 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 23969 | /* 61 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 23970 | /* 62 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 23971 | /* 63 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 23972 | /* 64 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23973 | /* 65 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23974 | /* 66 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23975 | /* 67 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23976 | /* 68 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23977 | /* 69 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23978 | /* 70 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23979 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23980 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23981 | /* 73 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23982 | /* 74 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23983 | /* 75 */ "Delete" OpHelp(""), |
| 23984 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23985 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23986 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23987 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23988 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23989 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23990 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23991 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23992 | /* 84 */ "ResetCount" OpHelp(""), |
| 23993 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23994 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23995 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23996 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23997 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | |
| 23998 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23999 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 24000 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 24001 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 24002 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 24003 | /* 95 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 24004 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 24005 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 24006 | /* 98 */ "SorterData" OpHelp("r[P2]=data"), |
| 24007 | /* 99 */ "RowKey" OpHelp("r[P2]=key"), |
| 24008 | /* 100 */ "RowData" OpHelp("r[P2]=data"), |
| 24009 | /* 101 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 24010 | /* 102 */ "NullRow" OpHelp(""), |
| 24011 | /* 103 */ "Last" OpHelp(""), |
| 24012 | /* 104 */ "SorterSort" OpHelp(""), |
| 24013 | /* 105 */ "Sort" OpHelp(""), |
| 24014 | /* 106 */ "Rewind" OpHelp(""), |
| 24015 | /* 107 */ "SorterInsert" OpHelp(""), |
| 24016 | /* 108 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 24017 | /* 109 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 24018 | /* 110 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 24019 | /* 111 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 24020 | /* 112 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 24021 | /* 113 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 24022 | /* 114 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 24023 | /* 115 */ "Destroy" OpHelp(""), |
| 24024 | /* 116 */ "Clear" OpHelp(""), |
| 24025 | /* 117 */ "ResetSorter" OpHelp(""), |
| 24026 | /* 118 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 24027 | /* 119 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 24028 | /* 120 */ "ParseSchema" OpHelp(""), |
| 24029 | /* 121 */ "LoadAnalysis" OpHelp(""), |
| 24030 | /* 122 */ "DropTable" OpHelp(""), |
| 24031 | /* 123 */ "DropIndex" OpHelp(""), |
| 24032 | /* 124 */ "DropTrigger" OpHelp(""), |
| 24033 | /* 125 */ "IntegrityCk" OpHelp(""), |
| 24034 | /* 126 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 24035 | /* 127 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 24036 | /* 128 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 24037 | /* 129 */ "Program" OpHelp(""), |
| 24038 | /* 130 */ "Param" OpHelp(""), |
| 24039 | /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24040 | /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24041 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24042 | /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24043 | /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24044 | /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 24045 | /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24046 | /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24047 | /* 139 */ "IncrVacuum" OpHelp(""), |
| 24048 | /* 140 */ "Expire" OpHelp(""), |
| 24049 | /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 24050 | /* 142 */ "VBegin" OpHelp(""), |
| 24051 | /* 143 */ "ToText" OpHelp(""), |
| 24052 | /* 144 */ "ToBlob" OpHelp(""), |
| 24053 | /* 145 */ "ToNumeric" OpHelp(""), |
| 24054 | /* 146 */ "ToInt" OpHelp(""), |
| 24055 | /* 147 */ "ToReal" OpHelp(""), |
| 24056 | /* 148 */ "VCreate" OpHelp(""), |
| 24057 | /* 149 */ "VDestroy" OpHelp(""), |
| 24058 | /* 150 */ "VOpen" OpHelp(""), |
| 24059 | /* 151 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 24060 | /* 152 */ "VNext" OpHelp(""), |
| 24061 | /* 153 */ "VRename" OpHelp(""), |
| 24062 | /* 154 */ "Pagecount" OpHelp(""), |
| 24063 | /* 155 */ "MaxPgcnt" OpHelp(""), |
| 24064 | /* 156 */ "Init" OpHelp("Start at P2"), |
| 24065 | /* 157 */ "Noop" OpHelp(""), |
| 24066 | /* 158 */ "Explain" OpHelp(""), |
| 24067 | }; |
| 24068 | return azName[i]; |
| 24069 | } |
| 24070 | #endif |
| 24071 | |
| @@ -32066,14 +32416,14 @@ | |
| 32416 | ** |
| 32417 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32418 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32419 | */ |
| 32420 | #ifdef SQLITE_TEST |
| 32421 | SQLITE_API LONG volatile sqlite3_os_type = 0; |
| 32422 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32423 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32424 | static LONG volatile sqlite3_os_type = 0; |
| 32425 | #endif |
| 32426 | |
| 32427 | #ifndef SYSCALL |
| 32428 | # define SYSCALL sqlite3_syscall_ptr |
| 32429 | #endif |
| @@ -32699,10 +33049,15 @@ | |
| 33049 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 33050 | #endif |
| 33051 | |
| 33052 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 33053 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 33054 | |
| 33055 | { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, |
| 33056 | |
| 33057 | #define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \ |
| 33058 | LONG,LONG))aSyscall[76].pCurrent) |
| 33059 | |
| 33060 | }; /* End of the overrideable system calls */ |
| 33061 | |
| 33062 | /* |
| 33063 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | |
| 33305 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 33306 | # define osIsNT() (1) |
| 33307 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 33308 | # define osIsNT() (0) |
| 33309 | #else |
| 33310 | # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) |
| 33311 | #endif |
| 33312 | |
| 33313 | /* |
| 33314 | ** This function determines if the machine is running a version of Windows |
| 33315 | ** based on the NT kernel. |
| 33316 | */ |
| 33317 | SQLITE_API int sqlite3_win32_is_nt(void){ |
| 33318 | if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ |
| 33319 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 33320 | OSVERSIONINFOW sInfo; |
| 33321 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 33322 | osGetVersionExW(&sInfo); |
| 33323 | #else |
| 33324 | OSVERSIONINFOA sInfo; |
| 33325 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 33326 | osGetVersionExA(&sInfo); |
| 33327 | #endif |
| 33328 | osInterlockedCompareExchange(&sqlite3_os_type, |
| 33329 | (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); |
| 33330 | } |
| 33331 | return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; |
| 33332 | } |
| 33333 | |
| 33334 | #ifdef SQLITE_WIN32_MALLOC |
| 33335 | /* |
| 33336 | ** Allocate nBytes of memory. |
| 33337 | */ |
| @@ -37121,11 +37483,11 @@ | |
| 37483 | }; |
| 37484 | #endif |
| 37485 | |
| 37486 | /* Double-check that the aSyscall[] array has been constructed |
| 37487 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37488 | assert( ArraySize(aSyscall)==77 ); |
| 37489 | |
| 37490 | /* get memory map allocation granularity */ |
| 37491 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37492 | #if SQLITE_OS_WINRT |
| 37493 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | |
| 53175 | return pBt->nPage; |
| 53176 | } |
| 53177 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 53178 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 53179 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 53180 | return btreePagecount(p->pBt); |
| 53181 | } |
| 53182 | |
| 53183 | /* |
| 53184 | ** Get a page from the pager and initialize it. This routine is just a |
| 53185 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | |
| 62716 | } |
| 62717 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62718 | pParse->aLabel = 0; |
| 62719 | pParse->nLabel = 0; |
| 62720 | *pMaxFuncArgs = nMaxArgs; |
| 62721 | assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); |
| 62722 | } |
| 62723 | |
| 62724 | /* |
| 62725 | ** Return the address of the next instruction to be inserted. |
| 62726 | */ |
| @@ -62381,11 +62743,11 @@ | |
| 62743 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62744 | VdbeOp *aOp = p->aOp; |
| 62745 | assert( aOp && !p->db->mallocFailed ); |
| 62746 | |
| 62747 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62748 | assert( DbMaskAllZero(p->btreeMask) ); |
| 62749 | |
| 62750 | resolveP2Values(p, pnMaxArg); |
| 62751 | *pnOp = p->nOp; |
| 62752 | p->aOp = 0; |
| 62753 | return aOp; |
| @@ -62966,13 +63328,13 @@ | |
| 63328 | ** p->btreeMask of databases that will require a lock. |
| 63329 | */ |
| 63330 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 63331 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 63332 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 63333 | DbMaskSet(p->btreeMask, i); |
| 63334 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 63335 | DbMaskSet(p->lockMask, i); |
| 63336 | } |
| 63337 | } |
| 63338 | |
| 63339 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 63340 | /* |
| @@ -62996,20 +63358,19 @@ | |
| 63358 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 63359 | ** be a problem. |
| 63360 | */ |
| 63361 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63362 | int i; |
| 63363 | sqlite3 *db; |
| 63364 | Db *aDb; |
| 63365 | int nDb; |
| 63366 | if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ |
| 63367 | db = p->db; |
| 63368 | aDb = db->aDb; |
| 63369 | nDb = db->nDb; |
| 63370 | for(i=0; i<nDb; i++){ |
| 63371 | if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ |
| 63372 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63373 | } |
| 63374 | } |
| 63375 | } |
| 63376 | #endif |
| @@ -63018,20 +63379,19 @@ | |
| 63379 | /* |
| 63380 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63381 | */ |
| 63382 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63383 | int i; |
| 63384 | sqlite3 *db; |
| 63385 | Db *aDb; |
| 63386 | int nDb; |
| 63387 | if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ |
| 63388 | db = p->db; |
| 63389 | aDb = db->aDb; |
| 63390 | nDb = db->nDb; |
| 63391 | for(i=0; i<nDb; i++){ |
| 63392 | if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ |
| 63393 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63394 | } |
| 63395 | } |
| 63396 | } |
| 63397 | #endif |
| @@ -63998,11 +64358,11 @@ | |
| 64358 | int cnt = 0; |
| 64359 | int nWrite = 0; |
| 64360 | int nRead = 0; |
| 64361 | p = db->pVdbe; |
| 64362 | while( p ){ |
| 64363 | if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ |
| 64364 | cnt++; |
| 64365 | if( p->readOnly==0 ) nWrite++; |
| 64366 | if( p->bIsReader ) nRead++; |
| 64367 | } |
| 64368 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | |
| 65003 | /* |
| 65004 | ** Return the serial-type for the value stored in pMem. |
| 65005 | */ |
| 65006 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 65007 | int flags = pMem->flags; |
| 65008 | u32 n; |
| 65009 | |
| 65010 | if( flags&MEM_Null ){ |
| 65011 | return 0; |
| 65012 | } |
| 65013 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | |
| 65033 | } |
| 65034 | if( flags&MEM_Real ){ |
| 65035 | return 7; |
| 65036 | } |
| 65037 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 65038 | assert( pMem->n>=0 ); |
| 65039 | n = (u32)pMem->n; |
| 65040 | if( flags & MEM_Zero ){ |
| 65041 | n += pMem->u.nZero; |
| 65042 | } |
| 65043 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 65044 | } |
| 65045 | |
| 65046 | /* |
| 65047 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | |
| 67555 | /* |
| 67556 | ** Return true if the prepared statement is in need of being reset. |
| 67557 | */ |
| 67558 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67559 | Vdbe *v = (Vdbe*)pStmt; |
| 67560 | return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; |
| 67561 | } |
| 67562 | |
| 67563 | /* |
| 67564 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67565 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | |
| 68113 | ** do so without loss of information. In other words, if the string |
| 68114 | ** looks like a number, convert it into a number. If it does not |
| 68115 | ** look like a number, leave it alone. |
| 68116 | */ |
| 68117 | static void applyNumericAffinity(Mem *pRec){ |
| 68118 | double rValue; |
| 68119 | i64 iValue; |
| 68120 | u8 enc = pRec->enc; |
| 68121 | if( (pRec->flags&MEM_Str)==0 ) return; |
| 68122 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; |
| 68123 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ |
| 68124 | pRec->u.i = iValue; |
| 68125 | pRec->flags |= MEM_Int; |
| 68126 | }else{ |
| 68127 | pRec->r = rValue; |
| 68128 | pRec->flags |= MEM_Real; |
| 68129 | } |
| 68130 | } |
| 68131 | #define ApplyNumericAffinity(X) \ |
| 68132 | if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} |
| 68133 | |
| 68134 | /* |
| 68135 | ** Processing is determine by the affinity parameter: |
| 68136 | ** |
| 68137 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | |
| 68164 | } |
| 68165 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 68166 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 68167 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 68168 | || affinity==SQLITE_AFF_NUMERIC ); |
| 68169 | ApplyNumericAffinity(pRec); |
| 68170 | if( pRec->flags & MEM_Real ){ |
| 68171 | sqlite3VdbeIntegerAffinity(pRec); |
| 68172 | } |
| 68173 | } |
| 68174 | } |
| @@ -68385,16 +68745,18 @@ | |
| 68745 | break; |
| 68746 | } |
| 68747 | |
| 68748 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68749 | ** |
| 68750 | ** Set up register P1 so that it will Yield to the coroutine |
| 68751 | ** located at address P3. |
| 68752 | ** |
| 68753 | ** If P2!=0 then the coroutine implementation immediately follows |
| 68754 | ** this opcode. So jump over the coroutine implementation to |
| 68755 | ** address P2. |
| 68756 | ** |
| 68757 | ** See also: EndCoroutine |
| 68758 | */ |
| 68759 | case OP_InitCoroutine: { /* jump */ |
| 68760 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68761 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68762 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | |
| 68768 | break; |
| 68769 | } |
| 68770 | |
| 68771 | /* Opcode: EndCoroutine P1 * * * * |
| 68772 | ** |
| 68773 | ** The instruction at the address in register P1 is an Yield. |
| 68774 | ** Jump to the P2 parameter of that Yield. |
| 68775 | ** After the jump, register P1 becomes undefined. |
| 68776 | ** |
| 68777 | ** See also: InitCoroutine |
| 68778 | */ |
| 68779 | case OP_EndCoroutine: { /* in1 */ |
| 68780 | VdbeOp *pCaller; |
| 68781 | pIn1 = &aMem[pOp->p1]; |
| 68782 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | |
| 68789 | break; |
| 68790 | } |
| 68791 | |
| 68792 | /* Opcode: Yield P1 P2 * * * |
| 68793 | ** |
| 68794 | ** Swap the program counter with the value in register P1. This |
| 68795 | ** has the effect of yielding to a coroutine. |
| 68796 | ** |
| 68797 | ** If the coroutine that is launched by this instruction ends with |
| 68798 | ** Yield or Return then continue to the next instruction. But if |
| 68799 | ** the coroutine launched by this instruction ends with |
| 68800 | ** EndCoroutine, then jump to P2 rather than continuing with the |
| 68801 | ** next instruction. |
| 68802 | ** |
| 68803 | ** See also: InitCoroutine |
| 68804 | */ |
| 68805 | case OP_Yield: { /* in1, jump */ |
| 68806 | int pcDest; |
| 68807 | pIn1 = &aMem[pOp->p1]; |
| 68808 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | |
| 70183 | break; |
| 70184 | } |
| 70185 | |
| 70186 | /* Opcode: Once P1 P2 * * * |
| 70187 | ** |
| 70188 | ** Check the "once" flag number P1. If it is set, jump to instruction P2. |
| 70189 | ** Otherwise, set the flag and fall through to the next instruction. |
| 70190 | ** In other words, this opcode causes all following opcodes up through P2 |
| 70191 | ** (but not including P2) to run just once and to be skipped on subsequent |
| 70192 | ** times through the loop. |
| 70193 | ** |
| 70194 | ** All "once" flags are initially cleared whenever a prepared statement |
| 70195 | ** first begins to run. |
| 70196 | */ |
| 70197 | case OP_Once: { /* jump */ |
| 70198 | assert( pOp->p1<p->nOnceFlag ); |
| 70199 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 70200 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | |
| 71025 | int iGen; |
| 71026 | |
| 71027 | assert( p->bIsReader ); |
| 71028 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 71029 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 71030 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 71031 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 71032 | rc = SQLITE_READONLY; |
| 71033 | goto abort_due_to_error; |
| 71034 | } |
| 71035 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | |
| 71120 | iDb = pOp->p1; |
| 71121 | iCookie = pOp->p3; |
| 71122 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 71123 | assert( iDb>=0 && iDb<db->nDb ); |
| 71124 | assert( db->aDb[iDb].pBt!=0 ); |
| 71125 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 71126 | |
| 71127 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 71128 | pOut->u.i = iMeta; |
| 71129 | break; |
| 71130 | } |
| @@ -70768,11 +71141,11 @@ | |
| 71141 | */ |
| 71142 | case OP_SetCookie: { /* in3 */ |
| 71143 | Db *pDb; |
| 71144 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 71145 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 71146 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 71147 | assert( p->readOnly==0 ); |
| 71148 | pDb = &db->aDb[pOp->p1]; |
| 71149 | assert( pDb->pBt!=0 ); |
| 71150 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 71151 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | |
| 71196 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 71197 | ** structure, then said structure defines the content and collating |
| 71198 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 71199 | ** value, it is set to the number of columns in the table. |
| 71200 | ** |
| 71201 | ** See also: OpenWrite, ReopenIdx |
| 71202 | */ |
| 71203 | /* Opcode: ReopenIdx P1 P2 P3 P4 P5 |
| 71204 | ** Synopsis: root=P2 iDb=P3 |
| 71205 | ** |
| 71206 | ** The ReopenIdx opcode works exactly like ReadOpen except that it first |
| 71207 | ** checks to see if the cursor on P1 is already open with a root page |
| 71208 | ** number of P2 and if it is this opcode becomes a no-op. In other words, |
| 71209 | ** if the cursor is already open, do not reopen it. |
| 71210 | ** |
| 71211 | ** The ReopenIdx opcode may only be used with P5==0 and with P4 being |
| 71212 | ** a P4_KEYINFO object. Furthermore, the P3 value must be the same as |
| 71213 | ** every other ReopenIdx or OpenRead for the same cursor number. |
| 71214 | ** |
| 71215 | ** See the OpenRead opcode documentation for additional information. |
| 71216 | */ |
| 71217 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 71218 | ** Synopsis: root=P2 iDb=P3 |
| 71219 | ** |
| 71220 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | |
| 71232 | ** in read/write mode. For a given table, there can be one or more read-only |
| 71233 | ** cursors or a single read/write cursor but not both. |
| 71234 | ** |
| 71235 | ** See also OpenRead. |
| 71236 | */ |
| 71237 | case OP_ReopenIdx: { |
| 71238 | VdbeCursor *pCur; |
| 71239 | |
| 71240 | assert( pOp->p5==0 ); |
| 71241 | assert( pOp->p4type==P4_KEYINFO ); |
| 71242 | pCur = p->apCsr[pOp->p1]; |
| 71243 | if( pCur && pCur->pgnoRoot==pOp->p2 ){ |
| 71244 | assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ |
| 71245 | break; |
| 71246 | } |
| 71247 | /* If the cursor is not currently open or is open on a different |
| 71248 | ** index, then fall through into OP_OpenRead to force a reopen */ |
| 71249 | } |
| 71250 | case OP_OpenRead: |
| 71251 | case OP_OpenWrite: { |
| 71252 | int nField; |
| 71253 | KeyInfo *pKeyInfo; |
| 71254 | int p2; |
| @@ -70859,11 +71259,12 @@ | |
| 71259 | Db *pDb; |
| 71260 | |
| 71261 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 71262 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 71263 | assert( p->bIsReader ); |
| 71264 | assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx |
| 71265 | || p->readOnly==0 ); |
| 71266 | |
| 71267 | if( p->expired ){ |
| 71268 | rc = SQLITE_ABORT; |
| 71269 | break; |
| 71270 | } |
| @@ -70871,11 +71272,11 @@ | |
| 71272 | nField = 0; |
| 71273 | pKeyInfo = 0; |
| 71274 | p2 = pOp->p2; |
| 71275 | iDb = pOp->p3; |
| 71276 | assert( iDb>=0 && iDb<db->nDb ); |
| 71277 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 71278 | pDb = &db->aDb[iDb]; |
| 71279 | pX = pDb->pBt; |
| 71280 | assert( pX!=0 ); |
| 71281 | if( pOp->opcode==OP_OpenWrite ){ |
| 71282 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | |
| 71317 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 71318 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 71319 | if( pCur==0 ) goto no_mem; |
| 71320 | pCur->nullRow = 1; |
| 71321 | pCur->isOrdered = 1; |
| 71322 | pCur->pgnoRoot = p2; |
| 71323 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 71324 | pCur->pKeyInfo = pKeyInfo; |
| 71325 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 71326 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 71327 | |
| @@ -71070,11 +71472,11 @@ | |
| 71472 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71473 | p->apCsr[pOp->p1] = 0; |
| 71474 | break; |
| 71475 | } |
| 71476 | |
| 71477 | /* Opcode: SeekGE P1 P2 P3 P4 * |
| 71478 | ** Synopsis: key=r[P3@P4] |
| 71479 | ** |
| 71480 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71481 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71482 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | |
| 71483 | ** that are used as an unpacked index key. |
| 71484 | ** |
| 71485 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71486 | ** is greater than or equal to the key value. If there are no records |
| 71487 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71488 | ** |
| 71489 | ** This opcode leaves the cursor configured to move in forward order, |
| 71490 | ** from the begining toward the end. In other words, the cursor is |
| 71491 | ** configured to use Next, not Prev. |
| 71492 | ** |
| 71493 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71494 | */ |
| 71495 | /* Opcode: SeekGT P1 P2 P3 P4 * |
| 71496 | ** Synopsis: key=r[P3@P4] |
| 71497 | ** |
| 71498 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71499 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71500 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | |
| 71501 | ** that are used as an unpacked index key. |
| 71502 | ** |
| 71503 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71504 | ** is greater than the key value. If there are no records greater than |
| 71505 | ** the key and P2 is not zero, then jump to P2. |
| 71506 | ** |
| 71507 | ** This opcode leaves the cursor configured to move in forward order, |
| 71508 | ** from the begining toward the end. In other words, the cursor is |
| 71509 | ** configured to use Next, not Prev. |
| 71510 | ** |
| 71511 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71512 | */ |
| 71513 | /* Opcode: SeekLT P1 P2 P3 P4 * |
| 71514 | ** Synopsis: key=r[P3@P4] |
| 71515 | ** |
| 71516 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71517 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71518 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | |
| 71519 | ** that are used as an unpacked index key. |
| 71520 | ** |
| 71521 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71522 | ** is less than the key value. If there are no records less than |
| 71523 | ** the key and P2 is not zero, then jump to P2. |
| 71524 | ** |
| 71525 | ** This opcode leaves the cursor configured to move in reverse order, |
| 71526 | ** from the end toward the beginning. In other words, the cursor is |
| 71527 | ** configured to use Prev, not Next. |
| 71528 | ** |
| 71529 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71530 | */ |
| 71531 | /* Opcode: SeekLE P1 P2 P3 P4 * |
| 71532 | ** Synopsis: key=r[P3@P4] |
| 71533 | ** |
| 71534 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71535 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71536 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | |
| 71537 | ** that are used as an unpacked index key. |
| 71538 | ** |
| 71539 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71540 | ** is less than or equal to the key value. If there are no records |
| 71541 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71542 | ** |
| 71543 | ** This opcode leaves the cursor configured to move in reverse order, |
| 71544 | ** from the end toward the beginning. In other words, the cursor is |
| 71545 | ** configured to use Prev, not Next. |
| 71546 | ** |
| 71547 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71548 | */ |
| 71549 | case OP_SeekLT: /* jump, in3 */ |
| 71550 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | |
| 71567 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71568 | assert( pC->isOrdered ); |
| 71569 | assert( pC->pCursor!=0 ); |
| 71570 | oc = pOp->opcode; |
| 71571 | pC->nullRow = 0; |
| 71572 | #ifdef SQLITE_DEBUG |
| 71573 | pC->seekOp = pOp->opcode; |
| 71574 | #endif |
| 71575 | if( pC->isTable ){ |
| 71576 | /* The input value in P3 might be of any type: integer, real, string, |
| 71577 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71578 | ** the seek, so covert it. */ |
| 71579 | pIn3 = &aMem[pOp->p3]; |
| 71580 | ApplyNumericAffinity(pIn3); |
| 71581 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71582 | pC->rowidIsValid = 0; |
| 71583 | |
| 71584 | /* If the P3 value could not be converted into an integer without |
| 71585 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | |
| 71724 | ** record. |
| 71725 | ** |
| 71726 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71727 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71728 | ** P1 is left pointing at the matching entry. |
| 71729 | ** |
| 71730 | ** This operation leaves the cursor in a state where it cannot be |
| 71731 | ** advanced in either direction. In other words, the Next and Prev |
| 71732 | ** opcodes do not work after this operation. |
| 71733 | ** |
| 71734 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71735 | */ |
| 71736 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71737 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | |
| 71743 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71744 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71745 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71746 | ** falls through to the next instruction and P1 is left pointing at the |
| 71747 | ** matching entry. |
| 71748 | ** |
| 71749 | ** This operation leaves the cursor in a state where it cannot be |
| 71750 | ** advanced in either direction. In other words, the Next and Prev |
| 71751 | ** opcodes do not work after this operation. |
| 71752 | ** |
| 71753 | ** See also: Found, NotExists, NoConflict |
| 71754 | */ |
| 71755 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71756 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | |
| 71766 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71767 | ** cursor pointing to the matching row. |
| 71768 | ** |
| 71769 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71770 | ** branch is always taken if any part of the search key input is NULL. |
| 71771 | ** |
| 71772 | ** This operation leaves the cursor in a state where it cannot be |
| 71773 | ** advanced in either direction. In other words, the Next and Prev |
| 71774 | ** opcodes do not work after this operation. |
| 71775 | ** |
| 71776 | ** See also: NotFound, Found, NotExists |
| 71777 | */ |
| 71778 | case OP_NoConflict: /* jump, in3 */ |
| 71779 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | |
| 71793 | |
| 71794 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71795 | assert( pOp->p4type==P4_INT32 ); |
| 71796 | pC = p->apCsr[pOp->p1]; |
| 71797 | assert( pC!=0 ); |
| 71798 | #ifdef SQLITE_DEBUG |
| 71799 | pC->seekOp = 0; |
| 71800 | #endif |
| 71801 | pIn3 = &aMem[pOp->p3]; |
| 71802 | assert( pC->pCursor!=0 ); |
| 71803 | assert( pC->isTable==0 ); |
| 71804 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71805 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | |
| 71866 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71867 | ** through to the next instruction. |
| 71868 | ** |
| 71869 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71870 | ** (with arbitrary multi-value keys). |
| 71871 | ** |
| 71872 | ** This opcode leaves the cursor in a state where it cannot be advanced |
| 71873 | ** in either direction. In other words, the Next and Prev opcodes will |
| 71874 | ** not work following this opcode. |
| 71875 | ** |
| 71876 | ** See also: Found, NotFound, NoConflict |
| 71877 | */ |
| 71878 | case OP_NotExists: { /* jump, in3 */ |
| 71879 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | |
| 71884 | pIn3 = &aMem[pOp->p3]; |
| 71885 | assert( pIn3->flags & MEM_Int ); |
| 71886 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71887 | pC = p->apCsr[pOp->p1]; |
| 71888 | assert( pC!=0 ); |
| 71889 | #ifdef SQLITE_DEBUG |
| 71890 | pC->seekOp = 0; |
| 71891 | #endif |
| 71892 | assert( pC->isTable ); |
| 71893 | assert( pC->pseudoTableReg==0 ); |
| 71894 | pCrsr = pC->pCursor; |
| 71895 | assert( pCrsr!=0 ); |
| 71896 | res = 0; |
| @@ -71806,16 +72249,16 @@ | |
| 72249 | p->nChange = 0; |
| 72250 | break; |
| 72251 | } |
| 72252 | |
| 72253 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 72254 | ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 |
| 72255 | ** |
| 72256 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 72257 | ** the record blob in register P3 against a prefix of the entry that |
| 72258 | ** the sorter cursor currently points to. Only the first P4 fields |
| 72259 | ** of r[P3] and the sorter record are compared. |
| 72260 | ** |
| 72261 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 72262 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 72263 | ** the comparison is assumed to be equal. |
| 72264 | ** |
| @@ -71823,18 +72266,18 @@ | |
| 72266 | ** each other. Jump to P2 if they are different. |
| 72267 | */ |
| 72268 | case OP_SorterCompare: { |
| 72269 | VdbeCursor *pC; |
| 72270 | int res; |
| 72271 | int nKeyCol; |
| 72272 | |
| 72273 | pC = p->apCsr[pOp->p1]; |
| 72274 | assert( isSorter(pC) ); |
| 72275 | assert( pOp->p4type==P4_INT32 ); |
| 72276 | pIn3 = &aMem[pOp->p3]; |
| 72277 | nKeyCol = pOp->p4.i; |
| 72278 | rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); |
| 72279 | VdbeBranchTaken(res!=0,2); |
| 72280 | if( res ){ |
| 72281 | pc = pOp->p2-1; |
| 72282 | } |
| 72283 | break; |
| @@ -72010,15 +72453,19 @@ | |
| 72453 | break; |
| 72454 | } |
| 72455 | |
| 72456 | /* Opcode: Last P1 P2 * * * |
| 72457 | ** |
| 72458 | ** The next use of the Rowid or Column or Prev instruction for P1 |
| 72459 | ** will refer to the last entry in the database table or index. |
| 72460 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72461 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72462 | ** to the following instruction. |
| 72463 | ** |
| 72464 | ** This opcode leaves the cursor configured to move in reverse order, |
| 72465 | ** from the end toward the beginning. In other words, the cursor is |
| 72466 | ** configured to use Prev, not Next. |
| 72467 | */ |
| 72468 | case OP_Last: { /* jump */ |
| 72469 | VdbeCursor *pC; |
| 72470 | BtCursor *pCrsr; |
| 72471 | int res; |
| @@ -72032,10 +72479,13 @@ | |
| 72479 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72480 | pC->nullRow = (u8)res; |
| 72481 | pC->deferredMoveto = 0; |
| 72482 | pC->rowidIsValid = 0; |
| 72483 | pC->cacheStatus = CACHE_STALE; |
| 72484 | #ifdef SQLITE_DEBUG |
| 72485 | pC->seekOp = OP_Last; |
| 72486 | #endif |
| 72487 | if( pOp->p2>0 ){ |
| 72488 | VdbeBranchTaken(res!=0,2); |
| 72489 | if( res ) pc = pOp->p2 - 1; |
| 72490 | } |
| 72491 | break; |
| @@ -72068,10 +72518,14 @@ | |
| 72518 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72519 | ** will refer to the first entry in the database table or index. |
| 72520 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72521 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72522 | ** to the following instruction. |
| 72523 | ** |
| 72524 | ** This opcode leaves the cursor configured to move in forward order, |
| 72525 | ** from the begining toward the end. In other words, the cursor is |
| 72526 | ** configured to use Next, not Prev. |
| 72527 | */ |
| 72528 | case OP_Rewind: { /* jump */ |
| 72529 | VdbeCursor *pC; |
| 72530 | BtCursor *pCrsr; |
| 72531 | int res; |
| @@ -72079,10 +72533,13 @@ | |
| 72533 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72534 | pC = p->apCsr[pOp->p1]; |
| 72535 | assert( pC!=0 ); |
| 72536 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72537 | res = 1; |
| 72538 | #ifdef SQLITE_DEBUG |
| 72539 | pC->seekOp = OP_Rewind; |
| 72540 | #endif |
| 72541 | if( isSorter(pC) ){ |
| 72542 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72543 | }else{ |
| 72544 | pCrsr = pC->pCursor; |
| 72545 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | |
| 72561 | ** |
| 72562 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72563 | ** table or index. If there are no more key/value pairs then fall through |
| 72564 | ** to the following instruction. But if the cursor advance was successful, |
| 72565 | ** jump immediately to P2. |
| 72566 | ** |
| 72567 | ** The Next opcode is only valid following an SeekGT, SeekGE, or |
| 72568 | ** OP_Rewind opcode used to position the cursor. Next is not allowed |
| 72569 | ** to follow SeekLT, SeekLE, or OP_Last. |
| 72570 | ** |
| 72571 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72572 | ** been opened prior to this opcode or the program will segfault. |
| 72573 | ** |
| 72574 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | |
| 72584 | ** |
| 72585 | ** See also: Prev, NextIfOpen |
| 72586 | */ |
| 72587 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72588 | ** |
| 72589 | ** This opcode works just like Next except that if cursor P1 is not |
| 72590 | ** open it behaves a no-op. |
| 72591 | */ |
| 72592 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72593 | ** |
| 72594 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72595 | ** table or index. If there is no previous key/value pairs then fall through |
| 72596 | ** to the following instruction. But if the cursor backup was successful, |
| 72597 | ** jump immediately to P2. |
| 72598 | ** |
| 72599 | ** |
| 72600 | ** The Prev opcode is only valid following an SeekLT, SeekLE, or |
| 72601 | ** OP_Last opcode used to position the cursor. Prev is not allowed |
| 72602 | ** to follow SeekGT, SeekGE, or OP_Rewind. |
| 72603 | ** |
| 72604 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72605 | ** not open then the behavior is undefined. |
| 72606 | ** |
| 72607 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72608 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | |
| 72615 | ** If P5 is positive and the jump is taken, then event counter |
| 72616 | ** number P5-1 in the prepared statement is incremented. |
| 72617 | */ |
| 72618 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72619 | ** |
| 72620 | ** This opcode works just like Prev except that if cursor P1 is not |
| 72621 | ** open it behaves a no-op. |
| 72622 | */ |
| 72623 | case OP_SorterNext: { /* jump */ |
| 72624 | VdbeCursor *pC; |
| 72625 | int res; |
| @@ -72180,10 +72646,20 @@ | |
| 72646 | testcase( res==1 ); |
| 72647 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72648 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72649 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72650 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72651 | |
| 72652 | /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. |
| 72653 | ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ |
| 72654 | assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen |
| 72655 | || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE |
| 72656 | || pC->seekOp==OP_Rewind ); |
| 72657 | assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen |
| 72658 | || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE |
| 72659 | || pC->seekOp==OP_Last ); |
| 72660 | |
| 72661 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72662 | next_tail: |
| 72663 | pC->cacheStatus = CACHE_STALE; |
| 72664 | VdbeBranchTaken(res==0,2); |
| 72665 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | |
| 72938 | rc = SQLITE_LOCKED; |
| 72939 | p->errorAction = OE_Abort; |
| 72940 | }else{ |
| 72941 | iDb = pOp->p3; |
| 72942 | assert( iCnt==1 ); |
| 72943 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 72944 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72945 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72946 | pOut->flags = MEM_Int; |
| 72947 | pOut->u.i = iMoved; |
| 72948 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | |
| 72978 | case OP_Clear: { |
| 72979 | int nChange; |
| 72980 | |
| 72981 | nChange = 0; |
| 72982 | assert( p->readOnly==0 ); |
| 72983 | assert( DbMaskTest(p->btreeMask, pOp->p2) ); |
| 72984 | rc = sqlite3BtreeClearTable( |
| 72985 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72986 | ); |
| 72987 | if( pOp->p3 ){ |
| 72988 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | |
| 73048 | int flags; |
| 73049 | Db *pDb; |
| 73050 | |
| 73051 | pgno = 0; |
| 73052 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73053 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 73054 | assert( p->readOnly==0 ); |
| 73055 | pDb = &db->aDb[pOp->p1]; |
| 73056 | assert( pDb->pBt!=0 ); |
| 73057 | if( pOp->opcode==OP_CreateTable ){ |
| 73058 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | |
| 73136 | |
| 73137 | /* Opcode: DropTable P1 * * P4 * |
| 73138 | ** |
| 73139 | ** Remove the internal (in-memory) data structures that describe |
| 73140 | ** the table named P4 in database P1. This is called after a table |
| 73141 | ** is dropped from disk (using the Destroy opcode) in order to keep |
| 73142 | ** the internal representation of the |
| 73143 | ** schema consistent with what is on disk. |
| 73144 | */ |
| 73145 | case OP_DropTable: { |
| 73146 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 73147 | break; |
| @@ -72672,11 +73149,12 @@ | |
| 73149 | |
| 73150 | /* Opcode: DropIndex P1 * * P4 * |
| 73151 | ** |
| 73152 | ** Remove the internal (in-memory) data structures that describe |
| 73153 | ** the index named P4 in database P1. This is called after an index |
| 73154 | ** is dropped from disk (using the Destroy opcode) |
| 73155 | ** in order to keep the internal representation of the |
| 73156 | ** schema consistent with what is on disk. |
| 73157 | */ |
| 73158 | case OP_DropIndex: { |
| 73159 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 73160 | break; |
| @@ -72684,11 +73162,12 @@ | |
| 73162 | |
| 73163 | /* Opcode: DropTrigger P1 * * P4 * |
| 73164 | ** |
| 73165 | ** Remove the internal (in-memory) data structures that describe |
| 73166 | ** the trigger named P4 in database P1. This is called after a trigger |
| 73167 | ** is dropped from disk (using the Destroy opcode) in order to keep |
| 73168 | ** the internal representation of the |
| 73169 | ** schema consistent with what is on disk. |
| 73170 | */ |
| 73171 | case OP_DropTrigger: { |
| 73172 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 73173 | break; |
| @@ -72737,11 +73216,11 @@ | |
| 73216 | for(j=0; j<nRoot; j++){ |
| 73217 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 73218 | } |
| 73219 | aRoot[j] = 0; |
| 73220 | assert( pOp->p5<db->nDb ); |
| 73221 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); |
| 73222 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 73223 | (int)pnErr->u.i, &nErr); |
| 73224 | sqlite3DbFree(db, aRoot); |
| 73225 | pnErr->u.i -= nErr; |
| 73226 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | |
| 73876 | */ |
| 73877 | case OP_IncrVacuum: { /* jump */ |
| 73878 | Btree *pBt; |
| 73879 | |
| 73880 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73881 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 73882 | assert( p->readOnly==0 ); |
| 73883 | pBt = db->aDb[pOp->p1].pBt; |
| 73884 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73885 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73886 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | |
| 73891 | } |
| 73892 | #endif |
| 73893 | |
| 73894 | /* Opcode: Expire P1 * * * * |
| 73895 | ** |
| 73896 | ** Cause precompiled statements to expire. When an expired statement |
| 73897 | ** is executed using sqlite3_step() it will either automatically |
| 73898 | ** reprepare itself (if it was originally created using sqlite3_prepare_v2()) |
| 73899 | ** or it will fail with SQLITE_SCHEMA. |
| 73900 | ** |
| 73901 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73902 | ** then only the currently executing statement is expired. |
| 73903 | */ |
| 73904 | case OP_Expire: { |
| 73905 | if( !pOp->p1 ){ |
| 73906 | sqlite3ExpirePreparedStatements(db); |
| 73907 | }else{ |
| @@ -73449,11 +73929,11 @@ | |
| 73929 | case OP_TableLock: { |
| 73930 | u8 isWriteLock = (u8)pOp->p3; |
| 73931 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73932 | int p1 = pOp->p1; |
| 73933 | assert( p1>=0 && p1<db->nDb ); |
| 73934 | assert( DbMaskTest(p->btreeMask, p1) ); |
| 73935 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73936 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73937 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73938 | const char *z = pOp->p4.z; |
| 73939 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | |
| 74379 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 74380 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 74381 | if( zTrace ){ |
| 74382 | int i; |
| 74383 | for(i=0; i<db->nDb; i++){ |
| 74384 | if( DbMaskTest(p->btreeMask, i)==0 ) continue; |
| 74385 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 74386 | } |
| 74387 | } |
| 74388 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 74389 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | |
| 75369 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 75370 | ** has been allocated and contains an unpacked record that is used as key2. |
| 75371 | */ |
| 75372 | static void vdbeSorterCompare( |
| 75373 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 75374 | int nKeyCol, /* Num of columns. 0 means "all" */ |
| 75375 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 75376 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 75377 | int *pRes /* OUT: Result of comparison */ |
| 75378 | ){ |
| 75379 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | |
| 75383 | |
| 75384 | if( pKey2 ){ |
| 75385 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 75386 | } |
| 75387 | |
| 75388 | if( nKeyCol ){ |
| 75389 | r2->nField = nKeyCol; |
| 75390 | for(i=0; i<nKeyCol; i++){ |
| 75391 | if( r2->aMem[i].flags & MEM_Null ){ |
| 75392 | *pRes = -1; |
| 75393 | return; |
| 75394 | } |
| 75395 | } |
| @@ -75588,18 +76067,18 @@ | |
| 76067 | ** key. |
| 76068 | */ |
| 76069 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 76070 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 76071 | Mem *pVal, /* Value to compare to current sorter key */ |
| 76072 | int nKeyCol, /* Only compare this many fields */ |
| 76073 | int *pRes /* OUT: Result of comparison */ |
| 76074 | ){ |
| 76075 | VdbeSorter *pSorter = pCsr->pSorter; |
| 76076 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 76077 | |
| 76078 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 76079 | vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes); |
| 76080 | return SQLITE_OK; |
| 76081 | } |
| 76082 | |
| 76083 | /************** End of vdbesort.c ********************************************/ |
| 76084 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | |
| 79831 | } |
| 79832 | } |
| 79833 | } |
| 79834 | |
| 79835 | if( eType==0 ){ |
| 79836 | /* Could not find an existing table or index to use as the RHS b-tree. |
| 79837 | ** We will have to generate an ephemeral table to do the job. |
| 79838 | */ |
| 79839 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79840 | int rMayHaveNull = 0; |
| 79841 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | |
| 79961 | /* Case 1: expr IN (SELECT ...) |
| 79962 | ** |
| 79963 | ** Generate code to write the results of the select into the temporary |
| 79964 | ** table allocated and opened above. |
| 79965 | */ |
| 79966 | Select *pSelect = pExpr->x.pSelect; |
| 79967 | SelectDest dest; |
| 79968 | ExprList *pEList; |
| 79969 | |
| 79970 | assert( !isRowid ); |
| 79971 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79972 | dest.affSdst = (u8)affinity; |
| 79973 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79974 | pSelect->iLimit = 0; |
| 79975 | testcase( pSelect->selFlags & SF_Distinct ); |
| 79976 | pSelect->selFlags &= ~SF_Distinct; |
| 79977 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79978 | if( sqlite3Select(pParse, pSelect, &dest) ){ |
| 79979 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79980 | return 0; |
| 79981 | } |
| 79982 | pEList = pSelect->pEList; |
| 79983 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79984 | assert( pEList!=0 ); |
| 79985 | assert( pEList->nExpr>0 ); |
| 79986 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79987 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | |
| 80285 | }else{ |
| 80286 | int c; |
| 80287 | i64 value; |
| 80288 | const char *z = pExpr->u.zToken; |
| 80289 | assert( z!=0 ); |
| 80290 | c = sqlite3DecOrHexToI64(z, &value); |
| 80291 | if( c==0 || (c==2 && negFlag) ){ |
| 80292 | char *zV; |
| 80293 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 80294 | zV = dup8bytes(v, (char*)&value); |
| 80295 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 80296 | }else{ |
| 80297 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 80298 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 80299 | #else |
| 80300 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 80301 | if( sqlite3_strnicmp(z,"0x",2)==0 ){ |
| 80302 | sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); |
| 80303 | }else |
| 80304 | #endif |
| 80305 | { |
| 80306 | codeReal(v, z, negFlag, iMem); |
| 80307 | } |
| 80308 | #endif |
| 80309 | } |
| 80310 | } |
| 80311 | } |
| 80312 | |
| @@ -83186,19 +83675,24 @@ | |
| 83675 | } |
| 83676 | |
| 83677 | /* |
| 83678 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83679 | ** are: |
| 83680 | ** N: The number of columns in the index including the rowid/pk (note 1) |
| 83681 | ** K: The number of columns in the index excluding the rowid/pk. |
| 83682 | ** C: The number of rows in the index (note 2) |
| 83683 | ** |
| 83684 | ** Note 1: In the special case of the covering index that implements a |
| 83685 | ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the |
| 83686 | ** total number of columns in the table. |
| 83687 | ** |
| 83688 | ** Note 2: C is only used for STAT3 and STAT4. |
| 83689 | ** |
| 83690 | ** For indexes on ordinary rowid tables, N==K+1. But for indexes on |
| 83691 | ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the |
| 83692 | ** PRIMARY KEY of the table. The covering index that implements the |
| 83693 | ** original WITHOUT ROWID table as N==K as a special case. |
| 83694 | ** |
| 83695 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83696 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83697 | ** the size of the blob is sizeof(void*) bytes). |
| 83698 | */ |
| @@ -83504,11 +83998,14 @@ | |
| 83998 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83999 | ** C Index of left-most column to differ from previous row |
| 84000 | ** R Rowid for the current row. Might be a key record for |
| 84001 | ** WITHOUT ROWID tables. |
| 84002 | ** |
| 84003 | ** This SQL function always returns NULL. It's purpose it to accumulate |
| 84004 | ** statistical data and/or samples in the Stat4Accum object about the |
| 84005 | ** index being analyzed. The stat_get() SQL function will later be used to |
| 84006 | ** extract relevant information for constructing the sqlite_statN tables. |
| 84007 | ** |
| 84008 | ** The R parameter is only used for STAT3 and STAT4 |
| 84009 | */ |
| 84010 | static void statPush( |
| 84011 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | |
| 84095 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 84096 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 84097 | |
| 84098 | /* |
| 84099 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 84100 | ** used to query statistical information that has been gathered into |
| 84101 | ** the Stat4Accum object by prior calls to stat_push(). The P parameter |
| 84102 | ** is a BLOB which is decoded into a pointer to the Stat4Accum objects. |
| 84103 | ** The content to returned is determined by the parameter J |
| 84104 | ** which is one of the STAT_GET_xxxx values defined above. |
| 84105 | ** |
| 84106 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 84107 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 84108 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | |
| 84317 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 84318 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 84319 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 84320 | |
| 84321 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 84322 | int nCol; /* Number of columns in pIdx. "N" */ |
| 84323 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 84324 | int addrNextRow; /* Address of "next_row:" */ |
| 84325 | const char *zIdxName; /* Name of the index */ |
| 84326 | int nColTest; /* Number of columns to test for changes */ |
| 84327 | |
| 84328 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 84329 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 84330 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 84331 | nCol = pIdx->nKeyCol; |
| 84332 | zIdxName = pTab->zName; |
| 84333 | nColTest = nCol - 1; |
| 84334 | }else{ |
| 84335 | nCol = pIdx->nColumn; |
| 84336 | zIdxName = pIdx->zName; |
| 84337 | nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; |
| 84338 | } |
| 84339 | |
| 84340 | /* Populate the register containing the index name. */ |
| 84341 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 84342 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 84343 | |
| @@ -83863,11 +84362,11 @@ | |
| 84362 | ** regPrev(0) = idx(0) |
| 84363 | ** chng_addr_1: |
| 84364 | ** regPrev(1) = idx(1) |
| 84365 | ** ... |
| 84366 | ** |
| 84367 | ** endDistinctTest: |
| 84368 | ** regRowid = idx(rowid) |
| 84369 | ** stat_push(P, regChng, regRowid) |
| 84370 | ** Next csr |
| 84371 | ** if !eof(csr) goto next_row; |
| 84372 | ** |
| @@ -83876,24 +84375,27 @@ | |
| 84375 | |
| 84376 | /* Make sure there are enough memory cells allocated to accommodate |
| 84377 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 84378 | ** when building a record to insert into the sample column of |
| 84379 | ** the sqlite_stat4 table. */ |
| 84380 | pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); |
| 84381 | |
| 84382 | /* Open a read-only cursor on the index being analyzed. */ |
| 84383 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 84384 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 84385 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 84386 | VdbeComment((v, "%s", pIdx->zName)); |
| 84387 | |
| 84388 | /* Invoke the stat_init() function. The arguments are: |
| 84389 | ** |
| 84390 | ** (1) the number of columns in the index including the rowid |
| 84391 | ** (or for a WITHOUT ROWID table, the number of PK columns), |
| 84392 | ** (2) the number of columns in the key without the rowid/pk |
| 84393 | ** (3) the number of rows in the index, |
| 84394 | ** |
| 84395 | ** |
| 84396 | ** The third argument is only used for STAT3 and STAT4 |
| 84397 | */ |
| 84398 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84399 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 84400 | #endif |
| 84401 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | |
| 84413 | ** |
| 84414 | */ |
| 84415 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 84416 | VdbeCoverage(v); |
| 84417 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 84418 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84419 | |
| 84420 | if( nColTest>0 ){ |
| 84421 | int endDistinctTest = sqlite3VdbeMakeLabel(v); |
| 84422 | int *aGotoChng; /* Array of jump instruction addresses */ |
| 84423 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); |
| 84424 | if( aGotoChng==0 ) continue; |
| 84425 | |
| 84426 | /* |
| 84427 | ** next_row: |
| 84428 | ** regChng = 0 |
| 84429 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 84430 | ** regChng = 1 |
| 84431 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 84432 | ** ... |
| 84433 | ** regChng = N |
| 84434 | ** goto endDistinctTest |
| 84435 | */ |
| 84436 | sqlite3VdbeAddOp0(v, OP_Goto); |
| 84437 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84438 | if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ |
| 84439 | /* For a single-column UNIQUE index, once we have found a non-NULL |
| 84440 | ** row, we know that all the rest will be distinct, so skip |
| 84441 | ** subsequent distinctness tests. */ |
| 84442 | sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); |
| 84443 | VdbeCoverage(v); |
| 84444 | } |
| 84445 | for(i=0; i<nColTest; i++){ |
| 84446 | char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 84447 | sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 84448 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 84449 | aGotoChng[i] = |
| 84450 | sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 84451 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 84452 | VdbeCoverage(v); |
| 84453 | } |
| 84454 | sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); |
| 84455 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); |
| 84456 | |
| 84457 | |
| 84458 | /* |
| 84459 | ** chng_addr_0: |
| 84460 | ** regPrev(0) = idx(0) |
| 84461 | ** chng_addr_1: |
| 84462 | ** regPrev(1) = idx(1) |
| 84463 | ** ... |
| 84464 | */ |
| 84465 | sqlite3VdbeJumpHere(v, addrNextRow-1); |
| 84466 | for(i=0; i<nColTest; i++){ |
| 84467 | sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 84468 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 84469 | } |
| 84470 | sqlite3VdbeResolveLabel(v, endDistinctTest); |
| 84471 | sqlite3DbFree(db, aGotoChng); |
| 84472 | } |
| 84473 | |
| 84474 | /* |
| 84475 | ** chng_addr_N: |
| 84476 | ** regRowid = idx(rowid) // STAT34 only |
| 84477 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 84478 | ** Next csr |
| 84479 | ** if !eof(csr) goto next_row; |
| 84480 | */ |
| 84481 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84482 | assert( regRowid==(regStat4+2) ); |
| 84483 | if( HasRowid(pTab) ){ |
| 84484 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 84485 | }else{ |
| @@ -84034,11 +84553,10 @@ | |
| 84553 | } |
| 84554 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84555 | |
| 84556 | /* End of analysis */ |
| 84557 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84558 | } |
| 84559 | |
| 84560 | |
| 84561 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84562 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | |
| 84653 | int i; |
| 84654 | char *z, *zDb; |
| 84655 | Table *pTab; |
| 84656 | Index *pIdx; |
| 84657 | Token *pTableName; |
| 84658 | Vdbe *v; |
| 84659 | |
| 84660 | /* Read the database schema. If an error occurs, leave an error message |
| 84661 | ** and code in pParse and return NULL. */ |
| 84662 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84663 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | |
| 84701 | } |
| 84702 | sqlite3DbFree(db, z); |
| 84703 | } |
| 84704 | } |
| 84705 | } |
| 84706 | v = sqlite3GetVdbe(pParse); |
| 84707 | if( v ) sqlite3VdbeAddOp0(v, OP_Expire); |
| 84708 | } |
| 84709 | |
| 84710 | /* |
| 84711 | ** Used to pass information from the analyzer reader through to the |
| 84712 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | |
| 84761 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84762 | assert( pIndex!=0 ); |
| 84763 | #else |
| 84764 | if( pIndex ) |
| 84765 | #endif |
| 84766 | while( z[0] ){ |
| 84767 | if( sqlite3_strglob("unordered*", z)==0 ){ |
| 84768 | pIndex->bUnordered = 1; |
| 84769 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84770 | pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); |
| 84771 | } |
| 84772 | #ifdef SQLITE_ENABLE_COSTMULT |
| 84773 | else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ |
| 84774 | pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); |
| 84775 | } |
| 84776 | #endif |
| 84777 | while( z[0]!=0 && z[0]!=' ' ) z++; |
| 84778 | while( z[0]==' ' ) z++; |
| 84779 | } |
| 84780 | } |
| 84781 | |
| 84782 | /* |
| 84783 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | |
| 84814 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84815 | } |
| 84816 | z = argv[2]; |
| 84817 | |
| 84818 | if( pIndex ){ |
| 84819 | pIndex->bUnordered = 0; |
| 84820 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84821 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84822 | }else{ |
| 84823 | Index fakeIdx; |
| 84824 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84825 | #ifdef SQLITE_ENABLE_COSTMULT |
| 84826 | fakeIdx.pTable = pTable; |
| 84827 | #endif |
| 84828 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84829 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84830 | } |
| 84831 | |
| 84832 | return 0; |
| @@ -85568,10 +86098,23 @@ | |
| 86098 | } |
| 86099 | #else |
| 86100 | #define codeTableLocks(x) |
| 86101 | #endif |
| 86102 | |
| 86103 | /* |
| 86104 | ** Return TRUE if the given yDbMask object is empty - if it contains no |
| 86105 | ** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() |
| 86106 | ** macros when SQLITE_MAX_ATTACHED is greater than 30. |
| 86107 | */ |
| 86108 | #if SQLITE_MAX_ATTACHED>30 |
| 86109 | SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ |
| 86110 | int i; |
| 86111 | for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0; |
| 86112 | return 1; |
| 86113 | } |
| 86114 | #endif |
| 86115 | |
| 86116 | /* |
| 86117 | ** This routine is called after a single SQL statement has been |
| 86118 | ** parsed and a VDBE program to execute that statement has been |
| 86119 | ** prepared. This routine puts the finishing touches on the |
| 86120 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | |
| 86147 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 86148 | ** set for each database that is used. Generate code to start a |
| 86149 | ** transaction on each used database and to verify the schema cookie |
| 86150 | ** on each used database. |
| 86151 | */ |
| 86152 | if( db->mallocFailed==0 |
| 86153 | && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) |
| 86154 | ){ |
| 86155 | int iDb, i; |
| 86156 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 86157 | sqlite3VdbeJumpHere(v, 0); |
| 86158 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 86159 | if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; |
| 86160 | sqlite3VdbeUsesBtree(v, iDb); |
| 86161 | sqlite3VdbeAddOp4Int(v, |
| 86162 | OP_Transaction, /* Opcode */ |
| 86163 | iDb, /* P1 */ |
| 86164 | DbMaskTest(pParse->writeMask,iDb), /* P2 */ |
| 86165 | pParse->cookieValue[iDb], /* P3 */ |
| 86166 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 86167 | ); |
| 86168 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 86169 | } |
| @@ -85671,11 +86215,11 @@ | |
| 86215 | } |
| 86216 | pParse->nTab = 0; |
| 86217 | pParse->nMem = 0; |
| 86218 | pParse->nSet = 0; |
| 86219 | pParse->nVar = 0; |
| 86220 | DbMaskZero(pParse->cookieMask); |
| 86221 | } |
| 86222 | |
| 86223 | /* |
| 86224 | ** Run the parser and code generator recursively in order to generate |
| 86225 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | |
| 88697 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88698 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88699 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88700 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88701 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88702 | pIndex->nKeyCol); VdbeCoverage(v); |
| 88703 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88704 | }else{ |
| 88705 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88706 | } |
| 88707 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | |
| 89842 | ** later, by sqlite3FinishCoding(). |
| 89843 | */ |
| 89844 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89845 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89846 | sqlite3 *db = pToplevel->db; |
| 89847 | |
| 89848 | assert( iDb>=0 && iDb<db->nDb ); |
| 89849 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89850 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89851 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89852 | if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ |
| 89853 | DbMaskSet(pToplevel->cookieMask, iDb); |
| 89854 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89855 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89856 | sqlite3OpenTempDatabase(pToplevel); |
| 89857 | } |
| 89858 | } |
| @@ -89345,11 +89887,11 @@ | |
| 89887 | ** necessary to undo a write and the checkpoint should not be set. |
| 89888 | */ |
| 89889 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89890 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89891 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89892 | DbMaskSet(pToplevel->writeMask, iDb); |
| 89893 | pToplevel->isMultiWrite |= setStatement; |
| 89894 | } |
| 89895 | |
| 89896 | /* |
| 89897 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | |
| 98575 | ** Note that the values returned are one less that the values that |
| 98576 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98577 | ** to support legacy SQL code. The safety level used to be boolean |
| 98578 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98579 | */ |
| 98580 | static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ |
| 98581 | /* 123456789 123456789 */ |
| 98582 | static const char zText[] = "onoffalseyestruefull"; |
| 98583 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98584 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98585 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | |
| 98597 | } |
| 98598 | |
| 98599 | /* |
| 98600 | ** Interpret the given string as a boolean value. |
| 98601 | */ |
| 98602 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){ |
| 98603 | return getSafetyLevel(z,1,dflt)!=0; |
| 98604 | } |
| 98605 | |
| 98606 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98607 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | |
| 99143 | */ |
| 99144 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 99145 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 99146 | i64 iLimit = -2; |
| 99147 | if( zRight ){ |
| 99148 | sqlite3DecOrHexToI64(zRight, &iLimit); |
| 99149 | if( iLimit<-1 ) iLimit = -1; |
| 99150 | } |
| 99151 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 99152 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 99153 | break; |
| @@ -98729,11 +99271,11 @@ | |
| 99271 | sqlite3_int64 sz; |
| 99272 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 99273 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 99274 | if( zRight ){ |
| 99275 | int ii; |
| 99276 | sqlite3DecOrHexToI64(zRight, &sz); |
| 99277 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 99278 | if( pId2->n==0 ) db->szMmap = sz; |
| 99279 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 99280 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 99281 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | |
| 100314 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 100315 | ** use -1. |
| 100316 | */ |
| 100317 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 100318 | sqlite3_int64 N; |
| 100319 | if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ |
| 100320 | sqlite3_soft_heap_limit64(N); |
| 100321 | } |
| 100322 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 100323 | break; |
| 100324 | } |
| @@ -112245,11 +112787,12 @@ | |
| 112787 | int nEq = pLoop->u.btree.nEq; |
| 112788 | sqlite3 *db = pParse->db; |
| 112789 | int nLower = -1; |
| 112790 | int nUpper = p->nSample+1; |
| 112791 | int rc = SQLITE_OK; |
| 112792 | int iCol = p->aiColumn[nEq]; |
| 112793 | u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; |
| 112794 | CollSeq *pColl; |
| 112795 | |
| 112796 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112797 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112798 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | |
| 114163 | int regRowid = 0; /* Register holding rowid */ |
| 114164 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 114165 | int iRetInit; /* Address of regReturn init */ |
| 114166 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 114167 | int ii; /* Loop counter */ |
| 114168 | u16 wctrlFlags; /* Flags for sub-WHERE clause */ |
| 114169 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 114170 | Table *pTab = pTabItem->pTab; |
| 114171 | |
| 114172 | pTerm = pLoop->aLTerm[0]; |
| 114173 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | |
| 114259 | |
| 114260 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 114261 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 114262 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 114263 | */ |
| 114264 | wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | |
| 114265 | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY; |
| 114266 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 114267 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 114268 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 114269 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 114270 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | |
| 114273 | pAndExpr->pLeft = pOrExpr; |
| 114274 | pOrExpr = pAndExpr; |
| 114275 | } |
| 114276 | /* Loop through table entries that match term pOrTerm. */ |
| 114277 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 114278 | wctrlFlags, iCovCur); |
| 114279 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 114280 | if( pSubWInfo ){ |
| 114281 | WhereLoop *pSubLoop; |
| 114282 | explainOneScan( |
| 114283 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | |
| 114364 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 114365 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 114366 | ){ |
| 114367 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 114368 | pCov = pSubLoop->u.btree.pIndex; |
| 114369 | wctrlFlags |= WHERE_REOPEN_IDX; |
| 114370 | }else{ |
| 114371 | pCov = 0; |
| 114372 | } |
| 114373 | |
| 114374 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | |
| 114971 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114972 | } |
| 114973 | } |
| 114974 | } |
| 114975 | |
| 114976 | /* |
| 114977 | ** Adjust the cost C by the costMult facter T. This only occurs if |
| 114978 | ** compiled with -DSQLITE_ENABLE_COSTMULT |
| 114979 | */ |
| 114980 | #ifdef SQLITE_ENABLE_COSTMULT |
| 114981 | # define ApplyCostMultiplier(C,T) C += T |
| 114982 | #else |
| 114983 | # define ApplyCostMultiplier(C,T) |
| 114984 | #endif |
| 114985 | |
| 114986 | /* |
| 114987 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114988 | ** index pIndex. Try to match one more. |
| 114989 | ** |
| 114990 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | |
| 115177 | testcase( eOp & WO_ISNULL ); |
| 115178 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 115179 | }else{ |
| 115180 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 115181 | } |
| 115182 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 115183 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 115184 | if( nOut ){ |
| 115185 | pNew->nOut = sqlite3LogEst(nOut); |
| 115186 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | |
| 115208 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 115209 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 115210 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 115211 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 115212 | } |
| 115213 | ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); |
| 115214 | |
| 115215 | nOutUnadjusted = pNew->nOut; |
| 115216 | pNew->rRun += nInMul + nIn; |
| 115217 | pNew->nOut += nInMul + nIn; |
| 115218 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | |
| 115328 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 115329 | ** |
| 115330 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 115331 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 115332 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 115333 | ** |
| 115334 | ** The estimated values (nRow, nVisit, nSeek) often contain a large amount |
| 115335 | ** of uncertainty. For this reason, scoring is designed to pick plans that |
| 115336 | ** "do the least harm" if the estimates are inaccurate. For example, a |
| 115337 | ** log(nRow) factor is omitted from a non-covering index scan in order to |
| 115338 | ** bias the scoring in favor of using an index, since the worst-case |
| 115339 | ** performance of using an index is far better than the worst-case performance |
| 115340 | ** of a full table scan. |
| 115341 | */ |
| 115342 | static int whereLoopAddBtree( |
| 115343 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 115344 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 115345 | ){ |
| @@ -114859,10 +115423,11 @@ | |
| 115423 | pNew->aLTerm[0] = pTerm; |
| 115424 | /* TUNING: One-time cost for computing the automatic index is |
| 115425 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 115426 | ** the table being indexed. */ |
| 115427 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 115428 | ApplyCostMultiplier(pNew->rSetup, pTab->costMult); |
| 115429 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 115430 | ** is more than the usual guess of 10 rows, since we have no way |
| 115431 | ** of knowning how selective the index will ultimately be. It would |
| 115432 | ** not be unreasonable to make this value much larger. */ |
| 115433 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | |
| 115465 | |
| 115466 | /* Full table scan */ |
| 115467 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 115468 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 115469 | pNew->rRun = rSize + 16; |
| 115470 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 115471 | whereLoopOutputAdjust(pWC, pNew); |
| 115472 | rc = whereLoopInsert(pBuilder, pNew); |
| 115473 | pNew->nOut = rSize; |
| 115474 | if( rc ) break; |
| 115475 | }else{ |
| @@ -114935,11 +115501,11 @@ | |
| 115501 | ** also add the cost of visiting table rows (N*3.0). */ |
| 115502 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 115503 | if( m!=0 ){ |
| 115504 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 115505 | } |
| 115506 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 115507 | whereLoopOutputAdjust(pWC, pNew); |
| 115508 | rc = whereLoopInsert(pBuilder, pNew); |
| 115509 | pNew->nOut = rSize; |
| 115510 | if( rc ) break; |
| 115511 | } |
| @@ -116410,10 +116976,11 @@ | |
| 116976 | } |
| 116977 | op = OP_OpenWrite; |
| 116978 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116979 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116980 | iIndexCur = iIdxCur; |
| 116981 | if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; |
| 116982 | }else{ |
| 116983 | iIndexCur = pParse->nTab++; |
| 116984 | } |
| 116985 | pLevel->iIdxCur = iIndexCur; |
| 116986 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | |
| 121301 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 121302 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 121303 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 121304 | testcase( z[0]=='9' ); |
| 121305 | *tokenType = TK_INTEGER; |
| 121306 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 121307 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ |
| 121308 | for(i=3; sqlite3Isxdigit(z[i]); i++){} |
| 121309 | return i; |
| 121310 | } |
| 121311 | #endif |
| 121312 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 121313 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 121314 | if( z[i]=='.' ){ |
| 121315 | i++; |
| 121316 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | |
| 122983 | |
| 122984 | /* |
| 122985 | ** Return a static string containing the name corresponding to the error code |
| 122986 | ** specified in the argument. |
| 122987 | */ |
| 122988 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 122989 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122990 | const char *zName = 0; |
| 122991 | int i, origRc = rc; |
| 122992 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122993 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | |
| 124028 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 124029 | #endif |
| 124030 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 124031 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 124032 | #endif |
| 124033 | #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 |
| 124034 | # error SQLITE_MAX_ATTACHED must be between 0 and 125 |
| 124035 | #endif |
| 124036 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 124037 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 124038 | #endif |
| 124039 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | |
| 125288 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 125289 | #endif |
| 125290 | break; |
| 125291 | } |
| 125292 | |
| 125293 | /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); |
| 125294 | ** |
| 125295 | ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if |
| 125296 | ** not. |
| 125297 | */ |
| 125298 | case SQLITE_TESTCTRL_ISINIT: { |
| 125299 | if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; |
| 125300 | break; |
| 125301 | } |
| 125302 | |
| 125303 | } |
| 125304 | va_end(ap); |
| 125305 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 125306 | return rc; |
| 125307 | } |
| @@ -124763,11 +125346,11 @@ | |
| 125346 | const char *zParam, /* URI parameter sought */ |
| 125347 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 125348 | ){ |
| 125349 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 125350 | sqlite3_int64 v; |
| 125351 | if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ |
| 125352 | bDflt = v; |
| 125353 | } |
| 125354 | return bDflt; |
| 125355 | } |
| 125356 | |
| @@ -126294,11 +126877,11 @@ | |
| 126877 | |
| 126878 | /* fts3_tokenize_vtab.c */ |
| 126879 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126880 | |
| 126881 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126882 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 126883 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126884 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126885 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126886 | #endif |
| 126887 | |
| @@ -129764,11 +130347,11 @@ | |
| 130347 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 130348 | ** And so on. |
| 130349 | */ |
| 130350 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130351 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130352 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130353 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 130354 | #endif |
| 130355 | #ifdef SQLITE_ENABLE_ICU |
| 130356 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130357 | #endif |
| @@ -129782,20 +130365,20 @@ | |
| 130365 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 130366 | int rc = SQLITE_OK; |
| 130367 | Fts3Hash *pHash = 0; |
| 130368 | const sqlite3_tokenizer_module *pSimple = 0; |
| 130369 | const sqlite3_tokenizer_module *pPorter = 0; |
| 130370 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130371 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 130372 | #endif |
| 130373 | |
| 130374 | #ifdef SQLITE_ENABLE_ICU |
| 130375 | const sqlite3_tokenizer_module *pIcu = 0; |
| 130376 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 130377 | #endif |
| 130378 | |
| 130379 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130380 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 130381 | #endif |
| 130382 | |
| 130383 | #ifdef SQLITE_TEST |
| 130384 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | |
| 130402 | /* Load the built-in tokenizers into the hash table */ |
| 130403 | if( rc==SQLITE_OK ){ |
| 130404 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 130405 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 130406 | |
| 130407 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130408 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 130409 | #endif |
| 130410 | #ifdef SQLITE_ENABLE_ICU |
| 130411 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 130412 | #endif |
| @@ -143079,11 +143662,11 @@ | |
| 143662 | ****************************************************************************** |
| 143663 | ** |
| 143664 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143665 | */ |
| 143666 | |
| 143667 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 143668 | |
| 143669 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143670 | |
| 143671 | /* #include <assert.h> */ |
| 143672 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | |
| 143878 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143879 | pNew->bRemoveDiacritic = 1; |
| 143880 | |
| 143881 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143882 | const char *z = azArg[i]; |
| 143883 | int n = (int)strlen(z); |
| 143884 | |
| 143885 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143886 | pNew->bRemoveDiacritic = 1; |
| 143887 | } |
| 143888 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | |
| 144010 | }while( unicodeIsAlnum(p, iCode) |
| 144011 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 144012 | ); |
| 144013 | |
| 144014 | /* Set the output variables and return. */ |
| 144015 | pCsr->iOff = (int)(z - pCsr->aInput); |
| 144016 | *paToken = pCsr->zToken; |
| 144017 | *pnToken = (int)(zOut - pCsr->zToken); |
| 144018 | *piStart = (int)(zStart - pCsr->aInput); |
| 144019 | *piEnd = (int)(zEnd - pCsr->aInput); |
| 144020 | *piPos = pCsr->iToken++; |
| 144021 | return SQLITE_OK; |
| 144022 | } |
| 144023 | |
| 144024 | /* |
| @@ -143454,11 +144037,11 @@ | |
| 144037 | }; |
| 144038 | *ppModule = &module; |
| 144039 | } |
| 144040 | |
| 144041 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 144042 | #endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ |
| 144043 | |
| 144044 | /************** End of fts3_unicode.c ****************************************/ |
| 144045 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 144046 | /* |
| 144047 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | |
| 144058 | |
| 144059 | /* |
| 144060 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 144061 | */ |
| 144062 | |
| 144063 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 144064 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 144065 | |
| 144066 | /* #include <assert.h> */ |
| 144067 | |
| 144068 | /* |
| @@ -143822,11 +144405,11 @@ | |
| 144405 | } |
| 144406 | |
| 144407 | return ret; |
| 144408 | } |
| 144409 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 144410 | #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ |
| 144411 | |
| 144412 | /************** End of fts3_unicode2.c ***************************************/ |
| 144413 | /************** Begin file rtree.c *******************************************/ |
| 144414 | /* |
| 144415 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | |
| 145942 | int rc = SQLITE_OK; |
| 145943 | int iCell = 0; |
| 145944 | |
| 145945 | rtreeReference(pRtree); |
| 145946 | |
| 145947 | /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ |
| 145948 | freeCursorConstraints(pCsr); |
| 145949 | sqlite3_free(pCsr->aPoint); |
| 145950 | memset(pCsr, 0, sizeof(RtreeCursor)); |
| 145951 | pCsr->base.pVtab = (sqlite3_vtab*)pRtree; |
| 145952 | |
| 145953 | pCsr->iStrategy = idxNum; |
| 145954 | if( idxNum==1 ){ |
| 145955 | /* Special case - lookup by rowid. */ |
| 145956 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145957 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145958 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145959 |
+1063
-476
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -222,11 +222,11 @@ | ||
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | -#define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -2150,31 +2150,37 @@ | ||
| 2150 | 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | 2151 | |
| 2152 | 2152 | /* |
| 2153 | 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | 2154 | ** |
| 2155 | -** ^This routine sets a callback function that might be invoked whenever | |
| 2156 | -** an attempt is made to open a database table that another thread | |
| 2157 | -** or process has locked. | |
| 2155 | +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X | |
| 2156 | +** that might be invoked with argument P whenever | |
| 2157 | +** an attempt is made to access a database table associated with | |
| 2158 | +** [database connection] D when another thread | |
| 2159 | +** or process has the table locked. | |
| 2160 | +** The sqlite3_busy_handler() interface is used to implement | |
| 2161 | +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. | |
| 2158 | 2162 | ** |
| 2159 | 2163 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2160 | 2164 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2161 | 2165 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2162 | 2166 | ** |
| 2163 | 2167 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2164 | 2168 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2165 | 2169 | ** the busy handler callback is the number of times that the busy handler has |
| 2166 | -** been invoked for this locking event. ^If the | |
| 2170 | +** been invoked for the same locking event. ^If the | |
| 2167 | 2171 | ** busy callback returns 0, then no additional attempts are made to |
| 2168 | -** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. | |
| 2172 | +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned | |
| 2173 | +** to the application. | |
| 2169 | 2174 | ** ^If the callback returns non-zero, then another attempt |
| 2170 | -** is made to open the database for reading and the cycle repeats. | |
| 2175 | +** is made to access the database and the cycle repeats. | |
| 2171 | 2176 | ** |
| 2172 | 2177 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2173 | 2178 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2174 | 2179 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2175 | -** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. | |
| 2180 | +** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the | |
| 2181 | +** busy handler. | |
| 2176 | 2182 | ** Consider a scenario where one process is holding a read lock that |
| 2177 | 2183 | ** it is trying to promote to a reserved lock and |
| 2178 | 2184 | ** a second process is holding a reserved lock that it is trying |
| 2179 | 2185 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2180 | 2186 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | ||
| 2202 | 2208 | ** this is important. |
| 2203 | 2209 | ** |
| 2204 | 2210 | ** ^(There can only be a single busy handler defined for each |
| 2205 | 2211 | ** [database connection]. Setting a new busy handler clears any |
| 2206 | 2212 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2207 | -** will also set or clear the busy handler. | |
| 2213 | +** or evaluating [PRAGMA busy_timeout=N] will change the | |
| 2214 | +** busy handler and thus clear any previously set busy handler. | |
| 2208 | 2215 | ** |
| 2209 | 2216 | ** The busy callback should not take any actions which modify the |
| 2210 | -** database connection that invoked the busy handler. Any such actions | |
| 2217 | +** database connection that invoked the busy handler. In other words, | |
| 2218 | +** the busy handler is not reentrant. Any such actions | |
| 2211 | 2219 | ** result in undefined behavior. |
| 2212 | 2220 | ** |
| 2213 | 2221 | ** A busy handler must not close the database connection |
| 2214 | 2222 | ** or [prepared statement] that invoked the busy handler. |
| 2215 | 2223 | */ |
| @@ -2230,10 +2238,12 @@ | ||
| 2230 | 2238 | ** |
| 2231 | 2239 | ** ^(There can only be a single busy handler for a particular |
| 2232 | 2240 | ** [database connection] any any given moment. If another busy handler |
| 2233 | 2241 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2234 | 2242 | ** this routine, that other busy handler is cleared.)^ |
| 2243 | +** | |
| 2244 | +** See also: [PRAGMA busy_timeout] | |
| 2235 | 2245 | */ |
| 2236 | 2246 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2237 | 2247 | |
| 2238 | 2248 | /* |
| 2239 | 2249 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | ||
| 4818 | 4828 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4819 | 4829 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4820 | 4830 | ** will be placed in that directory.)^ ^If this variable |
| 4821 | 4831 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4822 | 4832 | ** temporary file directory. |
| 4833 | +** | |
| 4834 | +** Applications are strongly discouraged from using this global variable. | |
| 4835 | +** It is required to set a temporary folder on Windows Runtime (WinRT). | |
| 4836 | +** But for all other platforms, it is highly recommended that applications | |
| 4837 | +** neither read nor write this variable. This global variable is a relic | |
| 4838 | +** that exists for backwards compatibility of legacy applications and should | |
| 4839 | +** be avoided in new projects. | |
| 4823 | 4840 | ** |
| 4824 | 4841 | ** It is not safe to read or modify this variable in more than one |
| 4825 | 4842 | ** thread at a time. It is not safe to read or modify this variable |
| 4826 | 4843 | ** if a [database connection] is being used at the same time in a separate |
| 4827 | 4844 | ** thread. |
| @@ -4837,10 +4854,15 @@ | ||
| 4837 | 4854 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4838 | 4855 | ** using [sqlite3_free]. |
| 4839 | 4856 | ** Hence, if this variable is modified directly, either it should be |
| 4840 | 4857 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4841 | 4858 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4859 | +** Except when requested by the [temp_store_directory pragma], SQLite | |
| 4860 | +** does not free the memory that sqlite3_temp_directory points to. If | |
| 4861 | +** the application wants that memory to be freed, it must do | |
| 4862 | +** so itself, taking care to only do so after all [database connection] | |
| 4863 | +** objects have been destroyed. | |
| 4842 | 4864 | ** |
| 4843 | 4865 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4844 | 4866 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4845 | 4867 | ** features that require the use of temporary files may fail. Here is an |
| 4846 | 4868 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | ||
| 5971 | 5993 | ** <ul> |
| 5972 | 5994 | ** <li> SQLITE_MUTEX_FAST |
| 5973 | 5995 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5974 | 5996 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5975 | 5997 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5976 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 5998 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 5977 | 5999 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5978 | 6000 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5979 | -** <li> SQLITE_MUTEX_STATIC_LRU2 | |
| 6001 | +** <li> SQLITE_MUTEX_STATIC_PMEM | |
| 6002 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 6003 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 5980 | 6004 | ** </ul>)^ |
| 5981 | 6005 | ** |
| 5982 | 6006 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5983 | 6007 | ** cause sqlite3_mutex_alloc() to create |
| 5984 | 6008 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | ||
| 6178 | 6202 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6179 | 6203 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6180 | 6204 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6181 | 6205 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6182 | 6206 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6207 | +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ | |
| 6208 | +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ | |
| 6209 | +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ | |
| 6183 | 6210 | |
| 6184 | 6211 | /* |
| 6185 | 6212 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6186 | 6213 | ** |
| 6187 | 6214 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | ||
| 6273 | 6300 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6274 | 6301 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6275 | 6302 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6276 | 6303 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6277 | 6304 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6278 | -#define SQLITE_TESTCTRL_LAST 22 | |
| 6305 | +#define SQLITE_TESTCTRL_ISINIT 23 | |
| 6306 | +#define SQLITE_TESTCTRL_LAST 23 | |
| 6279 | 6307 | |
| 6280 | 6308 | /* |
| 6281 | 6309 | ** CAPI3REF: SQLite Runtime Status |
| 6282 | 6310 | ** |
| 6283 | 6311 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | ||
| 7256 | 7284 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7257 | 7285 | ** configured by this function. |
| 7258 | 7286 | ** |
| 7259 | 7287 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7260 | 7288 | ** from SQL. |
| 7289 | +** | |
| 7290 | +** ^Checkpoints initiated by this mechanism are | |
| 7291 | +** [sqlite3_wal_checkpoint_v2|PASSIVE]. | |
| 7261 | 7292 | ** |
| 7262 | 7293 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7263 | 7294 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7264 | 7295 | ** pages. The use of this interface |
| 7265 | 7296 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | ||
| 7273 | 7304 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7274 | 7305 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7275 | 7306 | ** empty string, then a checkpoint is run on all databases of |
| 7276 | 7307 | ** connection D. ^If the database connection D is not in |
| 7277 | 7308 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7309 | +** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a | |
| 7310 | +** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. | |
| 7311 | +** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL | |
| 7312 | +** or RESET checkpoint. | |
| 7278 | 7313 | ** |
| 7279 | 7314 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7280 | 7315 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7281 | 7316 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7282 | 7317 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | ||
| 7295 | 7330 | ** <dl> |
| 7296 | 7331 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7297 | 7332 | ** Checkpoint as many frames as possible without waiting for any database |
| 7298 | 7333 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7299 | 7334 | ** are checkpointed. This mode is the same as calling |
| 7300 | -** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. | |
| 7335 | +** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] | |
| 7336 | +** is never invoked. | |
| 7301 | 7337 | ** |
| 7302 | 7338 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7303 | -** This mode blocks (calls the busy-handler callback) until there is no | |
| 7339 | +** This mode blocks (it invokes the | |
| 7340 | +** [sqlite3_busy_handler|busy-handler callback]) until there is no | |
| 7304 | 7341 | ** database writer and all readers are reading from the most recent database |
| 7305 | 7342 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7306 | 7343 | ** database file. This call blocks database writers while it is running, |
| 7307 | 7344 | ** but not database readers. |
| 7308 | 7345 | ** |
| 7309 | 7346 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7310 | 7347 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7311 | -** checkpointing the log file it blocks (calls the busy-handler callback) | |
| 7348 | +** checkpointing the log file it blocks (calls the | |
| 7349 | +** [sqlite3_busy_handler|busy-handler callback]) | |
| 7312 | 7350 | ** until all readers are reading from the database file only. This ensures |
| 7313 | 7351 | ** that the next client to write to the database file restarts the log file |
| 7314 | 7352 | ** from the beginning. This call blocks database writers while it is running, |
| 7315 | 7353 | ** but not database readers. |
| 7316 | 7354 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | ||
| 9285 | 9323 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9286 | 9324 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9287 | 9325 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9288 | 9326 | #define OP_ReadCookie 50 |
| 9289 | 9327 | #define OP_SetCookie 51 |
| 9290 | -#define OP_OpenRead 52 /* synopsis: root=P2 iDb=P3 */ | |
| 9291 | -#define OP_OpenWrite 53 /* synopsis: root=P2 iDb=P3 */ | |
| 9292 | -#define OP_OpenAutoindex 54 /* synopsis: nColumn=P2 */ | |
| 9293 | -#define OP_OpenEphemeral 55 /* synopsis: nColumn=P2 */ | |
| 9294 | -#define OP_SorterOpen 56 | |
| 9295 | -#define OP_OpenPseudo 57 /* synopsis: P3 columns in r[P2] */ | |
| 9296 | -#define OP_Close 58 | |
| 9297 | -#define OP_SeekLT 59 | |
| 9298 | -#define OP_SeekLE 60 | |
| 9299 | -#define OP_SeekGE 61 | |
| 9300 | -#define OP_SeekGT 62 | |
| 9301 | -#define OP_Seek 63 /* synopsis: intkey=r[P2] */ | |
| 9302 | -#define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ | |
| 9303 | -#define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ | |
| 9304 | -#define OP_Found 66 /* synopsis: key=r[P3@P4] */ | |
| 9305 | -#define OP_NotExists 67 /* synopsis: intkey=r[P3] */ | |
| 9306 | -#define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ | |
| 9307 | -#define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ | |
| 9308 | -#define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ | |
| 9328 | +#define OP_ReopenIdx 52 /* synopsis: root=P2 iDb=P3 */ | |
| 9329 | +#define OP_OpenRead 53 /* synopsis: root=P2 iDb=P3 */ | |
| 9330 | +#define OP_OpenWrite 54 /* synopsis: root=P2 iDb=P3 */ | |
| 9331 | +#define OP_OpenAutoindex 55 /* synopsis: nColumn=P2 */ | |
| 9332 | +#define OP_OpenEphemeral 56 /* synopsis: nColumn=P2 */ | |
| 9333 | +#define OP_SorterOpen 57 | |
| 9334 | +#define OP_OpenPseudo 58 /* synopsis: P3 columns in r[P2] */ | |
| 9335 | +#define OP_Close 59 | |
| 9336 | +#define OP_SeekLT 60 /* synopsis: key=r[P3@P4] */ | |
| 9337 | +#define OP_SeekLE 61 /* synopsis: key=r[P3@P4] */ | |
| 9338 | +#define OP_SeekGE 62 /* synopsis: key=r[P3@P4] */ | |
| 9339 | +#define OP_SeekGT 63 /* synopsis: key=r[P3@P4] */ | |
| 9340 | +#define OP_Seek 64 /* synopsis: intkey=r[P2] */ | |
| 9341 | +#define OP_NoConflict 65 /* synopsis: key=r[P3@P4] */ | |
| 9342 | +#define OP_NotFound 66 /* synopsis: key=r[P3@P4] */ | |
| 9343 | +#define OP_Found 67 /* synopsis: key=r[P3@P4] */ | |
| 9344 | +#define OP_NotExists 68 /* synopsis: intkey=r[P3] */ | |
| 9345 | +#define OP_Sequence 69 /* synopsis: r[P2]=cursor[P1].ctr++ */ | |
| 9346 | +#define OP_NewRowid 70 /* synopsis: r[P2]=rowid */ | |
| 9309 | 9347 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9310 | 9348 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9311 | -#define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ | |
| 9312 | -#define OP_Delete 74 | |
| 9313 | -#define OP_ResetCount 75 | |
| 9349 | +#define OP_Insert 73 /* synopsis: intkey=r[P3] data=r[P2] */ | |
| 9350 | +#define OP_InsertInt 74 /* synopsis: intkey=P3 data=r[P2] */ | |
| 9351 | +#define OP_Delete 75 | |
| 9314 | 9352 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9315 | 9353 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9316 | 9354 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9317 | 9355 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9318 | 9356 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9319 | 9357 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9320 | 9358 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9321 | 9359 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9322 | -#define OP_SorterCompare 84 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ | |
| 9360 | +#define OP_ResetCount 84 | |
| 9323 | 9361 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9324 | 9362 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9325 | 9363 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9326 | 9364 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9327 | 9365 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | ||
| 9328 | 9366 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9329 | 9367 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9330 | 9368 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9331 | 9369 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9332 | 9370 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9333 | -#define OP_SorterData 95 /* synopsis: r[P2]=data */ | |
| 9371 | +#define OP_SorterCompare 95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ | |
| 9334 | 9372 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9335 | 9373 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9336 | -#define OP_RowKey 98 /* synopsis: r[P2]=key */ | |
| 9337 | -#define OP_RowData 99 /* synopsis: r[P2]=data */ | |
| 9338 | -#define OP_Rowid 100 /* synopsis: r[P2]=rowid */ | |
| 9339 | -#define OP_NullRow 101 | |
| 9340 | -#define OP_Last 102 | |
| 9341 | -#define OP_SorterSort 103 | |
| 9342 | -#define OP_Sort 104 | |
| 9343 | -#define OP_Rewind 105 | |
| 9344 | -#define OP_SorterInsert 106 | |
| 9345 | -#define OP_IdxInsert 107 /* synopsis: key=r[P2] */ | |
| 9346 | -#define OP_IdxDelete 108 /* synopsis: key=r[P2@P3] */ | |
| 9347 | -#define OP_IdxRowid 109 /* synopsis: r[P2]=rowid */ | |
| 9348 | -#define OP_IdxLE 110 /* synopsis: key=r[P3@P4] */ | |
| 9349 | -#define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ | |
| 9350 | -#define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ | |
| 9351 | -#define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ | |
| 9352 | -#define OP_Destroy 114 | |
| 9353 | -#define OP_Clear 115 | |
| 9354 | -#define OP_ResetSorter 116 | |
| 9355 | -#define OP_CreateIndex 117 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9356 | -#define OP_CreateTable 118 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9357 | -#define OP_ParseSchema 119 | |
| 9358 | -#define OP_LoadAnalysis 120 | |
| 9359 | -#define OP_DropTable 121 | |
| 9360 | -#define OP_DropIndex 122 | |
| 9361 | -#define OP_DropTrigger 123 | |
| 9362 | -#define OP_IntegrityCk 124 | |
| 9363 | -#define OP_RowSetAdd 125 /* synopsis: rowset(P1)=r[P2] */ | |
| 9364 | -#define OP_RowSetRead 126 /* synopsis: r[P3]=rowset(P1) */ | |
| 9365 | -#define OP_RowSetTest 127 /* synopsis: if r[P3] in rowset(P1) goto P2 */ | |
| 9366 | -#define OP_Program 128 | |
| 9367 | -#define OP_Param 129 | |
| 9368 | -#define OP_FkCounter 130 /* synopsis: fkctr[P1]+=P2 */ | |
| 9369 | -#define OP_FkIfZero 131 /* synopsis: if fkctr[P1]==0 goto P2 */ | |
| 9370 | -#define OP_MemMax 132 /* synopsis: r[P1]=max(r[P1],r[P2]) */ | |
| 9374 | +#define OP_SorterData 98 /* synopsis: r[P2]=data */ | |
| 9375 | +#define OP_RowKey 99 /* synopsis: r[P2]=key */ | |
| 9376 | +#define OP_RowData 100 /* synopsis: r[P2]=data */ | |
| 9377 | +#define OP_Rowid 101 /* synopsis: r[P2]=rowid */ | |
| 9378 | +#define OP_NullRow 102 | |
| 9379 | +#define OP_Last 103 | |
| 9380 | +#define OP_SorterSort 104 | |
| 9381 | +#define OP_Sort 105 | |
| 9382 | +#define OP_Rewind 106 | |
| 9383 | +#define OP_SorterInsert 107 | |
| 9384 | +#define OP_IdxInsert 108 /* synopsis: key=r[P2] */ | |
| 9385 | +#define OP_IdxDelete 109 /* synopsis: key=r[P2@P3] */ | |
| 9386 | +#define OP_IdxRowid 110 /* synopsis: r[P2]=rowid */ | |
| 9387 | +#define OP_IdxLE 111 /* synopsis: key=r[P3@P4] */ | |
| 9388 | +#define OP_IdxGT 112 /* synopsis: key=r[P3@P4] */ | |
| 9389 | +#define OP_IdxLT 113 /* synopsis: key=r[P3@P4] */ | |
| 9390 | +#define OP_IdxGE 114 /* synopsis: key=r[P3@P4] */ | |
| 9391 | +#define OP_Destroy 115 | |
| 9392 | +#define OP_Clear 116 | |
| 9393 | +#define OP_ResetSorter 117 | |
| 9394 | +#define OP_CreateIndex 118 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9395 | +#define OP_CreateTable 119 /* synopsis: r[P2]=root iDb=P1 */ | |
| 9396 | +#define OP_ParseSchema 120 | |
| 9397 | +#define OP_LoadAnalysis 121 | |
| 9398 | +#define OP_DropTable 122 | |
| 9399 | +#define OP_DropIndex 123 | |
| 9400 | +#define OP_DropTrigger 124 | |
| 9401 | +#define OP_IntegrityCk 125 | |
| 9402 | +#define OP_RowSetAdd 126 /* synopsis: rowset(P1)=r[P2] */ | |
| 9403 | +#define OP_RowSetRead 127 /* synopsis: r[P3]=rowset(P1) */ | |
| 9404 | +#define OP_RowSetTest 128 /* synopsis: if r[P3] in rowset(P1) goto P2 */ | |
| 9405 | +#define OP_Program 129 | |
| 9406 | +#define OP_Param 130 | |
| 9407 | +#define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ | |
| 9408 | +#define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ | |
| 9371 | 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9372 | -#define OP_IfPos 134 /* synopsis: if r[P1]>0 goto P2 */ | |
| 9373 | -#define OP_IfNeg 135 /* synopsis: if r[P1]<0 goto P2 */ | |
| 9374 | -#define OP_IfZero 136 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ | |
| 9375 | -#define OP_AggFinal 137 /* synopsis: accum=r[P1] N=P2 */ | |
| 9376 | -#define OP_IncrVacuum 138 | |
| 9377 | -#define OP_Expire 139 | |
| 9378 | -#define OP_TableLock 140 /* synopsis: iDb=P1 root=P2 write=P3 */ | |
| 9379 | -#define OP_VBegin 141 | |
| 9380 | -#define OP_VCreate 142 | |
| 9410 | +#define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ | |
| 9411 | +#define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ | |
| 9412 | +#define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ | |
| 9413 | +#define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ | |
| 9414 | +#define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ | |
| 9415 | +#define OP_IncrVacuum 139 | |
| 9416 | +#define OP_Expire 140 | |
| 9417 | +#define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ | |
| 9418 | +#define OP_VBegin 142 | |
| 9381 | 9419 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9382 | 9420 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9383 | 9421 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9384 | 9422 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9385 | 9423 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9386 | -#define OP_VDestroy 148 | |
| 9387 | -#define OP_VOpen 149 | |
| 9388 | -#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ | |
| 9389 | -#define OP_VNext 151 | |
| 9390 | -#define OP_VRename 152 | |
| 9391 | -#define OP_Pagecount 153 | |
| 9392 | -#define OP_MaxPgcnt 154 | |
| 9393 | -#define OP_Init 155 /* synopsis: Start at P2 */ | |
| 9394 | -#define OP_Noop 156 | |
| 9395 | -#define OP_Explain 157 | |
| 9424 | +#define OP_VCreate 148 | |
| 9425 | +#define OP_VDestroy 149 | |
| 9426 | +#define OP_VOpen 150 | |
| 9427 | +#define OP_VColumn 151 /* synopsis: r[P3]=vcolumn(P2) */ | |
| 9428 | +#define OP_VNext 152 | |
| 9429 | +#define OP_VRename 153 | |
| 9430 | +#define OP_Pagecount 154 | |
| 9431 | +#define OP_MaxPgcnt 155 | |
| 9432 | +#define OP_Init 156 /* synopsis: Start at P2 */ | |
| 9433 | +#define OP_Noop 157 | |
| 9434 | +#define OP_Explain 158 | |
| 9396 | 9435 | |
| 9397 | 9436 | |
| 9398 | 9437 | /* Properties such as "out2" or "jump" that are specified in |
| 9399 | 9438 | ** comments following the "case" for each opcode in the vdbe.c |
| 9400 | 9439 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | ||
| 9412 | 9451 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9413 | 9452 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9414 | 9453 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9415 | 9454 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9416 | 9455 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9417 | -/* 56 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\ | |
| 9418 | -/* 64 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c,\ | |
| 9456 | +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\ | |
| 9457 | +/* 64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\ | |
| 9419 | 9458 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9420 | 9459 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9421 | 9460 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9422 | -/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ | |
| 9423 | -/* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ | |
| 9424 | -/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,\ | |
| 9425 | -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15,\ | |
| 9426 | -/* 128 */ 0x01, 0x02, 0x00, 0x01, 0x08, 0x02, 0x05, 0x05,\ | |
| 9427 | -/* 136 */ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,\ | |
| 9428 | -/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01,\ | |
| 9429 | -/* 152 */ 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} | |
| 9461 | +/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ | |
| 9462 | +/* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\ | |
| 9463 | +/* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\ | |
| 9464 | +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ | |
| 9465 | +/* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\ | |
| 9466 | +/* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\ | |
| 9467 | +/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\ | |
| 9468 | +/* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} | |
| 9430 | 9469 | |
| 9431 | 9470 | /************** End of opcodes.h *********************************************/ |
| 9432 | 9471 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9433 | 9472 | |
| 9434 | 9473 | /* |
| @@ -10932,10 +10971,13 @@ | ||
| 10932 | 10971 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10933 | 10972 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10934 | 10973 | i16 nCol; /* Number of columns in this table */ |
| 10935 | 10974 | u16 nRef; /* Number of pointers to this Table */ |
| 10936 | 10975 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10976 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 10977 | + LogEst costMult; /* Cost multiplier for using this table */ | |
| 10978 | +#endif | |
| 10937 | 10979 | u8 tabFlags; /* Mask of TF_* values */ |
| 10938 | 10980 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10939 | 10981 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10940 | 10982 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10941 | 10983 | #endif |
| @@ -11591,10 +11633,11 @@ | ||
| 11591 | 11633 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11592 | 11634 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11593 | 11635 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11594 | 11636 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11595 | 11637 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11638 | +#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ | |
| 11596 | 11639 | |
| 11597 | 11640 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11598 | 11641 | */ |
| 11599 | 11642 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11600 | 11643 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | ||
| 11847 | 11890 | |
| 11848 | 11891 | /* |
| 11849 | 11892 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11850 | 11893 | */ |
| 11851 | 11894 | #if SQLITE_MAX_ATTACHED>30 |
| 11852 | - typedef sqlite3_uint64 yDbMask; | |
| 11895 | + typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; | |
| 11896 | +# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) | |
| 11897 | +# define DbMaskZero(M) memset((M),0,sizeof(M)) | |
| 11898 | +# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) | |
| 11899 | +# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) | |
| 11900 | +# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) | |
| 11853 | 11901 | #else |
| 11854 | 11902 | typedef unsigned int yDbMask; |
| 11903 | +# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) | |
| 11904 | +# define DbMaskZero(M) (M)=0 | |
| 11905 | +# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) | |
| 11906 | +# define DbMaskAllZero(M) (M)==0 | |
| 11907 | +# define DbMaskNonZero(M) (M)!=0 | |
| 11855 | 11908 | #endif |
| 11856 | 11909 | |
| 11857 | 11910 | /* |
| 11858 | 11911 | ** An SQL parser context. A copy of this structure is passed through |
| 11859 | 11912 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | ||
| 12522 | 12575 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12523 | 12576 | #else |
| 12524 | 12577 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12525 | 12578 | #endif |
| 12526 | 12579 | |
| 12580 | +#if SQLITE_MAX_ATTACHED>30 | |
| 12581 | +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); | |
| 12582 | +#endif | |
| 12527 | 12583 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12528 | 12584 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12529 | 12585 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12530 | 12586 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12531 | 12587 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | ||
| 12772 | 12828 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12773 | 12829 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12774 | 12830 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12775 | 12831 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12776 | 12832 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12833 | +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); | |
| 12777 | 12834 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12778 | 12835 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12779 | 12836 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12780 | 12837 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12781 | 12838 | |
| @@ -12801,11 +12858,11 @@ | ||
| 12801 | 12858 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12802 | 12859 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12803 | 12860 | #else |
| 12804 | 12861 | # define sqlite3FileSuffix3(X,Y) |
| 12805 | 12862 | #endif |
| 12806 | -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int); | |
| 12863 | +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); | |
| 12807 | 12864 | |
| 12808 | 12865 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12809 | 12866 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12810 | 12867 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12811 | 12868 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | ||
| 13876 | 13933 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13877 | 13934 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13878 | 13935 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13879 | 13936 | i16 nField; /* Number of fields in the header */ |
| 13880 | 13937 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13938 | +#ifdef SQLITE_DEBUG | |
| 13939 | + u8 seekOp; /* Most recent seek operation on this cursor */ | |
| 13940 | +#endif | |
| 13881 | 13941 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13882 | 13942 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13883 | 13943 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13884 | 13944 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13885 | 13945 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13886 | 13946 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13887 | 13947 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13888 | 13948 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13949 | + Pgno pgnoRoot; /* Root page of the open btree cursor */ | |
| 13889 | 13950 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13890 | 13951 | i64 seqCount; /* Sequence counter */ |
| 13891 | 13952 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13892 | 13953 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13893 | 13954 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | ||
| 18396 | 18457 | /* |
| 18397 | 18458 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18398 | 18459 | */ |
| 18399 | 18460 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18400 | 18461 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18401 | - if( sqlite3_initialize() ) return 0; | |
| 18462 | + if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; | |
| 18402 | 18463 | #endif |
| 18403 | 18464 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18404 | 18465 | } |
| 18405 | 18466 | |
| 18406 | 18467 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | ||
| 18577 | 18638 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18578 | 18639 | ** mutex and returns a pointer to it. If it returns NULL |
| 18579 | 18640 | ** that means that a mutex could not be allocated. |
| 18580 | 18641 | */ |
| 18581 | 18642 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18582 | - static sqlite3_debug_mutex aStatic[6]; | |
| 18643 | + static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1]; | |
| 18583 | 18644 | sqlite3_debug_mutex *pNew = 0; |
| 18584 | 18645 | switch( id ){ |
| 18585 | 18646 | case SQLITE_MUTEX_FAST: |
| 18586 | 18647 | case SQLITE_MUTEX_RECURSIVE: { |
| 18587 | 18648 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | ||
| 18774 | 18835 | ** <ul> |
| 18775 | 18836 | ** <li> SQLITE_MUTEX_FAST |
| 18776 | 18837 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18777 | 18838 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18778 | 18839 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18779 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 18840 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 18780 | 18841 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18781 | 18842 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18782 | 18843 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18844 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 18845 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 18846 | +** <li> SQLITE_MUTEX_STATIC_APP3 | |
| 18783 | 18847 | ** </ul> |
| 18784 | 18848 | ** |
| 18785 | 18849 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18786 | 18850 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18787 | 18851 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | ||
| 18806 | 18870 | ** mutex types, the same mutex is returned on every call that has |
| 18807 | 18871 | ** the same type number. |
| 18808 | 18872 | */ |
| 18809 | 18873 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18810 | 18874 | static sqlite3_mutex staticMutexes[] = { |
| 18875 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18876 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18877 | + SQLITE3_MUTEX_INITIALIZER, | |
| 18811 | 18878 | SQLITE3_MUTEX_INITIALIZER, |
| 18812 | 18879 | SQLITE3_MUTEX_INITIALIZER, |
| 18813 | 18880 | SQLITE3_MUTEX_INITIALIZER, |
| 18814 | 18881 | SQLITE3_MUTEX_INITIALIZER, |
| 18815 | 18882 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | ||
| 19041 | 19108 | ** May you do good and not evil. |
| 19042 | 19109 | ** May you find forgiveness for yourself and forgive others. |
| 19043 | 19110 | ** May you share freely, never taking more than you give. |
| 19044 | 19111 | ** |
| 19045 | 19112 | ************************************************************************* |
| 19046 | -** This file contains the C functions that implement mutexes for win32 | |
| 19113 | +** This file contains the C functions that implement mutexes for Win32. | |
| 19047 | 19114 | */ |
| 19048 | 19115 | |
| 19049 | 19116 | #if SQLITE_OS_WIN |
| 19117 | +/* | |
| 19118 | +** Include code that is common to all os_*.c files | |
| 19119 | +*/ | |
| 19120 | +/************** Include os_common.h in the middle of mutex_w32.c *************/ | |
| 19121 | +/************** Begin file os_common.h ***************************************/ | |
| 19122 | +/* | |
| 19123 | +** 2004 May 22 | |
| 19124 | +** | |
| 19125 | +** The author disclaims copyright to this source code. In place of | |
| 19126 | +** a legal notice, here is a blessing: | |
| 19127 | +** | |
| 19128 | +** May you do good and not evil. | |
| 19129 | +** May you find forgiveness for yourself and forgive others. | |
| 19130 | +** May you share freely, never taking more than you give. | |
| 19131 | +** | |
| 19132 | +****************************************************************************** | |
| 19133 | +** | |
| 19134 | +** This file contains macros and a little bit of code that is common to | |
| 19135 | +** all of the platform-specific files (os_*.c) and is #included into those | |
| 19136 | +** files. | |
| 19137 | +** | |
| 19138 | +** This file should be #included by the os_*.c files only. It is not a | |
| 19139 | +** general purpose header file. | |
| 19140 | +*/ | |
| 19141 | +#ifndef _OS_COMMON_H_ | |
| 19142 | +#define _OS_COMMON_H_ | |
| 19143 | + | |
| 19144 | +/* | |
| 19145 | +** At least two bugs have slipped in because we changed the MEMORY_DEBUG | |
| 19146 | +** macro to SQLITE_DEBUG and some older makefiles have not yet made the | |
| 19147 | +** switch. The following code should catch this problem at compile-time. | |
| 19148 | +*/ | |
| 19149 | +#ifdef MEMORY_DEBUG | |
| 19150 | +# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." | |
| 19151 | +#endif | |
| 19152 | + | |
| 19153 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | |
| 19154 | +# ifndef SQLITE_DEBUG_OS_TRACE | |
| 19155 | +# define SQLITE_DEBUG_OS_TRACE 0 | |
| 19156 | +# endif | |
| 19157 | + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; | |
| 19158 | +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X | |
| 19159 | +#else | |
| 19160 | +# define OSTRACE(X) | |
| 19161 | +#endif | |
| 19162 | + | |
| 19163 | +/* | |
| 19164 | +** Macros for performance tracing. Normally turned off. Only works | |
| 19165 | +** on i486 hardware. | |
| 19166 | +*/ | |
| 19167 | +#ifdef SQLITE_PERFORMANCE_TRACE | |
| 19168 | + | |
| 19169 | +/* | |
| 19170 | +** hwtime.h contains inline assembler code for implementing | |
| 19171 | +** high-performance timing routines. | |
| 19172 | +*/ | |
| 19173 | +/************** Include hwtime.h in the middle of os_common.h ****************/ | |
| 19174 | +/************** Begin file hwtime.h ******************************************/ | |
| 19175 | +/* | |
| 19176 | +** 2008 May 27 | |
| 19177 | +** | |
| 19178 | +** The author disclaims copyright to this source code. In place of | |
| 19179 | +** a legal notice, here is a blessing: | |
| 19180 | +** | |
| 19181 | +** May you do good and not evil. | |
| 19182 | +** May you find forgiveness for yourself and forgive others. | |
| 19183 | +** May you share freely, never taking more than you give. | |
| 19184 | +** | |
| 19185 | +****************************************************************************** | |
| 19186 | +** | |
| 19187 | +** This file contains inline asm code for retrieving "high-performance" | |
| 19188 | +** counters for x86 class CPUs. | |
| 19189 | +*/ | |
| 19190 | +#ifndef _HWTIME_H_ | |
| 19191 | +#define _HWTIME_H_ | |
| 19192 | + | |
| 19193 | +/* | |
| 19194 | +** The following routine only works on pentium-class (or newer) processors. | |
| 19195 | +** It uses the RDTSC opcode to read the cycle count value out of the | |
| 19196 | +** processor and returns that value. This can be used for high-res | |
| 19197 | +** profiling. | |
| 19198 | +*/ | |
| 19199 | +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ | |
| 19200 | + (defined(i386) || defined(__i386__) || defined(_M_IX86)) | |
| 19201 | + | |
| 19202 | + #if defined(__GNUC__) | |
| 19203 | + | |
| 19204 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19205 | + unsigned int lo, hi; | |
| 19206 | + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | |
| 19207 | + return (sqlite_uint64)hi << 32 | lo; | |
| 19208 | + } | |
| 19209 | + | |
| 19210 | + #elif defined(_MSC_VER) | |
| 19211 | + | |
| 19212 | + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | |
| 19213 | + __asm { | |
| 19214 | + rdtsc | |
| 19215 | + ret ; return value at EDX:EAX | |
| 19216 | + } | |
| 19217 | + } | |
| 19218 | + | |
| 19219 | + #endif | |
| 19220 | + | |
| 19221 | +#elif (defined(__GNUC__) && defined(__x86_64__)) | |
| 19222 | + | |
| 19223 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19224 | + unsigned long val; | |
| 19225 | + __asm__ __volatile__ ("rdtsc" : "=A" (val)); | |
| 19226 | + return val; | |
| 19227 | + } | |
| 19228 | + | |
| 19229 | +#elif (defined(__GNUC__) && defined(__ppc__)) | |
| 19230 | + | |
| 19231 | + __inline__ sqlite_uint64 sqlite3Hwtime(void){ | |
| 19232 | + unsigned long long retval; | |
| 19233 | + unsigned long junk; | |
| 19234 | + __asm__ __volatile__ ("\n\ | |
| 19235 | + 1: mftbu %1\n\ | |
| 19236 | + mftb %L0\n\ | |
| 19237 | + mftbu %0\n\ | |
| 19238 | + cmpw %0,%1\n\ | |
| 19239 | + bne 1b" | |
| 19240 | + : "=r" (retval), "=r" (junk)); | |
| 19241 | + return retval; | |
| 19242 | + } | |
| 19243 | + | |
| 19244 | +#else | |
| 19245 | + | |
| 19246 | + #error Need implementation of sqlite3Hwtime() for your platform. | |
| 19247 | + | |
| 19248 | + /* | |
| 19249 | + ** To compile without implementing sqlite3Hwtime() for your platform, | |
| 19250 | + ** you can remove the above #error and use the following | |
| 19251 | + ** stub function. You will lose timing support for many | |
| 19252 | + ** of the debugging and testing utilities, but it should at | |
| 19253 | + ** least compile and run. | |
| 19254 | + */ | |
| 19255 | +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | |
| 19256 | + | |
| 19257 | +#endif | |
| 19258 | + | |
| 19259 | +#endif /* !defined(_HWTIME_H_) */ | |
| 19260 | + | |
| 19261 | +/************** End of hwtime.h **********************************************/ | |
| 19262 | +/************** Continuing where we left off in os_common.h ******************/ | |
| 19263 | + | |
| 19264 | +static sqlite_uint64 g_start; | |
| 19265 | +static sqlite_uint64 g_elapsed; | |
| 19266 | +#define TIMER_START g_start=sqlite3Hwtime() | |
| 19267 | +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start | |
| 19268 | +#define TIMER_ELAPSED g_elapsed | |
| 19269 | +#else | |
| 19270 | +#define TIMER_START | |
| 19271 | +#define TIMER_END | |
| 19272 | +#define TIMER_ELAPSED ((sqlite_uint64)0) | |
| 19273 | +#endif | |
| 19274 | + | |
| 19275 | +/* | |
| 19276 | +** If we compile with the SQLITE_TEST macro set, then the following block | |
| 19277 | +** of code will give us the ability to simulate a disk I/O error. This | |
| 19278 | +** is used for testing the I/O recovery logic. | |
| 19279 | +*/ | |
| 19280 | +#ifdef SQLITE_TEST | |
| 19281 | +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ | |
| 19282 | +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ | |
| 19283 | +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ | |
| 19284 | +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ | |
| 19285 | +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ | |
| 19286 | +SQLITE_API int sqlite3_diskfull_pending = 0; | |
| 19287 | +SQLITE_API int sqlite3_diskfull = 0; | |
| 19288 | +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) | |
| 19289 | +#define SimulateIOError(CODE) \ | |
| 19290 | + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ | |
| 19291 | + || sqlite3_io_error_pending-- == 1 ) \ | |
| 19292 | + { local_ioerr(); CODE; } | |
| 19293 | +static void local_ioerr(){ | |
| 19294 | + IOTRACE(("IOERR\n")); | |
| 19295 | + sqlite3_io_error_hit++; | |
| 19296 | + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; | |
| 19297 | +} | |
| 19298 | +#define SimulateDiskfullError(CODE) \ | |
| 19299 | + if( sqlite3_diskfull_pending ){ \ | |
| 19300 | + if( sqlite3_diskfull_pending == 1 ){ \ | |
| 19301 | + local_ioerr(); \ | |
| 19302 | + sqlite3_diskfull = 1; \ | |
| 19303 | + sqlite3_io_error_hit = 1; \ | |
| 19304 | + CODE; \ | |
| 19305 | + }else{ \ | |
| 19306 | + sqlite3_diskfull_pending--; \ | |
| 19307 | + } \ | |
| 19308 | + } | |
| 19309 | +#else | |
| 19310 | +#define SimulateIOErrorBenign(X) | |
| 19311 | +#define SimulateIOError(A) | |
| 19312 | +#define SimulateDiskfullError(A) | |
| 19313 | +#endif | |
| 19314 | + | |
| 19315 | +/* | |
| 19316 | +** When testing, keep a count of the number of open files. | |
| 19317 | +*/ | |
| 19318 | +#ifdef SQLITE_TEST | |
| 19319 | +SQLITE_API int sqlite3_open_file_count = 0; | |
| 19320 | +#define OpenCounter(X) sqlite3_open_file_count+=(X) | |
| 19321 | +#else | |
| 19322 | +#define OpenCounter(X) | |
| 19323 | +#endif | |
| 19324 | + | |
| 19325 | +#endif /* !defined(_OS_COMMON_H_) */ | |
| 19326 | + | |
| 19327 | +/************** End of os_common.h *******************************************/ | |
| 19328 | +/************** Continuing where we left off in mutex_w32.c ******************/ | |
| 19329 | + | |
| 19050 | 19330 | /* |
| 19051 | 19331 | ** Include the header file for the Windows VFS. |
| 19052 | 19332 | */ |
| 19053 | 19333 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19054 | 19334 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | ||
| 19124 | 19404 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19125 | 19405 | #endif |
| 19126 | 19406 | |
| 19127 | 19407 | /* |
| 19128 | 19408 | ** The code in this file is only used if we are compiling multithreaded |
| 19129 | -** on a win32 system. | |
| 19409 | +** on a Win32 system. | |
| 19130 | 19410 | */ |
| 19131 | 19411 | #ifdef SQLITE_MUTEX_W32 |
| 19132 | 19412 | |
| 19133 | 19413 | /* |
| 19134 | 19414 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | ||
| 19137 | 19417 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19138 | 19418 | int id; /* Mutex type */ |
| 19139 | 19419 | #ifdef SQLITE_DEBUG |
| 19140 | 19420 | volatile int nRef; /* Number of enterances */ |
| 19141 | 19421 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19142 | - int trace; /* True to trace changes */ | |
| 19422 | + volatile int trace; /* True to trace changes */ | |
| 19143 | 19423 | #endif |
| 19144 | 19424 | }; |
| 19425 | + | |
| 19426 | +/* | |
| 19427 | +** These are the initializer values used when declaring a "static" mutex | |
| 19428 | +** on Win32. It should be noted that all mutexes require initialization | |
| 19429 | +** on the Win32 platform. | |
| 19430 | +*/ | |
| 19145 | 19431 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19432 | + | |
| 19146 | 19433 | #ifdef SQLITE_DEBUG |
| 19147 | -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } | |
| 19434 | +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ | |
| 19435 | + 0L, (DWORD)0, 0 } | |
| 19148 | 19436 | #else |
| 19149 | 19437 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19150 | 19438 | #endif |
| 19151 | 19439 | |
| 19152 | -/* | |
| 19153 | -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, | |
| 19154 | -** or WinCE. Return false (zero) for Win95, Win98, or WinME. | |
| 19155 | -** | |
| 19156 | -** Here is an interesting observation: Win95, Win98, and WinME lack | |
| 19157 | -** the LockFileEx() API. But we can still statically link against that | |
| 19158 | -** API as long as we don't call it win running Win95/98/ME. A call to | |
| 19159 | -** this routine is used to determine if the host is Win95/98/ME or | |
| 19160 | -** WinNT/2K/XP so that we will know whether or not we can safely call | |
| 19161 | -** the LockFileEx() API. | |
| 19162 | -** | |
| 19163 | -** mutexIsNT() is only used for the TryEnterCriticalSection() API call, | |
| 19164 | -** which is only available if your application was compiled with | |
| 19165 | -** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only | |
| 19166 | -** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef | |
| 19167 | -** this out as well. | |
| 19168 | -*/ | |
| 19169 | -#if 0 | |
| 19170 | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT | |
| 19171 | -# define mutexIsNT() (1) | |
| 19172 | -#else | |
| 19173 | - static int mutexIsNT(void){ | |
| 19174 | - static int osType = 0; | |
| 19175 | - if( osType==0 ){ | |
| 19176 | - OSVERSIONINFO sInfo; | |
| 19177 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 19178 | - GetVersionEx(&sInfo); | |
| 19179 | - osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; | |
| 19180 | - } | |
| 19181 | - return osType==2; | |
| 19182 | - } | |
| 19183 | -#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ | |
| 19184 | -#endif | |
| 19185 | - | |
| 19186 | 19440 | #ifdef SQLITE_DEBUG |
| 19187 | 19441 | /* |
| 19188 | 19442 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19189 | 19443 | ** intended for use only inside assert() statements. |
| 19190 | 19444 | */ |
| 19191 | 19445 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19192 | 19446 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19193 | 19447 | } |
| 19448 | + | |
| 19194 | 19449 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19195 | 19450 | return p->nRef==0 || p->owner!=tid; |
| 19196 | 19451 | } |
| 19452 | + | |
| 19197 | 19453 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19198 | - DWORD tid = GetCurrentThreadId(); | |
| 19454 | + DWORD tid = GetCurrentThreadId(); | |
| 19199 | 19455 | return winMutexNotheld2(p, tid); |
| 19200 | 19456 | } |
| 19201 | 19457 | #endif |
| 19202 | 19458 | |
| 19203 | - | |
| 19204 | 19459 | /* |
| 19205 | 19460 | ** Initialize and deinitialize the mutex subsystem. |
| 19206 | 19461 | */ |
| 19207 | -static sqlite3_mutex winMutex_staticMutexes[6] = { | |
| 19462 | +static sqlite3_mutex winMutex_staticMutexes[] = { | |
| 19463 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19464 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19465 | + SQLITE3_MUTEX_INITIALIZER, | |
| 19208 | 19466 | SQLITE3_MUTEX_INITIALIZER, |
| 19209 | 19467 | SQLITE3_MUTEX_INITIALIZER, |
| 19210 | 19468 | SQLITE3_MUTEX_INITIALIZER, |
| 19211 | 19469 | SQLITE3_MUTEX_INITIALIZER, |
| 19212 | 19470 | SQLITE3_MUTEX_INITIALIZER, |
| 19213 | 19471 | SQLITE3_MUTEX_INITIALIZER |
| 19214 | 19472 | }; |
| 19473 | + | |
| 19215 | 19474 | static int winMutex_isInit = 0; |
| 19216 | -/* As winMutexInit() and winMutexEnd() are called as part | |
| 19217 | -** of the sqlite3_initialize and sqlite3_shutdown() | |
| 19218 | -** processing, the "interlocked" magic is probably not | |
| 19219 | -** strictly necessary. | |
| 19475 | +static int winMutex_isNt = -1; /* <0 means "need to query" */ | |
| 19476 | + | |
| 19477 | +/* As the winMutexInit() and winMutexEnd() functions are called as part | |
| 19478 | +** of the sqlite3_initialize() and sqlite3_shutdown() processing, the | |
| 19479 | +** "interlocked" magic used here is probably not strictly necessary. | |
| 19220 | 19480 | */ |
| 19221 | -static LONG winMutex_lock = 0; | |
| 19481 | +static LONG volatile winMutex_lock = 0; | |
| 19222 | 19482 | |
| 19483 | +SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ | |
| 19223 | 19484 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19224 | 19485 | |
| 19225 | -static int winMutexInit(void){ | |
| 19486 | +static int winMutexInit(void){ | |
| 19226 | 19487 | /* The first to increment to 1 does actual initialization */ |
| 19227 | 19488 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19228 | 19489 | int i; |
| 19229 | 19490 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19230 | 19491 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | ||
| 19233 | 19494 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19234 | 19495 | #endif |
| 19235 | 19496 | } |
| 19236 | 19497 | winMutex_isInit = 1; |
| 19237 | 19498 | }else{ |
| 19238 | - /* Someone else is in the process of initing the static mutexes */ | |
| 19499 | + /* Another thread is (in the process of) initializing the static | |
| 19500 | + ** mutexes */ | |
| 19239 | 19501 | while( !winMutex_isInit ){ |
| 19240 | 19502 | sqlite3_win32_sleep(1); |
| 19241 | 19503 | } |
| 19242 | 19504 | } |
| 19243 | - return SQLITE_OK; | |
| 19505 | + return SQLITE_OK; | |
| 19244 | 19506 | } |
| 19245 | 19507 | |
| 19246 | -static int winMutexEnd(void){ | |
| 19247 | - /* The first to decrement to 0 does actual shutdown | |
| 19508 | +static int winMutexEnd(void){ | |
| 19509 | + /* The first to decrement to 0 does actual shutdown | |
| 19248 | 19510 | ** (which should be the last to shutdown.) */ |
| 19249 | 19511 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19250 | 19512 | if( winMutex_isInit==1 ){ |
| 19251 | 19513 | int i; |
| 19252 | 19514 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | ||
| 19253 | 19515 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19254 | 19516 | } |
| 19255 | 19517 | winMutex_isInit = 0; |
| 19256 | 19518 | } |
| 19257 | 19519 | } |
| 19258 | - return SQLITE_OK; | |
| 19520 | + return SQLITE_OK; | |
| 19259 | 19521 | } |
| 19260 | 19522 | |
| 19261 | 19523 | /* |
| 19262 | 19524 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19263 | 19525 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | ||
| 19268 | 19530 | ** <ul> |
| 19269 | 19531 | ** <li> SQLITE_MUTEX_FAST |
| 19270 | 19532 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19271 | 19533 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19272 | 19534 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19273 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 19535 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 19274 | 19536 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19275 | 19537 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19276 | 19538 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19539 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 19540 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 19541 | +** <li> SQLITE_MUTEX_STATIC_APP3 | |
| 19277 | 19542 | ** </ul> |
| 19278 | 19543 | ** |
| 19279 | 19544 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19280 | 19545 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19281 | 19546 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | ||
| 19294 | 19559 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19295 | 19560 | ** SQLITE_MUTEX_RECURSIVE. |
| 19296 | 19561 | ** |
| 19297 | 19562 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19298 | 19563 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19299 | -** returns a different mutex on every call. But for the static | |
| 19564 | +** returns a different mutex on every call. But for the static | |
| 19300 | 19565 | ** mutex types, the same mutex is returned on every call that has |
| 19301 | 19566 | ** the same type number. |
| 19302 | 19567 | */ |
| 19303 | 19568 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19304 | 19569 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | ||
| 19305 | 19570 | |
| 19306 | 19571 | switch( iType ){ |
| 19307 | 19572 | case SQLITE_MUTEX_FAST: |
| 19308 | 19573 | case SQLITE_MUTEX_RECURSIVE: { |
| 19309 | 19574 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19310 | - if( p ){ | |
| 19575 | + if( p ){ | |
| 19311 | 19576 | #ifdef SQLITE_DEBUG |
| 19312 | 19577 | p->id = iType; |
| 19578 | +#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC | |
| 19579 | + p->trace = 1; | |
| 19580 | +#endif | |
| 19313 | 19581 | #endif |
| 19314 | 19582 | #if SQLITE_OS_WINRT |
| 19315 | 19583 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19316 | 19584 | #else |
| 19317 | 19585 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | ||
| 19318 | 19586 | #endif |
| 19319 | 19587 | } |
| 19320 | 19588 | break; |
| 19321 | 19589 | } |
| 19322 | 19590 | default: { |
| 19323 | - assert( winMutex_isInit==1 ); | |
| 19324 | 19591 | assert( iType-2 >= 0 ); |
| 19325 | 19592 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19593 | + assert( winMutex_isInit==1 ); | |
| 19326 | 19594 | p = &winMutex_staticMutexes[iType-2]; |
| 19327 | 19595 | #ifdef SQLITE_DEBUG |
| 19328 | 19596 | p->id = iType; |
| 19597 | +#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC | |
| 19598 | + p->trace = 1; | |
| 19599 | +#endif | |
| 19329 | 19600 | #endif |
| 19330 | 19601 | break; |
| 19331 | 19602 | } |
| 19332 | 19603 | } |
| 19333 | 19604 | return p; |
| @@ -19339,12 +19610,15 @@ | ||
| 19339 | 19610 | ** allocated mutex. SQLite is careful to deallocate every |
| 19340 | 19611 | ** mutex that it allocates. |
| 19341 | 19612 | */ |
| 19342 | 19613 | static void winMutexFree(sqlite3_mutex *p){ |
| 19343 | 19614 | assert( p ); |
| 19615 | +#ifdef SQLITE_DEBUG | |
| 19344 | 19616 | assert( p->nRef==0 && p->owner==0 ); |
| 19345 | 19617 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19618 | +#endif | |
| 19619 | + assert( winMutex_isInit==1 ); | |
| 19346 | 19620 | DeleteCriticalSection(&p->mutex); |
| 19347 | 19621 | sqlite3_free(p); |
| 19348 | 19622 | } |
| 19349 | 19623 | |
| 19350 | 19624 | /* |
| @@ -19357,53 +19631,71 @@ | ||
| 19357 | 19631 | ** mutex must be exited an equal number of times before another thread |
| 19358 | 19632 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19359 | 19633 | ** more than once, the behavior is undefined. |
| 19360 | 19634 | */ |
| 19361 | 19635 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19636 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19637 | + DWORD tid = GetCurrentThreadId(); | |
| 19638 | +#endif | |
| 19362 | 19639 | #ifdef SQLITE_DEBUG |
| 19363 | - DWORD tid = GetCurrentThreadId(); | |
| 19640 | + assert( p ); | |
| 19364 | 19641 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19642 | +#else | |
| 19643 | + assert( p ); | |
| 19365 | 19644 | #endif |
| 19645 | + assert( winMutex_isInit==1 ); | |
| 19366 | 19646 | EnterCriticalSection(&p->mutex); |
| 19367 | 19647 | #ifdef SQLITE_DEBUG |
| 19368 | 19648 | assert( p->nRef>0 || p->owner==0 ); |
| 19369 | - p->owner = tid; | |
| 19649 | + p->owner = tid; | |
| 19370 | 19650 | p->nRef++; |
| 19371 | 19651 | if( p->trace ){ |
| 19372 | - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19652 | + OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", | |
| 19653 | + tid, p, p->trace, p->nRef)); | |
| 19373 | 19654 | } |
| 19374 | 19655 | #endif |
| 19375 | 19656 | } |
| 19657 | + | |
| 19376 | 19658 | static int winMutexTry(sqlite3_mutex *p){ |
| 19377 | -#ifndef NDEBUG | |
| 19378 | - DWORD tid = GetCurrentThreadId(); | |
| 19659 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19660 | + DWORD tid = GetCurrentThreadId(); | |
| 19379 | 19661 | #endif |
| 19380 | 19662 | int rc = SQLITE_BUSY; |
| 19663 | + assert( p ); | |
| 19381 | 19664 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19382 | 19665 | /* |
| 19383 | 19666 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19384 | 19667 | ** is used it is merely an optimization. So it is OK for it to always |
| 19385 | - ** fail. | |
| 19668 | + ** fail. | |
| 19386 | 19669 | ** |
| 19387 | 19670 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19388 | 19671 | ** And some windows compilers complain if you try to use it without |
| 19389 | 19672 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19390 | 19673 | ** For that reason, we will omit this optimization for now. See |
| 19391 | 19674 | ** ticket #2685. |
| 19392 | 19675 | */ |
| 19393 | -#if 0 | |
| 19394 | - if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ | |
| 19676 | +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 | |
| 19677 | + assert( winMutex_isInit==1 ); | |
| 19678 | + assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); | |
| 19679 | + if( winMutex_isNt<0 ){ | |
| 19680 | + winMutex_isNt = sqlite3_win32_is_nt(); | |
| 19681 | + } | |
| 19682 | + assert( winMutex_isNt==0 || winMutex_isNt==1 ); | |
| 19683 | + if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ | |
| 19684 | +#ifdef SQLITE_DEBUG | |
| 19395 | 19685 | p->owner = tid; |
| 19396 | 19686 | p->nRef++; |
| 19687 | +#endif | |
| 19397 | 19688 | rc = SQLITE_OK; |
| 19398 | 19689 | } |
| 19399 | 19690 | #else |
| 19400 | 19691 | UNUSED_PARAMETER(p); |
| 19401 | 19692 | #endif |
| 19402 | 19693 | #ifdef SQLITE_DEBUG |
| 19403 | - if( rc==SQLITE_OK && p->trace ){ | |
| 19404 | - printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19694 | + if( p->trace ){ | |
| 19695 | + OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", | |
| 19696 | + tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); | |
| 19405 | 19697 | } |
| 19406 | 19698 | #endif |
| 19407 | 19699 | return rc; |
| 19408 | 19700 | } |
| 19409 | 19701 | |
| @@ -19412,22 +19704,27 @@ | ||
| 19412 | 19704 | ** previously entered by the same thread. The behavior |
| 19413 | 19705 | ** is undefined if the mutex is not currently entered or |
| 19414 | 19706 | ** is not currently allocated. SQLite will never do either. |
| 19415 | 19707 | */ |
| 19416 | 19708 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19417 | -#ifndef NDEBUG | |
| 19709 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 19418 | 19710 | DWORD tid = GetCurrentThreadId(); |
| 19711 | +#endif | |
| 19712 | + assert( p ); | |
| 19713 | +#ifdef SQLITE_DEBUG | |
| 19419 | 19714 | assert( p->nRef>0 ); |
| 19420 | 19715 | assert( p->owner==tid ); |
| 19421 | 19716 | p->nRef--; |
| 19422 | 19717 | if( p->nRef==0 ) p->owner = 0; |
| 19423 | 19718 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19424 | 19719 | #endif |
| 19720 | + assert( winMutex_isInit==1 ); | |
| 19425 | 19721 | LeaveCriticalSection(&p->mutex); |
| 19426 | 19722 | #ifdef SQLITE_DEBUG |
| 19427 | 19723 | if( p->trace ){ |
| 19428 | - printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 19724 | + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", | |
| 19725 | + tid, p, p->trace, p->nRef)); | |
| 19429 | 19726 | } |
| 19430 | 19727 | #endif |
| 19431 | 19728 | } |
| 19432 | 19729 | |
| 19433 | 19730 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | ||
| 19445 | 19742 | #else |
| 19446 | 19743 | 0, |
| 19447 | 19744 | 0 |
| 19448 | 19745 | #endif |
| 19449 | 19746 | }; |
| 19450 | - | |
| 19451 | 19747 | return &sMutex; |
| 19452 | 19748 | } |
| 19749 | + | |
| 19453 | 19750 | #endif /* SQLITE_MUTEX_W32 */ |
| 19454 | 19751 | |
| 19455 | 19752 | /************** End of mutex_w32.c *******************************************/ |
| 19456 | 19753 | /************** Begin file malloc.c ******************************************/ |
| 19457 | 19754 | /* |
| @@ -22422,13 +22719,13 @@ | ||
| 22422 | 22719 | testcase( c==(+1) ); |
| 22423 | 22720 | } |
| 22424 | 22721 | return c; |
| 22425 | 22722 | } |
| 22426 | 22723 | |
| 22427 | - | |
| 22428 | 22724 | /* |
| 22429 | -** Convert zNum to a 64-bit signed integer. | |
| 22725 | +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This | |
| 22726 | +** routine does *not* accept hexadecimal notation. | |
| 22430 | 22727 | ** |
| 22431 | 22728 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22432 | 22729 | ** integer, then write that value into *pNum and return 0. |
| 22433 | 22730 | ** |
| 22434 | 22731 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | ||
| 22511 | 22808 | assert( u-1==LARGEST_INT64 ); |
| 22512 | 22809 | return neg ? 0 : 2; |
| 22513 | 22810 | } |
| 22514 | 22811 | } |
| 22515 | 22812 | } |
| 22813 | + | |
| 22814 | +/* | |
| 22815 | +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, | |
| 22816 | +** into a 64-bit signed integer. This routine accepts hexadecimal literals, | |
| 22817 | +** whereas sqlite3Atoi64() does not. | |
| 22818 | +** | |
| 22819 | +** Returns: | |
| 22820 | +** | |
| 22821 | +** 0 Successful transformation. Fits in a 64-bit signed integer. | |
| 22822 | +** 1 Integer too large for a 64-bit signed integer or is malformed | |
| 22823 | +** 2 Special case of 9223372036854775808 | |
| 22824 | +*/ | |
| 22825 | +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ | |
| 22826 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 22827 | + if( z[0]=='0' | |
| 22828 | + && (z[1]=='x' || z[1]=='X') | |
| 22829 | + && sqlite3Isxdigit(z[2]) | |
| 22830 | + ){ | |
| 22831 | + u64 u = 0; | |
| 22832 | + int i, k; | |
| 22833 | + for(i=2; z[i]=='0'; i++){} | |
| 22834 | + for(k=i; sqlite3Isxdigit(z[k]); k++){ | |
| 22835 | + u = u*16 + sqlite3HexToInt(z[k]); | |
| 22836 | + } | |
| 22837 | + memcpy(pOut, &u, 8); | |
| 22838 | + return (z[k]==0 && k-i<=16) ? 0 : 1; | |
| 22839 | + }else | |
| 22840 | +#endif /* SQLITE_OMIT_HEX_INTEGER */ | |
| 22841 | + { | |
| 22842 | + return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); | |
| 22843 | + } | |
| 22844 | +} | |
| 22516 | 22845 | |
| 22517 | 22846 | /* |
| 22518 | 22847 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22519 | 22848 | ** *pValue to that integer and return true. Otherwise return false. |
| 22849 | +** | |
| 22850 | +** This routine accepts both decimal and hexadecimal notation for integers. | |
| 22520 | 22851 | ** |
| 22521 | 22852 | ** Any non-numeric characters that following zNum are ignored. |
| 22522 | 22853 | ** This is different from sqlite3Atoi64() which requires the |
| 22523 | 22854 | ** input number to be zero-terminated. |
| 22524 | 22855 | */ |
| @@ -22530,11 +22861,29 @@ | ||
| 22530 | 22861 | neg = 1; |
| 22531 | 22862 | zNum++; |
| 22532 | 22863 | }else if( zNum[0]=='+' ){ |
| 22533 | 22864 | zNum++; |
| 22534 | 22865 | } |
| 22535 | - while( zNum[0]=='0' ) zNum++; | |
| 22866 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 22867 | + else if( zNum[0]=='0' | |
| 22868 | + && (zNum[1]=='x' || zNum[1]=='X') | |
| 22869 | + && sqlite3Isxdigit(zNum[2]) | |
| 22870 | + ){ | |
| 22871 | + u32 u = 0; | |
| 22872 | + zNum += 2; | |
| 22873 | + while( zNum[0]=='0' ) zNum++; | |
| 22874 | + for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ | |
| 22875 | + u = u*16 + sqlite3HexToInt(zNum[i]); | |
| 22876 | + } | |
| 22877 | + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ | |
| 22878 | + memcpy(pValue, &u, 4); | |
| 22879 | + return 1; | |
| 22880 | + }else{ | |
| 22881 | + return 0; | |
| 22882 | + } | |
| 22883 | + } | |
| 22884 | +#endif | |
| 22536 | 22885 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22537 | 22886 | v = v*10 + c; |
| 22538 | 22887 | } |
| 22539 | 22888 | |
| 22540 | 22889 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | ||
| 23606 | 23955 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23607 | 23956 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23608 | 23957 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23609 | 23958 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23610 | 23959 | /* 51 */ "SetCookie" OpHelp(""), |
| 23611 | - /* 52 */ "OpenRead" OpHelp("root=P2 iDb=P3"), | |
| 23612 | - /* 53 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), | |
| 23613 | - /* 54 */ "OpenAutoindex" OpHelp("nColumn=P2"), | |
| 23614 | - /* 55 */ "OpenEphemeral" OpHelp("nColumn=P2"), | |
| 23615 | - /* 56 */ "SorterOpen" OpHelp(""), | |
| 23616 | - /* 57 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), | |
| 23617 | - /* 58 */ "Close" OpHelp(""), | |
| 23618 | - /* 59 */ "SeekLT" OpHelp(""), | |
| 23619 | - /* 60 */ "SeekLE" OpHelp(""), | |
| 23620 | - /* 61 */ "SeekGE" OpHelp(""), | |
| 23621 | - /* 62 */ "SeekGT" OpHelp(""), | |
| 23622 | - /* 63 */ "Seek" OpHelp("intkey=r[P2]"), | |
| 23623 | - /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), | |
| 23624 | - /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), | |
| 23625 | - /* 66 */ "Found" OpHelp("key=r[P3@P4]"), | |
| 23626 | - /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), | |
| 23627 | - /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), | |
| 23628 | - /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), | |
| 23629 | - /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), | |
| 23960 | + /* 52 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), | |
| 23961 | + /* 53 */ "OpenRead" OpHelp("root=P2 iDb=P3"), | |
| 23962 | + /* 54 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), | |
| 23963 | + /* 55 */ "OpenAutoindex" OpHelp("nColumn=P2"), | |
| 23964 | + /* 56 */ "OpenEphemeral" OpHelp("nColumn=P2"), | |
| 23965 | + /* 57 */ "SorterOpen" OpHelp(""), | |
| 23966 | + /* 58 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), | |
| 23967 | + /* 59 */ "Close" OpHelp(""), | |
| 23968 | + /* 60 */ "SeekLT" OpHelp("key=r[P3@P4]"), | |
| 23969 | + /* 61 */ "SeekLE" OpHelp("key=r[P3@P4]"), | |
| 23970 | + /* 62 */ "SeekGE" OpHelp("key=r[P3@P4]"), | |
| 23971 | + /* 63 */ "SeekGT" OpHelp("key=r[P3@P4]"), | |
| 23972 | + /* 64 */ "Seek" OpHelp("intkey=r[P2]"), | |
| 23973 | + /* 65 */ "NoConflict" OpHelp("key=r[P3@P4]"), | |
| 23974 | + /* 66 */ "NotFound" OpHelp("key=r[P3@P4]"), | |
| 23975 | + /* 67 */ "Found" OpHelp("key=r[P3@P4]"), | |
| 23976 | + /* 68 */ "NotExists" OpHelp("intkey=r[P3]"), | |
| 23977 | + /* 69 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), | |
| 23978 | + /* 70 */ "NewRowid" OpHelp("r[P2]=rowid"), | |
| 23630 | 23979 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23631 | 23980 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23632 | - /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), | |
| 23633 | - /* 74 */ "Delete" OpHelp(""), | |
| 23634 | - /* 75 */ "ResetCount" OpHelp(""), | |
| 23981 | + /* 73 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), | |
| 23982 | + /* 74 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), | |
| 23983 | + /* 75 */ "Delete" OpHelp(""), | |
| 23635 | 23984 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23636 | 23985 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23637 | 23986 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23638 | 23987 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23639 | 23988 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23640 | 23989 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23641 | 23990 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23642 | 23991 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23643 | - /* 84 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), | |
| 23992 | + /* 84 */ "ResetCount" OpHelp(""), | |
| 23644 | 23993 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23645 | 23994 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23646 | 23995 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23647 | 23996 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23648 | 23997 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | ||
| 23649 | 23998 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23650 | 23999 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 23651 | 24000 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23652 | 24001 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 23653 | 24002 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 23654 | - /* 95 */ "SorterData" OpHelp("r[P2]=data"), | |
| 24003 | + /* 95 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), | |
| 23655 | 24004 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 23656 | 24005 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 23657 | - /* 98 */ "RowKey" OpHelp("r[P2]=key"), | |
| 23658 | - /* 99 */ "RowData" OpHelp("r[P2]=data"), | |
| 23659 | - /* 100 */ "Rowid" OpHelp("r[P2]=rowid"), | |
| 23660 | - /* 101 */ "NullRow" OpHelp(""), | |
| 23661 | - /* 102 */ "Last" OpHelp(""), | |
| 23662 | - /* 103 */ "SorterSort" OpHelp(""), | |
| 23663 | - /* 104 */ "Sort" OpHelp(""), | |
| 23664 | - /* 105 */ "Rewind" OpHelp(""), | |
| 23665 | - /* 106 */ "SorterInsert" OpHelp(""), | |
| 23666 | - /* 107 */ "IdxInsert" OpHelp("key=r[P2]"), | |
| 23667 | - /* 108 */ "IdxDelete" OpHelp("key=r[P2@P3]"), | |
| 23668 | - /* 109 */ "IdxRowid" OpHelp("r[P2]=rowid"), | |
| 23669 | - /* 110 */ "IdxLE" OpHelp("key=r[P3@P4]"), | |
| 23670 | - /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), | |
| 23671 | - /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), | |
| 23672 | - /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), | |
| 23673 | - /* 114 */ "Destroy" OpHelp(""), | |
| 23674 | - /* 115 */ "Clear" OpHelp(""), | |
| 23675 | - /* 116 */ "ResetSorter" OpHelp(""), | |
| 23676 | - /* 117 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), | |
| 23677 | - /* 118 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), | |
| 23678 | - /* 119 */ "ParseSchema" OpHelp(""), | |
| 23679 | - /* 120 */ "LoadAnalysis" OpHelp(""), | |
| 23680 | - /* 121 */ "DropTable" OpHelp(""), | |
| 23681 | - /* 122 */ "DropIndex" OpHelp(""), | |
| 23682 | - /* 123 */ "DropTrigger" OpHelp(""), | |
| 23683 | - /* 124 */ "IntegrityCk" OpHelp(""), | |
| 23684 | - /* 125 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), | |
| 23685 | - /* 126 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), | |
| 23686 | - /* 127 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | |
| 23687 | - /* 128 */ "Program" OpHelp(""), | |
| 23688 | - /* 129 */ "Param" OpHelp(""), | |
| 23689 | - /* 130 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), | |
| 23690 | - /* 131 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | |
| 23691 | - /* 132 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), | |
| 24006 | + /* 98 */ "SorterData" OpHelp("r[P2]=data"), | |
| 24007 | + /* 99 */ "RowKey" OpHelp("r[P2]=key"), | |
| 24008 | + /* 100 */ "RowData" OpHelp("r[P2]=data"), | |
| 24009 | + /* 101 */ "Rowid" OpHelp("r[P2]=rowid"), | |
| 24010 | + /* 102 */ "NullRow" OpHelp(""), | |
| 24011 | + /* 103 */ "Last" OpHelp(""), | |
| 24012 | + /* 104 */ "SorterSort" OpHelp(""), | |
| 24013 | + /* 105 */ "Sort" OpHelp(""), | |
| 24014 | + /* 106 */ "Rewind" OpHelp(""), | |
| 24015 | + /* 107 */ "SorterInsert" OpHelp(""), | |
| 24016 | + /* 108 */ "IdxInsert" OpHelp("key=r[P2]"), | |
| 24017 | + /* 109 */ "IdxDelete" OpHelp("key=r[P2@P3]"), | |
| 24018 | + /* 110 */ "IdxRowid" OpHelp("r[P2]=rowid"), | |
| 24019 | + /* 111 */ "IdxLE" OpHelp("key=r[P3@P4]"), | |
| 24020 | + /* 112 */ "IdxGT" OpHelp("key=r[P3@P4]"), | |
| 24021 | + /* 113 */ "IdxLT" OpHelp("key=r[P3@P4]"), | |
| 24022 | + /* 114 */ "IdxGE" OpHelp("key=r[P3@P4]"), | |
| 24023 | + /* 115 */ "Destroy" OpHelp(""), | |
| 24024 | + /* 116 */ "Clear" OpHelp(""), | |
| 24025 | + /* 117 */ "ResetSorter" OpHelp(""), | |
| 24026 | + /* 118 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), | |
| 24027 | + /* 119 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), | |
| 24028 | + /* 120 */ "ParseSchema" OpHelp(""), | |
| 24029 | + /* 121 */ "LoadAnalysis" OpHelp(""), | |
| 24030 | + /* 122 */ "DropTable" OpHelp(""), | |
| 24031 | + /* 123 */ "DropIndex" OpHelp(""), | |
| 24032 | + /* 124 */ "DropTrigger" OpHelp(""), | |
| 24033 | + /* 125 */ "IntegrityCk" OpHelp(""), | |
| 24034 | + /* 126 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), | |
| 24035 | + /* 127 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), | |
| 24036 | + /* 128 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | |
| 24037 | + /* 129 */ "Program" OpHelp(""), | |
| 24038 | + /* 130 */ "Param" OpHelp(""), | |
| 24039 | + /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), | |
| 24040 | + /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | |
| 23692 | 24041 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23693 | - /* 134 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), | |
| 23694 | - /* 135 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), | |
| 23695 | - /* 136 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), | |
| 23696 | - /* 137 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), | |
| 23697 | - /* 138 */ "IncrVacuum" OpHelp(""), | |
| 23698 | - /* 139 */ "Expire" OpHelp(""), | |
| 23699 | - /* 140 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), | |
| 23700 | - /* 141 */ "VBegin" OpHelp(""), | |
| 23701 | - /* 142 */ "VCreate" OpHelp(""), | |
| 24042 | + /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), | |
| 24043 | + /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), | |
| 24044 | + /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), | |
| 24045 | + /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), | |
| 24046 | + /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), | |
| 24047 | + /* 139 */ "IncrVacuum" OpHelp(""), | |
| 24048 | + /* 140 */ "Expire" OpHelp(""), | |
| 24049 | + /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), | |
| 24050 | + /* 142 */ "VBegin" OpHelp(""), | |
| 23702 | 24051 | /* 143 */ "ToText" OpHelp(""), |
| 23703 | 24052 | /* 144 */ "ToBlob" OpHelp(""), |
| 23704 | 24053 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23705 | 24054 | /* 146 */ "ToInt" OpHelp(""), |
| 23706 | 24055 | /* 147 */ "ToReal" OpHelp(""), |
| 23707 | - /* 148 */ "VDestroy" OpHelp(""), | |
| 23708 | - /* 149 */ "VOpen" OpHelp(""), | |
| 23709 | - /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), | |
| 23710 | - /* 151 */ "VNext" OpHelp(""), | |
| 23711 | - /* 152 */ "VRename" OpHelp(""), | |
| 23712 | - /* 153 */ "Pagecount" OpHelp(""), | |
| 23713 | - /* 154 */ "MaxPgcnt" OpHelp(""), | |
| 23714 | - /* 155 */ "Init" OpHelp("Start at P2"), | |
| 23715 | - /* 156 */ "Noop" OpHelp(""), | |
| 23716 | - /* 157 */ "Explain" OpHelp(""), | |
| 24056 | + /* 148 */ "VCreate" OpHelp(""), | |
| 24057 | + /* 149 */ "VDestroy" OpHelp(""), | |
| 24058 | + /* 150 */ "VOpen" OpHelp(""), | |
| 24059 | + /* 151 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), | |
| 24060 | + /* 152 */ "VNext" OpHelp(""), | |
| 24061 | + /* 153 */ "VRename" OpHelp(""), | |
| 24062 | + /* 154 */ "Pagecount" OpHelp(""), | |
| 24063 | + /* 155 */ "MaxPgcnt" OpHelp(""), | |
| 24064 | + /* 156 */ "Init" OpHelp("Start at P2"), | |
| 24065 | + /* 157 */ "Noop" OpHelp(""), | |
| 24066 | + /* 158 */ "Explain" OpHelp(""), | |
| 23717 | 24067 | }; |
| 23718 | 24068 | return azName[i]; |
| 23719 | 24069 | } |
| 23720 | 24070 | #endif |
| 23721 | 24071 | |
| @@ -32066,14 +32416,14 @@ | ||
| 32066 | 32416 | ** |
| 32067 | 32417 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32068 | 32418 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32069 | 32419 | */ |
| 32070 | 32420 | #ifdef SQLITE_TEST |
| 32071 | -SQLITE_API int sqlite3_os_type = 0; | |
| 32421 | +SQLITE_API LONG volatile sqlite3_os_type = 0; | |
| 32072 | 32422 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32073 | 32423 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32074 | -static int sqlite3_os_type = 0; | |
| 32424 | +static LONG volatile sqlite3_os_type = 0; | |
| 32075 | 32425 | #endif |
| 32076 | 32426 | |
| 32077 | 32427 | #ifndef SYSCALL |
| 32078 | 32428 | # define SYSCALL sqlite3_syscall_ptr |
| 32079 | 32429 | #endif |
| @@ -32699,10 +33049,15 @@ | ||
| 32699 | 33049 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 32700 | 33050 | #endif |
| 32701 | 33051 | |
| 32702 | 33052 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 32703 | 33053 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 33054 | + | |
| 33055 | + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, | |
| 33056 | + | |
| 33057 | +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \ | |
| 33058 | + LONG,LONG))aSyscall[76].pCurrent) | |
| 32704 | 33059 | |
| 32705 | 33060 | }; /* End of the overrideable system calls */ |
| 32706 | 33061 | |
| 32707 | 33062 | /* |
| 32708 | 33063 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | ||
| 32950 | 33305 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32951 | 33306 | # define osIsNT() (1) |
| 32952 | 33307 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32953 | 33308 | # define osIsNT() (0) |
| 32954 | 33309 | #else |
| 32955 | - static int osIsNT(void){ | |
| 32956 | - if( sqlite3_os_type==0 ){ | |
| 33310 | +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) | |
| 33311 | +#endif | |
| 33312 | + | |
| 33313 | +/* | |
| 33314 | +** This function determines if the machine is running a version of Windows | |
| 33315 | +** based on the NT kernel. | |
| 33316 | +*/ | |
| 33317 | +SQLITE_API int sqlite3_win32_is_nt(void){ | |
| 33318 | + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ | |
| 32957 | 33319 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 32958 | - OSVERSIONINFOW sInfo; | |
| 32959 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 32960 | - osGetVersionExW(&sInfo); | |
| 33320 | + OSVERSIONINFOW sInfo; | |
| 33321 | + sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 33322 | + osGetVersionExW(&sInfo); | |
| 32961 | 33323 | #else |
| 32962 | - OSVERSIONINFOA sInfo; | |
| 32963 | - sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 32964 | - osGetVersionExA(&sInfo); | |
| 32965 | -#endif | |
| 32966 | - sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; | |
| 32967 | - } | |
| 32968 | - return sqlite3_os_type==2; | |
| 32969 | - } | |
| 32970 | -#endif | |
| 33324 | + OSVERSIONINFOA sInfo; | |
| 33325 | + sInfo.dwOSVersionInfoSize = sizeof(sInfo); | |
| 33326 | + osGetVersionExA(&sInfo); | |
| 33327 | +#endif | |
| 33328 | + osInterlockedCompareExchange(&sqlite3_os_type, | |
| 33329 | + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); | |
| 33330 | + } | |
| 33331 | + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; | |
| 33332 | +} | |
| 32971 | 33333 | |
| 32972 | 33334 | #ifdef SQLITE_WIN32_MALLOC |
| 32973 | 33335 | /* |
| 32974 | 33336 | ** Allocate nBytes of memory. |
| 32975 | 33337 | */ |
| @@ -37121,11 +37483,11 @@ | ||
| 37121 | 37483 | }; |
| 37122 | 37484 | #endif |
| 37123 | 37485 | |
| 37124 | 37486 | /* Double-check that the aSyscall[] array has been constructed |
| 37125 | 37487 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37126 | - assert( ArraySize(aSyscall)==76 ); | |
| 37488 | + assert( ArraySize(aSyscall)==77 ); | |
| 37127 | 37489 | |
| 37128 | 37490 | /* get memory map allocation granularity */ |
| 37129 | 37491 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37130 | 37492 | #if SQLITE_OS_WINRT |
| 37131 | 37493 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | ||
| 52813 | 53175 | return pBt->nPage; |
| 52814 | 53176 | } |
| 52815 | 53177 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 52816 | 53178 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52817 | 53179 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 52818 | - return (int)btreePagecount(p->pBt); | |
| 53180 | + return btreePagecount(p->pBt); | |
| 52819 | 53181 | } |
| 52820 | 53182 | |
| 52821 | 53183 | /* |
| 52822 | 53184 | ** Get a page from the pager and initialize it. This routine is just a |
| 52823 | 53185 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | ||
| 62354 | 62716 | } |
| 62355 | 62717 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62356 | 62718 | pParse->aLabel = 0; |
| 62357 | 62719 | pParse->nLabel = 0; |
| 62358 | 62720 | *pMaxFuncArgs = nMaxArgs; |
| 62359 | - assert( p->bIsReader!=0 || p->btreeMask==0 ); | |
| 62721 | + assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); | |
| 62360 | 62722 | } |
| 62361 | 62723 | |
| 62362 | 62724 | /* |
| 62363 | 62725 | ** Return the address of the next instruction to be inserted. |
| 62364 | 62726 | */ |
| @@ -62381,11 +62743,11 @@ | ||
| 62381 | 62743 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62382 | 62744 | VdbeOp *aOp = p->aOp; |
| 62383 | 62745 | assert( aOp && !p->db->mallocFailed ); |
| 62384 | 62746 | |
| 62385 | 62747 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62386 | - assert( p->btreeMask==0 ); | |
| 62748 | + assert( DbMaskAllZero(p->btreeMask) ); | |
| 62387 | 62749 | |
| 62388 | 62750 | resolveP2Values(p, pnMaxArg); |
| 62389 | 62751 | *pnOp = p->nOp; |
| 62390 | 62752 | p->aOp = 0; |
| 62391 | 62753 | return aOp; |
| @@ -62966,13 +63328,13 @@ | ||
| 62966 | 63328 | ** p->btreeMask of databases that will require a lock. |
| 62967 | 63329 | */ |
| 62968 | 63330 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 62969 | 63331 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 62970 | 63332 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 62971 | - p->btreeMask |= ((yDbMask)1)<<i; | |
| 63333 | + DbMaskSet(p->btreeMask, i); | |
| 62972 | 63334 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 62973 | - p->lockMask |= ((yDbMask)1)<<i; | |
| 63335 | + DbMaskSet(p->lockMask, i); | |
| 62974 | 63336 | } |
| 62975 | 63337 | } |
| 62976 | 63338 | |
| 62977 | 63339 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 62978 | 63340 | /* |
| @@ -62996,20 +63358,19 @@ | ||
| 62996 | 63358 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 62997 | 63359 | ** be a problem. |
| 62998 | 63360 | */ |
| 62999 | 63361 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63000 | 63362 | int i; |
| 63001 | - yDbMask mask; | |
| 63002 | 63363 | sqlite3 *db; |
| 63003 | 63364 | Db *aDb; |
| 63004 | 63365 | int nDb; |
| 63005 | - if( p->lockMask==0 ) return; /* The common case */ | |
| 63366 | + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ | |
| 63006 | 63367 | db = p->db; |
| 63007 | 63368 | aDb = db->aDb; |
| 63008 | 63369 | nDb = db->nDb; |
| 63009 | - for(i=0, mask=1; i<nDb; i++, mask += mask){ | |
| 63010 | - if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63370 | + for(i=0; i<nDb; i++){ | |
| 63371 | + if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63011 | 63372 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63012 | 63373 | } |
| 63013 | 63374 | } |
| 63014 | 63375 | } |
| 63015 | 63376 | #endif |
| @@ -63018,20 +63379,19 @@ | ||
| 63018 | 63379 | /* |
| 63019 | 63380 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63020 | 63381 | */ |
| 63021 | 63382 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63022 | 63383 | int i; |
| 63023 | - yDbMask mask; | |
| 63024 | 63384 | sqlite3 *db; |
| 63025 | 63385 | Db *aDb; |
| 63026 | 63386 | int nDb; |
| 63027 | - if( p->lockMask==0 ) return; /* The common case */ | |
| 63387 | + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ | |
| 63028 | 63388 | db = p->db; |
| 63029 | 63389 | aDb = db->aDb; |
| 63030 | 63390 | nDb = db->nDb; |
| 63031 | - for(i=0, mask=1; i<nDb; i++, mask += mask){ | |
| 63032 | - if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63391 | + for(i=0; i<nDb; i++){ | |
| 63392 | + if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ | |
| 63033 | 63393 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63034 | 63394 | } |
| 63035 | 63395 | } |
| 63036 | 63396 | } |
| 63037 | 63397 | #endif |
| @@ -63998,11 +64358,11 @@ | ||
| 63998 | 64358 | int cnt = 0; |
| 63999 | 64359 | int nWrite = 0; |
| 64000 | 64360 | int nRead = 0; |
| 64001 | 64361 | p = db->pVdbe; |
| 64002 | 64362 | while( p ){ |
| 64003 | - if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ | |
| 64363 | + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ | |
| 64004 | 64364 | cnt++; |
| 64005 | 64365 | if( p->readOnly==0 ) nWrite++; |
| 64006 | 64366 | if( p->bIsReader ) nRead++; |
| 64007 | 64367 | } |
| 64008 | 64368 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | ||
| 64643 | 65003 | /* |
| 64644 | 65004 | ** Return the serial-type for the value stored in pMem. |
| 64645 | 65005 | */ |
| 64646 | 65006 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 64647 | 65007 | int flags = pMem->flags; |
| 64648 | - int n; | |
| 65008 | + u32 n; | |
| 64649 | 65009 | |
| 64650 | 65010 | if( flags&MEM_Null ){ |
| 64651 | 65011 | return 0; |
| 64652 | 65012 | } |
| 64653 | 65013 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | ||
| 64673 | 65033 | } |
| 64674 | 65034 | if( flags&MEM_Real ){ |
| 64675 | 65035 | return 7; |
| 64676 | 65036 | } |
| 64677 | 65037 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 64678 | - n = pMem->n; | |
| 65038 | + assert( pMem->n>=0 ); | |
| 65039 | + n = (u32)pMem->n; | |
| 64679 | 65040 | if( flags & MEM_Zero ){ |
| 64680 | 65041 | n += pMem->u.nZero; |
| 64681 | 65042 | } |
| 64682 | - assert( n>=0 ); | |
| 64683 | 65043 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 64684 | 65044 | } |
| 64685 | 65045 | |
| 64686 | 65046 | /* |
| 64687 | 65047 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | ||
| 67195 | 67555 | /* |
| 67196 | 67556 | ** Return true if the prepared statement is in need of being reset. |
| 67197 | 67557 | */ |
| 67198 | 67558 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67199 | 67559 | Vdbe *v = (Vdbe*)pStmt; |
| 67200 | - return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; | |
| 67560 | + return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; | |
| 67201 | 67561 | } |
| 67202 | 67562 | |
| 67203 | 67563 | /* |
| 67204 | 67564 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67205 | 67565 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | ||
| 67753 | 68113 | ** do so without loss of information. In other words, if the string |
| 67754 | 68114 | ** looks like a number, convert it into a number. If it does not |
| 67755 | 68115 | ** look like a number, leave it alone. |
| 67756 | 68116 | */ |
| 67757 | 68117 | static void applyNumericAffinity(Mem *pRec){ |
| 67758 | - if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ | |
| 67759 | - double rValue; | |
| 67760 | - i64 iValue; | |
| 67761 | - u8 enc = pRec->enc; | |
| 67762 | - if( (pRec->flags&MEM_Str)==0 ) return; | |
| 67763 | - if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | |
| 67764 | - if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | |
| 67765 | - pRec->u.i = iValue; | |
| 67766 | - pRec->flags |= MEM_Int; | |
| 67767 | - }else{ | |
| 67768 | - pRec->r = rValue; | |
| 67769 | - pRec->flags |= MEM_Real; | |
| 67770 | - } | |
| 67771 | - } | |
| 67772 | -} | |
| 68118 | + double rValue; | |
| 68119 | + i64 iValue; | |
| 68120 | + u8 enc = pRec->enc; | |
| 68121 | + if( (pRec->flags&MEM_Str)==0 ) return; | |
| 68122 | + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | |
| 68123 | + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | |
| 68124 | + pRec->u.i = iValue; | |
| 68125 | + pRec->flags |= MEM_Int; | |
| 68126 | + }else{ | |
| 68127 | + pRec->r = rValue; | |
| 68128 | + pRec->flags |= MEM_Real; | |
| 68129 | + } | |
| 68130 | +} | |
| 68131 | +#define ApplyNumericAffinity(X) \ | |
| 68132 | + if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} | |
| 67773 | 68133 | |
| 67774 | 68134 | /* |
| 67775 | 68135 | ** Processing is determine by the affinity parameter: |
| 67776 | 68136 | ** |
| 67777 | 68137 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | ||
| 67804 | 68164 | } |
| 67805 | 68165 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 67806 | 68166 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 67807 | 68167 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 67808 | 68168 | || affinity==SQLITE_AFF_NUMERIC ); |
| 67809 | - applyNumericAffinity(pRec); | |
| 68169 | + ApplyNumericAffinity(pRec); | |
| 67810 | 68170 | if( pRec->flags & MEM_Real ){ |
| 67811 | 68171 | sqlite3VdbeIntegerAffinity(pRec); |
| 67812 | 68172 | } |
| 67813 | 68173 | } |
| 67814 | 68174 | } |
| @@ -68385,16 +68745,18 @@ | ||
| 68385 | 68745 | break; |
| 68386 | 68746 | } |
| 68387 | 68747 | |
| 68388 | 68748 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68389 | 68749 | ** |
| 68390 | -** Set up register P1 so that it will OP_Yield to the co-routine | |
| 68750 | +** Set up register P1 so that it will Yield to the coroutine | |
| 68391 | 68751 | ** located at address P3. |
| 68392 | 68752 | ** |
| 68393 | -** If P2!=0 then the co-routine implementation immediately follows | |
| 68394 | -** this opcode. So jump over the co-routine implementation to | |
| 68753 | +** If P2!=0 then the coroutine implementation immediately follows | |
| 68754 | +** this opcode. So jump over the coroutine implementation to | |
| 68395 | 68755 | ** address P2. |
| 68756 | +** | |
| 68757 | +** See also: EndCoroutine | |
| 68396 | 68758 | */ |
| 68397 | 68759 | case OP_InitCoroutine: { /* jump */ |
| 68398 | 68760 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68399 | 68761 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68400 | 68762 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | ||
| 68406 | 68768 | break; |
| 68407 | 68769 | } |
| 68408 | 68770 | |
| 68409 | 68771 | /* Opcode: EndCoroutine P1 * * * * |
| 68410 | 68772 | ** |
| 68411 | -** The instruction at the address in register P1 is an OP_Yield. | |
| 68412 | -** Jump to the P2 parameter of that OP_Yield. | |
| 68773 | +** The instruction at the address in register P1 is an Yield. | |
| 68774 | +** Jump to the P2 parameter of that Yield. | |
| 68413 | 68775 | ** After the jump, register P1 becomes undefined. |
| 68776 | +** | |
| 68777 | +** See also: InitCoroutine | |
| 68414 | 68778 | */ |
| 68415 | 68779 | case OP_EndCoroutine: { /* in1 */ |
| 68416 | 68780 | VdbeOp *pCaller; |
| 68417 | 68781 | pIn1 = &aMem[pOp->p1]; |
| 68418 | 68782 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | ||
| 68425 | 68789 | break; |
| 68426 | 68790 | } |
| 68427 | 68791 | |
| 68428 | 68792 | /* Opcode: Yield P1 P2 * * * |
| 68429 | 68793 | ** |
| 68430 | -** Swap the program counter with the value in register P1. | |
| 68794 | +** Swap the program counter with the value in register P1. This | |
| 68795 | +** has the effect of yielding to a coroutine. | |
| 68431 | 68796 | ** |
| 68432 | -** If the co-routine ends with OP_Yield or OP_Return then continue | |
| 68433 | -** to the next instruction. But if the co-routine ends with | |
| 68434 | -** OP_EndCoroutine, jump immediately to P2. | |
| 68797 | +** If the coroutine that is launched by this instruction ends with | |
| 68798 | +** Yield or Return then continue to the next instruction. But if | |
| 68799 | +** the coroutine launched by this instruction ends with | |
| 68800 | +** EndCoroutine, then jump to P2 rather than continuing with the | |
| 68801 | +** next instruction. | |
| 68802 | +** | |
| 68803 | +** See also: InitCoroutine | |
| 68435 | 68804 | */ |
| 68436 | 68805 | case OP_Yield: { /* in1, jump */ |
| 68437 | 68806 | int pcDest; |
| 68438 | 68807 | pIn1 = &aMem[pOp->p1]; |
| 68439 | 68808 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | ||
| 69814 | 70183 | break; |
| 69815 | 70184 | } |
| 69816 | 70185 | |
| 69817 | 70186 | /* Opcode: Once P1 P2 * * * |
| 69818 | 70187 | ** |
| 69819 | -** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, | |
| 69820 | -** set the flag and fall through to the next instruction. In other words, | |
| 69821 | -** this opcode causes all following opcodes up through P2 (but not including | |
| 69822 | -** P2) to run just once and to be skipped on subsequent times through the loop. | |
| 70188 | +** Check the "once" flag number P1. If it is set, jump to instruction P2. | |
| 70189 | +** Otherwise, set the flag and fall through to the next instruction. | |
| 70190 | +** In other words, this opcode causes all following opcodes up through P2 | |
| 70191 | +** (but not including P2) to run just once and to be skipped on subsequent | |
| 70192 | +** times through the loop. | |
| 70193 | +** | |
| 70194 | +** All "once" flags are initially cleared whenever a prepared statement | |
| 70195 | +** first begins to run. | |
| 69823 | 70196 | */ |
| 69824 | 70197 | case OP_Once: { /* jump */ |
| 69825 | 70198 | assert( pOp->p1<p->nOnceFlag ); |
| 69826 | 70199 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 69827 | 70200 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | ||
| 70652 | 71025 | int iGen; |
| 70653 | 71026 | |
| 70654 | 71027 | assert( p->bIsReader ); |
| 70655 | 71028 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 70656 | 71029 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70657 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 71030 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 70658 | 71031 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 70659 | 71032 | rc = SQLITE_READONLY; |
| 70660 | 71033 | goto abort_due_to_error; |
| 70661 | 71034 | } |
| 70662 | 71035 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | ||
| 70747 | 71120 | iDb = pOp->p1; |
| 70748 | 71121 | iCookie = pOp->p3; |
| 70749 | 71122 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 70750 | 71123 | assert( iDb>=0 && iDb<db->nDb ); |
| 70751 | 71124 | assert( db->aDb[iDb].pBt!=0 ); |
| 70752 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 71125 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 70753 | 71126 | |
| 70754 | 71127 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 70755 | 71128 | pOut->u.i = iMeta; |
| 70756 | 71129 | break; |
| 70757 | 71130 | } |
| @@ -70768,11 +71141,11 @@ | ||
| 70768 | 71141 | */ |
| 70769 | 71142 | case OP_SetCookie: { /* in3 */ |
| 70770 | 71143 | Db *pDb; |
| 70771 | 71144 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 70772 | 71145 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70773 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 71146 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 70774 | 71147 | assert( p->readOnly==0 ); |
| 70775 | 71148 | pDb = &db->aDb[pOp->p1]; |
| 70776 | 71149 | assert( pDb->pBt!=0 ); |
| 70777 | 71150 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 70778 | 71151 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | ||
| 70823 | 71196 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 70824 | 71197 | ** structure, then said structure defines the content and collating |
| 70825 | 71198 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 70826 | 71199 | ** value, it is set to the number of columns in the table. |
| 70827 | 71200 | ** |
| 70828 | -** See also OpenWrite. | |
| 71201 | +** See also: OpenWrite, ReopenIdx | |
| 71202 | +*/ | |
| 71203 | +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 | |
| 71204 | +** Synopsis: root=P2 iDb=P3 | |
| 71205 | +** | |
| 71206 | +** The ReopenIdx opcode works exactly like ReadOpen except that it first | |
| 71207 | +** checks to see if the cursor on P1 is already open with a root page | |
| 71208 | +** number of P2 and if it is this opcode becomes a no-op. In other words, | |
| 71209 | +** if the cursor is already open, do not reopen it. | |
| 71210 | +** | |
| 71211 | +** The ReopenIdx opcode may only be used with P5==0 and with P4 being | |
| 71212 | +** a P4_KEYINFO object. Furthermore, the P3 value must be the same as | |
| 71213 | +** every other ReopenIdx or OpenRead for the same cursor number. | |
| 71214 | +** | |
| 71215 | +** See the OpenRead opcode documentation for additional information. | |
| 70829 | 71216 | */ |
| 70830 | 71217 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 70831 | 71218 | ** Synopsis: root=P2 iDb=P3 |
| 70832 | 71219 | ** |
| 70833 | 71220 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | ||
| 70845 | 71232 | ** in read/write mode. For a given table, there can be one or more read-only |
| 70846 | 71233 | ** cursors or a single read/write cursor but not both. |
| 70847 | 71234 | ** |
| 70848 | 71235 | ** See also OpenRead. |
| 70849 | 71236 | */ |
| 71237 | +case OP_ReopenIdx: { | |
| 71238 | + VdbeCursor *pCur; | |
| 71239 | + | |
| 71240 | + assert( pOp->p5==0 ); | |
| 71241 | + assert( pOp->p4type==P4_KEYINFO ); | |
| 71242 | + pCur = p->apCsr[pOp->p1]; | |
| 71243 | + if( pCur && pCur->pgnoRoot==pOp->p2 ){ | |
| 71244 | + assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ | |
| 71245 | + break; | |
| 71246 | + } | |
| 71247 | + /* If the cursor is not currently open or is open on a different | |
| 71248 | + ** index, then fall through into OP_OpenRead to force a reopen */ | |
| 71249 | +} | |
| 70850 | 71250 | case OP_OpenRead: |
| 70851 | 71251 | case OP_OpenWrite: { |
| 70852 | 71252 | int nField; |
| 70853 | 71253 | KeyInfo *pKeyInfo; |
| 70854 | 71254 | int p2; |
| @@ -70859,11 +71259,12 @@ | ||
| 70859 | 71259 | Db *pDb; |
| 70860 | 71260 | |
| 70861 | 71261 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 70862 | 71262 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 70863 | 71263 | assert( p->bIsReader ); |
| 70864 | - assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); | |
| 71264 | + assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx | |
| 71265 | + || p->readOnly==0 ); | |
| 70865 | 71266 | |
| 70866 | 71267 | if( p->expired ){ |
| 70867 | 71268 | rc = SQLITE_ABORT; |
| 70868 | 71269 | break; |
| 70869 | 71270 | } |
| @@ -70871,11 +71272,11 @@ | ||
| 70871 | 71272 | nField = 0; |
| 70872 | 71273 | pKeyInfo = 0; |
| 70873 | 71274 | p2 = pOp->p2; |
| 70874 | 71275 | iDb = pOp->p3; |
| 70875 | 71276 | assert( iDb>=0 && iDb<db->nDb ); |
| 70876 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 71277 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 70877 | 71278 | pDb = &db->aDb[iDb]; |
| 70878 | 71279 | pX = pDb->pBt; |
| 70879 | 71280 | assert( pX!=0 ); |
| 70880 | 71281 | if( pOp->opcode==OP_OpenWrite ){ |
| 70881 | 71282 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | ||
| 70916 | 71317 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 70917 | 71318 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 70918 | 71319 | if( pCur==0 ) goto no_mem; |
| 70919 | 71320 | pCur->nullRow = 1; |
| 70920 | 71321 | pCur->isOrdered = 1; |
| 71322 | + pCur->pgnoRoot = p2; | |
| 70921 | 71323 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 70922 | 71324 | pCur->pKeyInfo = pKeyInfo; |
| 70923 | 71325 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 70924 | 71326 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 70925 | 71327 | |
| @@ -71070,11 +71472,11 @@ | ||
| 71070 | 71472 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71071 | 71473 | p->apCsr[pOp->p1] = 0; |
| 71072 | 71474 | break; |
| 71073 | 71475 | } |
| 71074 | 71476 | |
| 71075 | -/* Opcode: SeekGe P1 P2 P3 P4 * | |
| 71477 | +/* Opcode: SeekGE P1 P2 P3 P4 * | |
| 71076 | 71478 | ** Synopsis: key=r[P3@P4] |
| 71077 | 71479 | ** |
| 71078 | 71480 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71079 | 71481 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71080 | 71482 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | ||
| 71081 | 71483 | ** that are used as an unpacked index key. |
| 71082 | 71484 | ** |
| 71083 | 71485 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71084 | 71486 | ** is greater than or equal to the key value. If there are no records |
| 71085 | 71487 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71488 | +** | |
| 71489 | +** This opcode leaves the cursor configured to move in forward order, | |
| 71490 | +** from the begining toward the end. In other words, the cursor is | |
| 71491 | +** configured to use Next, not Prev. | |
| 71086 | 71492 | ** |
| 71087 | 71493 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71088 | 71494 | */ |
| 71089 | -/* Opcode: SeekGt P1 P2 P3 P4 * | |
| 71495 | +/* Opcode: SeekGT P1 P2 P3 P4 * | |
| 71090 | 71496 | ** Synopsis: key=r[P3@P4] |
| 71091 | 71497 | ** |
| 71092 | 71498 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71093 | 71499 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71094 | 71500 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | ||
| 71095 | 71501 | ** that are used as an unpacked index key. |
| 71096 | 71502 | ** |
| 71097 | 71503 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71098 | 71504 | ** is greater than the key value. If there are no records greater than |
| 71099 | 71505 | ** the key and P2 is not zero, then jump to P2. |
| 71506 | +** | |
| 71507 | +** This opcode leaves the cursor configured to move in forward order, | |
| 71508 | +** from the begining toward the end. In other words, the cursor is | |
| 71509 | +** configured to use Next, not Prev. | |
| 71100 | 71510 | ** |
| 71101 | 71511 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71102 | 71512 | */ |
| 71103 | -/* Opcode: SeekLt P1 P2 P3 P4 * | |
| 71513 | +/* Opcode: SeekLT P1 P2 P3 P4 * | |
| 71104 | 71514 | ** Synopsis: key=r[P3@P4] |
| 71105 | 71515 | ** |
| 71106 | 71516 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71107 | 71517 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71108 | 71518 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | ||
| 71109 | 71519 | ** that are used as an unpacked index key. |
| 71110 | 71520 | ** |
| 71111 | 71521 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71112 | 71522 | ** is less than the key value. If there are no records less than |
| 71113 | 71523 | ** the key and P2 is not zero, then jump to P2. |
| 71524 | +** | |
| 71525 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 71526 | +** from the end toward the beginning. In other words, the cursor is | |
| 71527 | +** configured to use Prev, not Next. | |
| 71114 | 71528 | ** |
| 71115 | 71529 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71116 | 71530 | */ |
| 71117 | -/* Opcode: SeekLe P1 P2 P3 P4 * | |
| 71531 | +/* Opcode: SeekLE P1 P2 P3 P4 * | |
| 71118 | 71532 | ** Synopsis: key=r[P3@P4] |
| 71119 | 71533 | ** |
| 71120 | 71534 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71121 | 71535 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71122 | 71536 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | ||
| 71123 | 71537 | ** that are used as an unpacked index key. |
| 71124 | 71538 | ** |
| 71125 | 71539 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71126 | 71540 | ** is less than or equal to the key value. If there are no records |
| 71127 | 71541 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71542 | +** | |
| 71543 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 71544 | +** from the end toward the beginning. In other words, the cursor is | |
| 71545 | +** configured to use Prev, not Next. | |
| 71128 | 71546 | ** |
| 71129 | 71547 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71130 | 71548 | */ |
| 71131 | 71549 | case OP_SeekLT: /* jump, in3 */ |
| 71132 | 71550 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | ||
| 71149 | 71567 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71150 | 71568 | assert( pC->isOrdered ); |
| 71151 | 71569 | assert( pC->pCursor!=0 ); |
| 71152 | 71570 | oc = pOp->opcode; |
| 71153 | 71571 | pC->nullRow = 0; |
| 71572 | +#ifdef SQLITE_DEBUG | |
| 71573 | + pC->seekOp = pOp->opcode; | |
| 71574 | +#endif | |
| 71154 | 71575 | if( pC->isTable ){ |
| 71155 | 71576 | /* The input value in P3 might be of any type: integer, real, string, |
| 71156 | 71577 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71157 | 71578 | ** the seek, so covert it. */ |
| 71158 | 71579 | pIn3 = &aMem[pOp->p3]; |
| 71159 | - applyNumericAffinity(pIn3); | |
| 71580 | + ApplyNumericAffinity(pIn3); | |
| 71160 | 71581 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71161 | 71582 | pC->rowidIsValid = 0; |
| 71162 | 71583 | |
| 71163 | 71584 | /* If the P3 value could not be converted into an integer without |
| 71164 | 71585 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | ||
| 71303 | 71724 | ** record. |
| 71304 | 71725 | ** |
| 71305 | 71726 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71306 | 71727 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71307 | 71728 | ** P1 is left pointing at the matching entry. |
| 71729 | +** | |
| 71730 | +** This operation leaves the cursor in a state where it cannot be | |
| 71731 | +** advanced in either direction. In other words, the Next and Prev | |
| 71732 | +** opcodes do not work after this operation. | |
| 71308 | 71733 | ** |
| 71309 | 71734 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71310 | 71735 | */ |
| 71311 | 71736 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71312 | 71737 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | ||
| 71318 | 71743 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71319 | 71744 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71320 | 71745 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71321 | 71746 | ** falls through to the next instruction and P1 is left pointing at the |
| 71322 | 71747 | ** matching entry. |
| 71748 | +** | |
| 71749 | +** This operation leaves the cursor in a state where it cannot be | |
| 71750 | +** advanced in either direction. In other words, the Next and Prev | |
| 71751 | +** opcodes do not work after this operation. | |
| 71323 | 71752 | ** |
| 71324 | 71753 | ** See also: Found, NotExists, NoConflict |
| 71325 | 71754 | */ |
| 71326 | 71755 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71327 | 71756 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | ||
| 71337 | 71766 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71338 | 71767 | ** cursor pointing to the matching row. |
| 71339 | 71768 | ** |
| 71340 | 71769 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71341 | 71770 | ** branch is always taken if any part of the search key input is NULL. |
| 71771 | +** | |
| 71772 | +** This operation leaves the cursor in a state where it cannot be | |
| 71773 | +** advanced in either direction. In other words, the Next and Prev | |
| 71774 | +** opcodes do not work after this operation. | |
| 71342 | 71775 | ** |
| 71343 | 71776 | ** See also: NotFound, Found, NotExists |
| 71344 | 71777 | */ |
| 71345 | 71778 | case OP_NoConflict: /* jump, in3 */ |
| 71346 | 71779 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | ||
| 71360 | 71793 | |
| 71361 | 71794 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71362 | 71795 | assert( pOp->p4type==P4_INT32 ); |
| 71363 | 71796 | pC = p->apCsr[pOp->p1]; |
| 71364 | 71797 | assert( pC!=0 ); |
| 71798 | +#ifdef SQLITE_DEBUG | |
| 71799 | + pC->seekOp = 0; | |
| 71800 | +#endif | |
| 71365 | 71801 | pIn3 = &aMem[pOp->p3]; |
| 71366 | 71802 | assert( pC->pCursor!=0 ); |
| 71367 | 71803 | assert( pC->isTable==0 ); |
| 71368 | 71804 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71369 | 71805 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | ||
| 71430 | 71866 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71431 | 71867 | ** through to the next instruction. |
| 71432 | 71868 | ** |
| 71433 | 71869 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71434 | 71870 | ** (with arbitrary multi-value keys). |
| 71871 | +** | |
| 71872 | +** This opcode leaves the cursor in a state where it cannot be advanced | |
| 71873 | +** in either direction. In other words, the Next and Prev opcodes will | |
| 71874 | +** not work following this opcode. | |
| 71435 | 71875 | ** |
| 71436 | 71876 | ** See also: Found, NotFound, NoConflict |
| 71437 | 71877 | */ |
| 71438 | 71878 | case OP_NotExists: { /* jump, in3 */ |
| 71439 | 71879 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | ||
| 71444 | 71884 | pIn3 = &aMem[pOp->p3]; |
| 71445 | 71885 | assert( pIn3->flags & MEM_Int ); |
| 71446 | 71886 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71447 | 71887 | pC = p->apCsr[pOp->p1]; |
| 71448 | 71888 | assert( pC!=0 ); |
| 71889 | +#ifdef SQLITE_DEBUG | |
| 71890 | + pC->seekOp = 0; | |
| 71891 | +#endif | |
| 71449 | 71892 | assert( pC->isTable ); |
| 71450 | 71893 | assert( pC->pseudoTableReg==0 ); |
| 71451 | 71894 | pCrsr = pC->pCursor; |
| 71452 | 71895 | assert( pCrsr!=0 ); |
| 71453 | 71896 | res = 0; |
| @@ -71806,16 +72249,16 @@ | ||
| 71806 | 72249 | p->nChange = 0; |
| 71807 | 72250 | break; |
| 71808 | 72251 | } |
| 71809 | 72252 | |
| 71810 | 72253 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 71811 | -** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 | |
| 72254 | +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 | |
| 71812 | 72255 | ** |
| 71813 | 72256 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 71814 | 72257 | ** the record blob in register P3 against a prefix of the entry that |
| 71815 | -** the sorter cursor currently points to. The final P4 fields of both | |
| 71816 | -** the P3 and sorter record are ignored. | |
| 72258 | +** the sorter cursor currently points to. Only the first P4 fields | |
| 72259 | +** of r[P3] and the sorter record are compared. | |
| 71817 | 72260 | ** |
| 71818 | 72261 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 71819 | 72262 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 71820 | 72263 | ** the comparison is assumed to be equal. |
| 71821 | 72264 | ** |
| @@ -71823,18 +72266,18 @@ | ||
| 71823 | 72266 | ** each other. Jump to P2 if they are different. |
| 71824 | 72267 | */ |
| 71825 | 72268 | case OP_SorterCompare: { |
| 71826 | 72269 | VdbeCursor *pC; |
| 71827 | 72270 | int res; |
| 71828 | - int nIgnore; | |
| 72271 | + int nKeyCol; | |
| 71829 | 72272 | |
| 71830 | 72273 | pC = p->apCsr[pOp->p1]; |
| 71831 | 72274 | assert( isSorter(pC) ); |
| 71832 | 72275 | assert( pOp->p4type==P4_INT32 ); |
| 71833 | 72276 | pIn3 = &aMem[pOp->p3]; |
| 71834 | - nIgnore = pOp->p4.i; | |
| 71835 | - rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); | |
| 72277 | + nKeyCol = pOp->p4.i; | |
| 72278 | + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); | |
| 71836 | 72279 | VdbeBranchTaken(res!=0,2); |
| 71837 | 72280 | if( res ){ |
| 71838 | 72281 | pc = pOp->p2-1; |
| 71839 | 72282 | } |
| 71840 | 72283 | break; |
| @@ -72010,15 +72453,19 @@ | ||
| 72010 | 72453 | break; |
| 72011 | 72454 | } |
| 72012 | 72455 | |
| 72013 | 72456 | /* Opcode: Last P1 P2 * * * |
| 72014 | 72457 | ** |
| 72015 | -** The next use of the Rowid or Column or Next instruction for P1 | |
| 72458 | +** The next use of the Rowid or Column or Prev instruction for P1 | |
| 72016 | 72459 | ** will refer to the last entry in the database table or index. |
| 72017 | 72460 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72018 | 72461 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72019 | 72462 | ** to the following instruction. |
| 72463 | +** | |
| 72464 | +** This opcode leaves the cursor configured to move in reverse order, | |
| 72465 | +** from the end toward the beginning. In other words, the cursor is | |
| 72466 | +** configured to use Prev, not Next. | |
| 72020 | 72467 | */ |
| 72021 | 72468 | case OP_Last: { /* jump */ |
| 72022 | 72469 | VdbeCursor *pC; |
| 72023 | 72470 | BtCursor *pCrsr; |
| 72024 | 72471 | int res; |
| @@ -72032,10 +72479,13 @@ | ||
| 72032 | 72479 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72033 | 72480 | pC->nullRow = (u8)res; |
| 72034 | 72481 | pC->deferredMoveto = 0; |
| 72035 | 72482 | pC->rowidIsValid = 0; |
| 72036 | 72483 | pC->cacheStatus = CACHE_STALE; |
| 72484 | +#ifdef SQLITE_DEBUG | |
| 72485 | + pC->seekOp = OP_Last; | |
| 72486 | +#endif | |
| 72037 | 72487 | if( pOp->p2>0 ){ |
| 72038 | 72488 | VdbeBranchTaken(res!=0,2); |
| 72039 | 72489 | if( res ) pc = pOp->p2 - 1; |
| 72040 | 72490 | } |
| 72041 | 72491 | break; |
| @@ -72068,10 +72518,14 @@ | ||
| 72068 | 72518 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72069 | 72519 | ** will refer to the first entry in the database table or index. |
| 72070 | 72520 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72071 | 72521 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72072 | 72522 | ** to the following instruction. |
| 72523 | +** | |
| 72524 | +** This opcode leaves the cursor configured to move in forward order, | |
| 72525 | +** from the begining toward the end. In other words, the cursor is | |
| 72526 | +** configured to use Next, not Prev. | |
| 72073 | 72527 | */ |
| 72074 | 72528 | case OP_Rewind: { /* jump */ |
| 72075 | 72529 | VdbeCursor *pC; |
| 72076 | 72530 | BtCursor *pCrsr; |
| 72077 | 72531 | int res; |
| @@ -72079,10 +72533,13 @@ | ||
| 72079 | 72533 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72080 | 72534 | pC = p->apCsr[pOp->p1]; |
| 72081 | 72535 | assert( pC!=0 ); |
| 72082 | 72536 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72083 | 72537 | res = 1; |
| 72538 | +#ifdef SQLITE_DEBUG | |
| 72539 | + pC->seekOp = OP_Rewind; | |
| 72540 | +#endif | |
| 72084 | 72541 | if( isSorter(pC) ){ |
| 72085 | 72542 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72086 | 72543 | }else{ |
| 72087 | 72544 | pCrsr = pC->pCursor; |
| 72088 | 72545 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | ||
| 72104 | 72561 | ** |
| 72105 | 72562 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72106 | 72563 | ** table or index. If there are no more key/value pairs then fall through |
| 72107 | 72564 | ** to the following instruction. But if the cursor advance was successful, |
| 72108 | 72565 | ** jump immediately to P2. |
| 72566 | +** | |
| 72567 | +** The Next opcode is only valid following an SeekGT, SeekGE, or | |
| 72568 | +** OP_Rewind opcode used to position the cursor. Next is not allowed | |
| 72569 | +** to follow SeekLT, SeekLE, or OP_Last. | |
| 72109 | 72570 | ** |
| 72110 | 72571 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72111 | 72572 | ** been opened prior to this opcode or the program will segfault. |
| 72112 | 72573 | ** |
| 72113 | 72574 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | ||
| 72123 | 72584 | ** |
| 72124 | 72585 | ** See also: Prev, NextIfOpen |
| 72125 | 72586 | */ |
| 72126 | 72587 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72127 | 72588 | ** |
| 72128 | -** This opcode works just like OP_Next except that if cursor P1 is not | |
| 72589 | +** This opcode works just like Next except that if cursor P1 is not | |
| 72129 | 72590 | ** open it behaves a no-op. |
| 72130 | 72591 | */ |
| 72131 | 72592 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72132 | 72593 | ** |
| 72133 | 72594 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72134 | 72595 | ** table or index. If there is no previous key/value pairs then fall through |
| 72135 | 72596 | ** to the following instruction. But if the cursor backup was successful, |
| 72136 | 72597 | ** jump immediately to P2. |
| 72137 | 72598 | ** |
| 72599 | +** | |
| 72600 | +** The Prev opcode is only valid following an SeekLT, SeekLE, or | |
| 72601 | +** OP_Last opcode used to position the cursor. Prev is not allowed | |
| 72602 | +** to follow SeekGT, SeekGE, or OP_Rewind. | |
| 72603 | +** | |
| 72138 | 72604 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72139 | 72605 | ** not open then the behavior is undefined. |
| 72140 | 72606 | ** |
| 72141 | 72607 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72142 | 72608 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | ||
| 72149 | 72615 | ** If P5 is positive and the jump is taken, then event counter |
| 72150 | 72616 | ** number P5-1 in the prepared statement is incremented. |
| 72151 | 72617 | */ |
| 72152 | 72618 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72153 | 72619 | ** |
| 72154 | -** This opcode works just like OP_Prev except that if cursor P1 is not | |
| 72620 | +** This opcode works just like Prev except that if cursor P1 is not | |
| 72155 | 72621 | ** open it behaves a no-op. |
| 72156 | 72622 | */ |
| 72157 | 72623 | case OP_SorterNext: { /* jump */ |
| 72158 | 72624 | VdbeCursor *pC; |
| 72159 | 72625 | int res; |
| @@ -72180,10 +72646,20 @@ | ||
| 72180 | 72646 | testcase( res==1 ); |
| 72181 | 72647 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72182 | 72648 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72183 | 72649 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72184 | 72650 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72651 | + | |
| 72652 | + /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. | |
| 72653 | + ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ | |
| 72654 | + assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen | |
| 72655 | + || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE | |
| 72656 | + || pC->seekOp==OP_Rewind ); | |
| 72657 | + assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen | |
| 72658 | + || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE | |
| 72659 | + || pC->seekOp==OP_Last ); | |
| 72660 | + | |
| 72185 | 72661 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72186 | 72662 | next_tail: |
| 72187 | 72663 | pC->cacheStatus = CACHE_STALE; |
| 72188 | 72664 | VdbeBranchTaken(res==0,2); |
| 72189 | 72665 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | ||
| 72462 | 72938 | rc = SQLITE_LOCKED; |
| 72463 | 72939 | p->errorAction = OE_Abort; |
| 72464 | 72940 | }else{ |
| 72465 | 72941 | iDb = pOp->p3; |
| 72466 | 72942 | assert( iCnt==1 ); |
| 72467 | - assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | |
| 72943 | + assert( DbMaskTest(p->btreeMask, iDb) ); | |
| 72468 | 72944 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72469 | 72945 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72470 | 72946 | pOut->flags = MEM_Int; |
| 72471 | 72947 | pOut->u.i = iMoved; |
| 72472 | 72948 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | ||
| 72502 | 72978 | case OP_Clear: { |
| 72503 | 72979 | int nChange; |
| 72504 | 72980 | |
| 72505 | 72981 | nChange = 0; |
| 72506 | 72982 | assert( p->readOnly==0 ); |
| 72507 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); | |
| 72983 | + assert( DbMaskTest(p->btreeMask, pOp->p2) ); | |
| 72508 | 72984 | rc = sqlite3BtreeClearTable( |
| 72509 | 72985 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72510 | 72986 | ); |
| 72511 | 72987 | if( pOp->p3 ){ |
| 72512 | 72988 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | ||
| 72572 | 73048 | int flags; |
| 72573 | 73049 | Db *pDb; |
| 72574 | 73050 | |
| 72575 | 73051 | pgno = 0; |
| 72576 | 73052 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72577 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 73053 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 72578 | 73054 | assert( p->readOnly==0 ); |
| 72579 | 73055 | pDb = &db->aDb[pOp->p1]; |
| 72580 | 73056 | assert( pDb->pBt!=0 ); |
| 72581 | 73057 | if( pOp->opcode==OP_CreateTable ){ |
| 72582 | 73058 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | ||
| 72660 | 73136 | |
| 72661 | 73137 | /* Opcode: DropTable P1 * * P4 * |
| 72662 | 73138 | ** |
| 72663 | 73139 | ** Remove the internal (in-memory) data structures that describe |
| 72664 | 73140 | ** the table named P4 in database P1. This is called after a table |
| 72665 | -** is dropped in order to keep the internal representation of the | |
| 73141 | +** is dropped from disk (using the Destroy opcode) in order to keep | |
| 73142 | +** the internal representation of the | |
| 72666 | 73143 | ** schema consistent with what is on disk. |
| 72667 | 73144 | */ |
| 72668 | 73145 | case OP_DropTable: { |
| 72669 | 73146 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 72670 | 73147 | break; |
| @@ -72672,11 +73149,12 @@ | ||
| 72672 | 73149 | |
| 72673 | 73150 | /* Opcode: DropIndex P1 * * P4 * |
| 72674 | 73151 | ** |
| 72675 | 73152 | ** Remove the internal (in-memory) data structures that describe |
| 72676 | 73153 | ** the index named P4 in database P1. This is called after an index |
| 72677 | -** is dropped in order to keep the internal representation of the | |
| 73154 | +** is dropped from disk (using the Destroy opcode) | |
| 73155 | +** in order to keep the internal representation of the | |
| 72678 | 73156 | ** schema consistent with what is on disk. |
| 72679 | 73157 | */ |
| 72680 | 73158 | case OP_DropIndex: { |
| 72681 | 73159 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 72682 | 73160 | break; |
| @@ -72684,11 +73162,12 @@ | ||
| 72684 | 73162 | |
| 72685 | 73163 | /* Opcode: DropTrigger P1 * * P4 * |
| 72686 | 73164 | ** |
| 72687 | 73165 | ** Remove the internal (in-memory) data structures that describe |
| 72688 | 73166 | ** the trigger named P4 in database P1. This is called after a trigger |
| 72689 | -** is dropped in order to keep the internal representation of the | |
| 73167 | +** is dropped from disk (using the Destroy opcode) in order to keep | |
| 73168 | +** the internal representation of the | |
| 72690 | 73169 | ** schema consistent with what is on disk. |
| 72691 | 73170 | */ |
| 72692 | 73171 | case OP_DropTrigger: { |
| 72693 | 73172 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 72694 | 73173 | break; |
| @@ -72737,11 +73216,11 @@ | ||
| 72737 | 73216 | for(j=0; j<nRoot; j++){ |
| 72738 | 73217 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 72739 | 73218 | } |
| 72740 | 73219 | aRoot[j] = 0; |
| 72741 | 73220 | assert( pOp->p5<db->nDb ); |
| 72742 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); | |
| 73221 | + assert( DbMaskTest(p->btreeMask, pOp->p5) ); | |
| 72743 | 73222 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 72744 | 73223 | (int)pnErr->u.i, &nErr); |
| 72745 | 73224 | sqlite3DbFree(db, aRoot); |
| 72746 | 73225 | pnErr->u.i -= nErr; |
| 72747 | 73226 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | ||
| 73397 | 73876 | */ |
| 73398 | 73877 | case OP_IncrVacuum: { /* jump */ |
| 73399 | 73878 | Btree *pBt; |
| 73400 | 73879 | |
| 73401 | 73880 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73402 | - assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | |
| 73881 | + assert( DbMaskTest(p->btreeMask, pOp->p1) ); | |
| 73403 | 73882 | assert( p->readOnly==0 ); |
| 73404 | 73883 | pBt = db->aDb[pOp->p1].pBt; |
| 73405 | 73884 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73406 | 73885 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73407 | 73886 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | ||
| 73412 | 73891 | } |
| 73413 | 73892 | #endif |
| 73414 | 73893 | |
| 73415 | 73894 | /* Opcode: Expire P1 * * * * |
| 73416 | 73895 | ** |
| 73417 | -** Cause precompiled statements to become expired. An expired statement | |
| 73418 | -** fails with an error code of SQLITE_SCHEMA if it is ever executed | |
| 73419 | -** (via sqlite3_step()). | |
| 73896 | +** Cause precompiled statements to expire. When an expired statement | |
| 73897 | +** is executed using sqlite3_step() it will either automatically | |
| 73898 | +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) | |
| 73899 | +** or it will fail with SQLITE_SCHEMA. | |
| 73420 | 73900 | ** |
| 73421 | 73901 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73422 | -** then only the currently executing statement is affected. | |
| 73902 | +** then only the currently executing statement is expired. | |
| 73423 | 73903 | */ |
| 73424 | 73904 | case OP_Expire: { |
| 73425 | 73905 | if( !pOp->p1 ){ |
| 73426 | 73906 | sqlite3ExpirePreparedStatements(db); |
| 73427 | 73907 | }else{ |
| @@ -73449,11 +73929,11 @@ | ||
| 73449 | 73929 | case OP_TableLock: { |
| 73450 | 73930 | u8 isWriteLock = (u8)pOp->p3; |
| 73451 | 73931 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73452 | 73932 | int p1 = pOp->p1; |
| 73453 | 73933 | assert( p1>=0 && p1<db->nDb ); |
| 73454 | - assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); | |
| 73934 | + assert( DbMaskTest(p->btreeMask, p1) ); | |
| 73455 | 73935 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73456 | 73936 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73457 | 73937 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73458 | 73938 | const char *z = pOp->p4.z; |
| 73459 | 73939 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | ||
| 73899 | 74379 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 73900 | 74380 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 73901 | 74381 | if( zTrace ){ |
| 73902 | 74382 | int i; |
| 73903 | 74383 | for(i=0; i<db->nDb; i++){ |
| 73904 | - if( (MASKBIT(i) & p->btreeMask)==0 ) continue; | |
| 74384 | + if( DbMaskTest(p->btreeMask, i)==0 ) continue; | |
| 73905 | 74385 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 73906 | 74386 | } |
| 73907 | 74387 | } |
| 73908 | 74388 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 73909 | 74389 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | ||
| 74889 | 75369 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 74890 | 75370 | ** has been allocated and contains an unpacked record that is used as key2. |
| 74891 | 75371 | */ |
| 74892 | 75372 | static void vdbeSorterCompare( |
| 74893 | 75373 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 74894 | - int nIgnore, /* Ignore the last nIgnore fields */ | |
| 75374 | + int nKeyCol, /* Num of columns. 0 means "all" */ | |
| 74895 | 75375 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 74896 | 75376 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 74897 | 75377 | int *pRes /* OUT: Result of comparison */ |
| 74898 | 75378 | ){ |
| 74899 | 75379 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | ||
| 74903 | 75383 | |
| 74904 | 75384 | if( pKey2 ){ |
| 74905 | 75385 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 74906 | 75386 | } |
| 74907 | 75387 | |
| 74908 | - if( nIgnore ){ | |
| 74909 | - r2->nField = pKeyInfo->nField - nIgnore; | |
| 74910 | - assert( r2->nField>0 ); | |
| 74911 | - for(i=0; i<r2->nField; i++){ | |
| 75388 | + if( nKeyCol ){ | |
| 75389 | + r2->nField = nKeyCol; | |
| 75390 | + for(i=0; i<nKeyCol; i++){ | |
| 74912 | 75391 | if( r2->aMem[i].flags & MEM_Null ){ |
| 74913 | 75392 | *pRes = -1; |
| 74914 | 75393 | return; |
| 74915 | 75394 | } |
| 74916 | 75395 | } |
| @@ -75588,18 +76067,18 @@ | ||
| 75588 | 76067 | ** key. |
| 75589 | 76068 | */ |
| 75590 | 76069 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 75591 | 76070 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 75592 | 76071 | Mem *pVal, /* Value to compare to current sorter key */ |
| 75593 | - int nIgnore, /* Ignore this many fields at the end */ | |
| 76072 | + int nKeyCol, /* Only compare this many fields */ | |
| 75594 | 76073 | int *pRes /* OUT: Result of comparison */ |
| 75595 | 76074 | ){ |
| 75596 | 76075 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75597 | 76076 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 75598 | 76077 | |
| 75599 | 76078 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 75600 | - vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes); | |
| 76079 | + vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes); | |
| 75601 | 76080 | return SQLITE_OK; |
| 75602 | 76081 | } |
| 75603 | 76082 | |
| 75604 | 76083 | /************** End of vdbesort.c ********************************************/ |
| 75605 | 76084 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | ||
| 79352 | 79831 | } |
| 79353 | 79832 | } |
| 79354 | 79833 | } |
| 79355 | 79834 | |
| 79356 | 79835 | if( eType==0 ){ |
| 79357 | - /* Could not found an existing table or index to use as the RHS b-tree. | |
| 79836 | + /* Could not find an existing table or index to use as the RHS b-tree. | |
| 79358 | 79837 | ** We will have to generate an ephemeral table to do the job. |
| 79359 | 79838 | */ |
| 79360 | 79839 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79361 | 79840 | int rMayHaveNull = 0; |
| 79362 | 79841 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | ||
| 79482 | 79961 | /* Case 1: expr IN (SELECT ...) |
| 79483 | 79962 | ** |
| 79484 | 79963 | ** Generate code to write the results of the select into the temporary |
| 79485 | 79964 | ** table allocated and opened above. |
| 79486 | 79965 | */ |
| 79966 | + Select *pSelect = pExpr->x.pSelect; | |
| 79487 | 79967 | SelectDest dest; |
| 79488 | 79968 | ExprList *pEList; |
| 79489 | 79969 | |
| 79490 | 79970 | assert( !isRowid ); |
| 79491 | 79971 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79492 | 79972 | dest.affSdst = (u8)affinity; |
| 79493 | 79973 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79494 | - pExpr->x.pSelect->iLimit = 0; | |
| 79974 | + pSelect->iLimit = 0; | |
| 79975 | + testcase( pSelect->selFlags & SF_Distinct ); | |
| 79976 | + pSelect->selFlags &= ~SF_Distinct; | |
| 79495 | 79977 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79496 | - if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ | |
| 79978 | + if( sqlite3Select(pParse, pSelect, &dest) ){ | |
| 79497 | 79979 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79498 | 79980 | return 0; |
| 79499 | 79981 | } |
| 79500 | - pEList = pExpr->x.pSelect->pEList; | |
| 79982 | + pEList = pSelect->pEList; | |
| 79501 | 79983 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79502 | 79984 | assert( pEList!=0 ); |
| 79503 | 79985 | assert( pEList->nExpr>0 ); |
| 79504 | 79986 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79505 | 79987 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | ||
| 79803 | 80285 | }else{ |
| 79804 | 80286 | int c; |
| 79805 | 80287 | i64 value; |
| 79806 | 80288 | const char *z = pExpr->u.zToken; |
| 79807 | 80289 | assert( z!=0 ); |
| 79808 | - c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); | |
| 80290 | + c = sqlite3DecOrHexToI64(z, &value); | |
| 79809 | 80291 | if( c==0 || (c==2 && negFlag) ){ |
| 79810 | 80292 | char *zV; |
| 79811 | 80293 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 79812 | 80294 | zV = dup8bytes(v, (char*)&value); |
| 79813 | 80295 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 79814 | 80296 | }else{ |
| 79815 | 80297 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 79816 | 80298 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 79817 | 80299 | #else |
| 79818 | - codeReal(v, z, negFlag, iMem); | |
| 80300 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 80301 | + if( sqlite3_strnicmp(z,"0x",2)==0 ){ | |
| 80302 | + sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); | |
| 80303 | + }else | |
| 80304 | +#endif | |
| 80305 | + { | |
| 80306 | + codeReal(v, z, negFlag, iMem); | |
| 80307 | + } | |
| 79819 | 80308 | #endif |
| 79820 | 80309 | } |
| 79821 | 80310 | } |
| 79822 | 80311 | } |
| 79823 | 80312 | |
| @@ -83186,19 +83675,24 @@ | ||
| 83186 | 83675 | } |
| 83187 | 83676 | |
| 83188 | 83677 | /* |
| 83189 | 83678 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83190 | 83679 | ** are: |
| 83191 | -** N: The number of columns in the index including the rowid/pk | |
| 83192 | -** K: The number of columns in the index excluding the rowid/pk | |
| 83193 | -** C: The number of rows in the index | |
| 83194 | -** | |
| 83195 | -** C is only used for STAT3 and STAT4. | |
| 83196 | -** | |
| 83197 | -** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables, | |
| 83198 | -** N=K+P where P is the number of columns in the primary key. For the | |
| 83199 | -** covering index that implements the original WITHOUT ROWID table, N==K. | |
| 83680 | +** N: The number of columns in the index including the rowid/pk (note 1) | |
| 83681 | +** K: The number of columns in the index excluding the rowid/pk. | |
| 83682 | +** C: The number of rows in the index (note 2) | |
| 83683 | +** | |
| 83684 | +** Note 1: In the special case of the covering index that implements a | |
| 83685 | +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the | |
| 83686 | +** total number of columns in the table. | |
| 83687 | +** | |
| 83688 | +** Note 2: C is only used for STAT3 and STAT4. | |
| 83689 | +** | |
| 83690 | +** For indexes on ordinary rowid tables, N==K+1. But for indexes on | |
| 83691 | +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the | |
| 83692 | +** PRIMARY KEY of the table. The covering index that implements the | |
| 83693 | +** original WITHOUT ROWID table as N==K as a special case. | |
| 83200 | 83694 | ** |
| 83201 | 83695 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83202 | 83696 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83203 | 83697 | ** the size of the blob is sizeof(void*) bytes). |
| 83204 | 83698 | */ |
| @@ -83504,11 +83998,14 @@ | ||
| 83504 | 83998 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83505 | 83999 | ** C Index of left-most column to differ from previous row |
| 83506 | 84000 | ** R Rowid for the current row. Might be a key record for |
| 83507 | 84001 | ** WITHOUT ROWID tables. |
| 83508 | 84002 | ** |
| 83509 | -** The SQL function always returns NULL. | |
| 84003 | +** This SQL function always returns NULL. It's purpose it to accumulate | |
| 84004 | +** statistical data and/or samples in the Stat4Accum object about the | |
| 84005 | +** index being analyzed. The stat_get() SQL function will later be used to | |
| 84006 | +** extract relevant information for constructing the sqlite_statN tables. | |
| 83510 | 84007 | ** |
| 83511 | 84008 | ** The R parameter is only used for STAT3 and STAT4 |
| 83512 | 84009 | */ |
| 83513 | 84010 | static void statPush( |
| 83514 | 84011 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | ||
| 83598 | 84095 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 83599 | 84096 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 83600 | 84097 | |
| 83601 | 84098 | /* |
| 83602 | 84099 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 83603 | -** used to query the results. Content is returned for parameter J | |
| 84100 | +** used to query statistical information that has been gathered into | |
| 84101 | +** the Stat4Accum object by prior calls to stat_push(). The P parameter | |
| 84102 | +** is a BLOB which is decoded into a pointer to the Stat4Accum objects. | |
| 84103 | +** The content to returned is determined by the parameter J | |
| 83604 | 84104 | ** which is one of the STAT_GET_xxxx values defined above. |
| 83605 | 84105 | ** |
| 83606 | 84106 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 83607 | 84107 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 83608 | 84108 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | ||
| 83817 | 84317 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 83818 | 84318 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 83819 | 84319 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 83820 | 84320 | |
| 83821 | 84321 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 83822 | - int nCol; /* Number of columns indexed by pIdx */ | |
| 83823 | - int *aGotoChng; /* Array of jump instruction addresses */ | |
| 84322 | + int nCol; /* Number of columns in pIdx. "N" */ | |
| 83824 | 84323 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 83825 | - int addrGotoChng0; /* Address of "Goto addr_chng_0" */ | |
| 83826 | 84324 | int addrNextRow; /* Address of "next_row:" */ |
| 83827 | 84325 | const char *zIdxName; /* Name of the index */ |
| 84326 | + int nColTest; /* Number of columns to test for changes */ | |
| 83828 | 84327 | |
| 83829 | 84328 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 83830 | 84329 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 83831 | 84330 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 83832 | 84331 | nCol = pIdx->nKeyCol; |
| 83833 | 84332 | zIdxName = pTab->zName; |
| 84333 | + nColTest = nCol - 1; | |
| 83834 | 84334 | }else{ |
| 83835 | 84335 | nCol = pIdx->nColumn; |
| 83836 | 84336 | zIdxName = pIdx->zName; |
| 84337 | + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; | |
| 83837 | 84338 | } |
| 83838 | - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); | |
| 83839 | - if( aGotoChng==0 ) continue; | |
| 83840 | 84339 | |
| 83841 | 84340 | /* Populate the register containing the index name. */ |
| 83842 | 84341 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 83843 | 84342 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 83844 | 84343 | |
| @@ -83863,11 +84362,11 @@ | ||
| 83863 | 84362 | ** regPrev(0) = idx(0) |
| 83864 | 84363 | ** chng_addr_1: |
| 83865 | 84364 | ** regPrev(1) = idx(1) |
| 83866 | 84365 | ** ... |
| 83867 | 84366 | ** |
| 83868 | - ** chng_addr_N: | |
| 84367 | + ** endDistinctTest: | |
| 83869 | 84368 | ** regRowid = idx(rowid) |
| 83870 | 84369 | ** stat_push(P, regChng, regRowid) |
| 83871 | 84370 | ** Next csr |
| 83872 | 84371 | ** if !eof(csr) goto next_row; |
| 83873 | 84372 | ** |
| @@ -83876,24 +84375,27 @@ | ||
| 83876 | 84375 | |
| 83877 | 84376 | /* Make sure there are enough memory cells allocated to accommodate |
| 83878 | 84377 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 83879 | 84378 | ** when building a record to insert into the sample column of |
| 83880 | 84379 | ** the sqlite_stat4 table. */ |
| 83881 | - pParse->nMem = MAX(pParse->nMem, regPrev+nCol); | |
| 84380 | + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); | |
| 83882 | 84381 | |
| 83883 | 84382 | /* Open a read-only cursor on the index being analyzed. */ |
| 83884 | 84383 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 83885 | 84384 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 83886 | 84385 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 83887 | 84386 | VdbeComment((v, "%s", pIdx->zName)); |
| 83888 | 84387 | |
| 83889 | 84388 | /* Invoke the stat_init() function. The arguments are: |
| 83890 | 84389 | ** |
| 83891 | - ** (1) the number of columns in the index including the rowid, | |
| 83892 | - ** (2) the number of rows in the index, | |
| 84390 | + ** (1) the number of columns in the index including the rowid | |
| 84391 | + ** (or for a WITHOUT ROWID table, the number of PK columns), | |
| 84392 | + ** (2) the number of columns in the key without the rowid/pk | |
| 84393 | + ** (3) the number of rows in the index, | |
| 83893 | 84394 | ** |
| 83894 | - ** The second argument is only used for STAT3 and STAT4 | |
| 84395 | + ** | |
| 84396 | + ** The third argument is only used for STAT3 and STAT4 | |
| 83895 | 84397 | */ |
| 83896 | 84398 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83897 | 84399 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 83898 | 84400 | #endif |
| 83899 | 84401 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | ||
| 83911 | 84413 | ** |
| 83912 | 84414 | */ |
| 83913 | 84415 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 83914 | 84416 | VdbeCoverage(v); |
| 83915 | 84417 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 83916 | - addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 83917 | - | |
| 83918 | - /* | |
| 83919 | - ** next_row: | |
| 83920 | - ** regChng = 0 | |
| 83921 | - ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 83922 | - ** regChng = 1 | |
| 83923 | - ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 83924 | - ** ... | |
| 83925 | - ** regChng = N | |
| 83926 | - ** goto chng_addr_N | |
| 83927 | - */ | |
| 83928 | 84418 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 83929 | - for(i=0; i<nCol; i++){ | |
| 83930 | - char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | |
| 83931 | - sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | |
| 83932 | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | |
| 83933 | - aGotoChng[i] = | |
| 83934 | - sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | |
| 83935 | - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); | |
| 83936 | - VdbeCoverage(v); | |
| 83937 | - } | |
| 83938 | - sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); | |
| 83939 | - aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 83940 | - | |
| 83941 | - /* | |
| 83942 | - ** chng_addr_0: | |
| 83943 | - ** regPrev(0) = idx(0) | |
| 83944 | - ** chng_addr_1: | |
| 83945 | - ** regPrev(1) = idx(1) | |
| 83946 | - ** ... | |
| 83947 | - */ | |
| 83948 | - sqlite3VdbeJumpHere(v, addrGotoChng0); | |
| 83949 | - for(i=0; i<nCol; i++){ | |
| 83950 | - sqlite3VdbeJumpHere(v, aGotoChng[i]); | |
| 83951 | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); | |
| 83952 | - } | |
| 83953 | - | |
| 84419 | + | |
| 84420 | + if( nColTest>0 ){ | |
| 84421 | + int endDistinctTest = sqlite3VdbeMakeLabel(v); | |
| 84422 | + int *aGotoChng; /* Array of jump instruction addresses */ | |
| 84423 | + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); | |
| 84424 | + if( aGotoChng==0 ) continue; | |
| 84425 | + | |
| 84426 | + /* | |
| 84427 | + ** next_row: | |
| 84428 | + ** regChng = 0 | |
| 84429 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 84430 | + ** regChng = 1 | |
| 84431 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 84432 | + ** ... | |
| 84433 | + ** regChng = N | |
| 84434 | + ** goto endDistinctTest | |
| 84435 | + */ | |
| 84436 | + sqlite3VdbeAddOp0(v, OP_Goto); | |
| 84437 | + addrNextRow = sqlite3VdbeCurrentAddr(v); | |
| 84438 | + if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ | |
| 84439 | + /* For a single-column UNIQUE index, once we have found a non-NULL | |
| 84440 | + ** row, we know that all the rest will be distinct, so skip | |
| 84441 | + ** subsequent distinctness tests. */ | |
| 84442 | + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); | |
| 84443 | + VdbeCoverage(v); | |
| 84444 | + } | |
| 84445 | + for(i=0; i<nColTest; i++){ | |
| 84446 | + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | |
| 84447 | + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | |
| 84448 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | |
| 84449 | + aGotoChng[i] = | |
| 84450 | + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | |
| 84451 | + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); | |
| 84452 | + VdbeCoverage(v); | |
| 84453 | + } | |
| 84454 | + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); | |
| 84455 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); | |
| 84456 | + | |
| 84457 | + | |
| 84458 | + /* | |
| 84459 | + ** chng_addr_0: | |
| 84460 | + ** regPrev(0) = idx(0) | |
| 84461 | + ** chng_addr_1: | |
| 84462 | + ** regPrev(1) = idx(1) | |
| 84463 | + ** ... | |
| 84464 | + */ | |
| 84465 | + sqlite3VdbeJumpHere(v, addrNextRow-1); | |
| 84466 | + for(i=0; i<nColTest; i++){ | |
| 84467 | + sqlite3VdbeJumpHere(v, aGotoChng[i]); | |
| 84468 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); | |
| 84469 | + } | |
| 84470 | + sqlite3VdbeResolveLabel(v, endDistinctTest); | |
| 84471 | + sqlite3DbFree(db, aGotoChng); | |
| 84472 | + } | |
| 84473 | + | |
| 83954 | 84474 | /* |
| 83955 | 84475 | ** chng_addr_N: |
| 83956 | 84476 | ** regRowid = idx(rowid) // STAT34 only |
| 83957 | 84477 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 83958 | 84478 | ** Next csr |
| 83959 | 84479 | ** if !eof(csr) goto next_row; |
| 83960 | 84480 | */ |
| 83961 | - sqlite3VdbeJumpHere(v, aGotoChng[nCol]); | |
| 83962 | 84481 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83963 | 84482 | assert( regRowid==(regStat4+2) ); |
| 83964 | 84483 | if( HasRowid(pTab) ){ |
| 83965 | 84484 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 83966 | 84485 | }else{ |
| @@ -84034,11 +84553,10 @@ | ||
| 84034 | 84553 | } |
| 84035 | 84554 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84036 | 84555 | |
| 84037 | 84556 | /* End of analysis */ |
| 84038 | 84557 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84039 | - sqlite3DbFree(db, aGotoChng); | |
| 84040 | 84558 | } |
| 84041 | 84559 | |
| 84042 | 84560 | |
| 84043 | 84561 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84044 | 84562 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | ||
| 84135 | 84653 | int i; |
| 84136 | 84654 | char *z, *zDb; |
| 84137 | 84655 | Table *pTab; |
| 84138 | 84656 | Index *pIdx; |
| 84139 | 84657 | Token *pTableName; |
| 84658 | + Vdbe *v; | |
| 84140 | 84659 | |
| 84141 | 84660 | /* Read the database schema. If an error occurs, leave an error message |
| 84142 | 84661 | ** and code in pParse and return NULL. */ |
| 84143 | 84662 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84144 | 84663 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | ||
| 84182 | 84701 | } |
| 84183 | 84702 | sqlite3DbFree(db, z); |
| 84184 | 84703 | } |
| 84185 | 84704 | } |
| 84186 | 84705 | } |
| 84706 | + v = sqlite3GetVdbe(pParse); | |
| 84707 | + if( v ) sqlite3VdbeAddOp0(v, OP_Expire); | |
| 84187 | 84708 | } |
| 84188 | 84709 | |
| 84189 | 84710 | /* |
| 84190 | 84711 | ** Used to pass information from the analyzer reader through to the |
| 84191 | 84712 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | ||
| 84240 | 84761 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84241 | 84762 | assert( pIndex!=0 ); |
| 84242 | 84763 | #else |
| 84243 | 84764 | if( pIndex ) |
| 84244 | 84765 | #endif |
| 84245 | - { | |
| 84246 | - if( strcmp(z, "unordered")==0 ){ | |
| 84766 | + while( z[0] ){ | |
| 84767 | + if( sqlite3_strglob("unordered*", z)==0 ){ | |
| 84247 | 84768 | pIndex->bUnordered = 1; |
| 84248 | 84769 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84249 | - int v32 = 0; | |
| 84250 | - sqlite3GetInt32(z+3, &v32); | |
| 84251 | - pIndex->szIdxRow = sqlite3LogEst(v32); | |
| 84770 | + pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); | |
| 84252 | 84771 | } |
| 84772 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 84773 | + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ | |
| 84774 | + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); | |
| 84775 | + } | |
| 84776 | +#endif | |
| 84777 | + while( z[0]!=0 && z[0]!=' ' ) z++; | |
| 84778 | + while( z[0]==' ' ) z++; | |
| 84253 | 84779 | } |
| 84254 | 84780 | } |
| 84255 | 84781 | |
| 84256 | 84782 | /* |
| 84257 | 84783 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | ||
| 84288 | 84814 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84289 | 84815 | } |
| 84290 | 84816 | z = argv[2]; |
| 84291 | 84817 | |
| 84292 | 84818 | if( pIndex ){ |
| 84819 | + pIndex->bUnordered = 0; | |
| 84293 | 84820 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84294 | 84821 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84295 | 84822 | }else{ |
| 84296 | 84823 | Index fakeIdx; |
| 84297 | 84824 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84825 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 84826 | + fakeIdx.pTable = pTable; | |
| 84827 | +#endif | |
| 84298 | 84828 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84299 | 84829 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84300 | 84830 | } |
| 84301 | 84831 | |
| 84302 | 84832 | return 0; |
| @@ -85568,10 +86098,23 @@ | ||
| 85568 | 86098 | } |
| 85569 | 86099 | #else |
| 85570 | 86100 | #define codeTableLocks(x) |
| 85571 | 86101 | #endif |
| 85572 | 86102 | |
| 86103 | +/* | |
| 86104 | +** Return TRUE if the given yDbMask object is empty - if it contains no | |
| 86105 | +** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() | |
| 86106 | +** macros when SQLITE_MAX_ATTACHED is greater than 30. | |
| 86107 | +*/ | |
| 86108 | +#if SQLITE_MAX_ATTACHED>30 | |
| 86109 | +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ | |
| 86110 | + int i; | |
| 86111 | + for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0; | |
| 86112 | + return 1; | |
| 86113 | +} | |
| 86114 | +#endif | |
| 86115 | + | |
| 85573 | 86116 | /* |
| 85574 | 86117 | ** This routine is called after a single SQL statement has been |
| 85575 | 86118 | ** parsed and a VDBE program to execute that statement has been |
| 85576 | 86119 | ** prepared. This routine puts the finishing touches on the |
| 85577 | 86120 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | ||
| 85604 | 86147 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 85605 | 86148 | ** set for each database that is used. Generate code to start a |
| 85606 | 86149 | ** transaction on each used database and to verify the schema cookie |
| 85607 | 86150 | ** on each used database. |
| 85608 | 86151 | */ |
| 85609 | - if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ | |
| 85610 | - yDbMask mask; | |
| 86152 | + if( db->mallocFailed==0 | |
| 86153 | + && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) | |
| 86154 | + ){ | |
| 85611 | 86155 | int iDb, i; |
| 85612 | 86156 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 85613 | 86157 | sqlite3VdbeJumpHere(v, 0); |
| 85614 | - for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ | |
| 85615 | - if( (mask & pParse->cookieMask)==0 ) continue; | |
| 86158 | + for(iDb=0; iDb<db->nDb; iDb++){ | |
| 86159 | + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; | |
| 85616 | 86160 | sqlite3VdbeUsesBtree(v, iDb); |
| 85617 | 86161 | sqlite3VdbeAddOp4Int(v, |
| 85618 | 86162 | OP_Transaction, /* Opcode */ |
| 85619 | 86163 | iDb, /* P1 */ |
| 85620 | - (mask & pParse->writeMask)!=0, /* P2 */ | |
| 86164 | + DbMaskTest(pParse->writeMask,iDb), /* P2 */ | |
| 85621 | 86165 | pParse->cookieValue[iDb], /* P3 */ |
| 85622 | 86166 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 85623 | 86167 | ); |
| 85624 | 86168 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 85625 | 86169 | } |
| @@ -85671,11 +86215,11 @@ | ||
| 85671 | 86215 | } |
| 85672 | 86216 | pParse->nTab = 0; |
| 85673 | 86217 | pParse->nMem = 0; |
| 85674 | 86218 | pParse->nSet = 0; |
| 85675 | 86219 | pParse->nVar = 0; |
| 85676 | - pParse->cookieMask = 0; | |
| 86220 | + DbMaskZero(pParse->cookieMask); | |
| 85677 | 86221 | } |
| 85678 | 86222 | |
| 85679 | 86223 | /* |
| 85680 | 86224 | ** Run the parser and code generator recursively in order to generate |
| 85681 | 86225 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | ||
| 88153 | 88697 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88154 | 88698 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88155 | 88699 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88156 | 88700 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88157 | 88701 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88158 | - pKey->nField - pIndex->nKeyCol); VdbeCoverage(v); | |
| 88702 | + pIndex->nKeyCol); VdbeCoverage(v); | |
| 88159 | 88703 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88160 | 88704 | }else{ |
| 88161 | 88705 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88162 | 88706 | } |
| 88163 | 88707 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | ||
| 89298 | 89842 | ** later, by sqlite3FinishCoding(). |
| 89299 | 89843 | */ |
| 89300 | 89844 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89301 | 89845 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89302 | 89846 | sqlite3 *db = pToplevel->db; |
| 89303 | - yDbMask mask; | |
| 89304 | 89847 | |
| 89305 | 89848 | assert( iDb>=0 && iDb<db->nDb ); |
| 89306 | 89849 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89307 | 89850 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89308 | 89851 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89309 | - mask = ((yDbMask)1)<<iDb; | |
| 89310 | - if( (pToplevel->cookieMask & mask)==0 ){ | |
| 89311 | - pToplevel->cookieMask |= mask; | |
| 89852 | + if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ | |
| 89853 | + DbMaskSet(pToplevel->cookieMask, iDb); | |
| 89312 | 89854 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89313 | 89855 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89314 | 89856 | sqlite3OpenTempDatabase(pToplevel); |
| 89315 | 89857 | } |
| 89316 | 89858 | } |
| @@ -89345,11 +89887,11 @@ | ||
| 89345 | 89887 | ** necessary to undo a write and the checkpoint should not be set. |
| 89346 | 89888 | */ |
| 89347 | 89889 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89348 | 89890 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89349 | 89891 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89350 | - pToplevel->writeMask |= ((yDbMask)1)<<iDb; | |
| 89892 | + DbMaskSet(pToplevel->writeMask, iDb); | |
| 89351 | 89893 | pToplevel->isMultiWrite |= setStatement; |
| 89352 | 89894 | } |
| 89353 | 89895 | |
| 89354 | 89896 | /* |
| 89355 | 89897 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | ||
| 98033 | 98575 | ** Note that the values returned are one less that the values that |
| 98034 | 98576 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98035 | 98577 | ** to support legacy SQL code. The safety level used to be boolean |
| 98036 | 98578 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98037 | 98579 | */ |
| 98038 | -static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ | |
| 98580 | +static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ | |
| 98039 | 98581 | /* 123456789 123456789 */ |
| 98040 | 98582 | static const char zText[] = "onoffalseyestruefull"; |
| 98041 | 98583 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98042 | 98584 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98043 | 98585 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | ||
| 98055 | 98597 | } |
| 98056 | 98598 | |
| 98057 | 98599 | /* |
| 98058 | 98600 | ** Interpret the given string as a boolean value. |
| 98059 | 98601 | */ |
| 98060 | -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){ | |
| 98602 | +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){ | |
| 98061 | 98603 | return getSafetyLevel(z,1,dflt)!=0; |
| 98062 | 98604 | } |
| 98063 | 98605 | |
| 98064 | 98606 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98065 | 98607 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | ||
| 98601 | 99143 | */ |
| 98602 | 99144 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 98603 | 99145 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 98604 | 99146 | i64 iLimit = -2; |
| 98605 | 99147 | if( zRight ){ |
| 98606 | - sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 99148 | + sqlite3DecOrHexToI64(zRight, &iLimit); | |
| 98607 | 99149 | if( iLimit<-1 ) iLimit = -1; |
| 98608 | 99150 | } |
| 98609 | 99151 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 98610 | 99152 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 98611 | 99153 | break; |
| @@ -98729,11 +99271,11 @@ | ||
| 98729 | 99271 | sqlite3_int64 sz; |
| 98730 | 99272 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 98731 | 99273 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 98732 | 99274 | if( zRight ){ |
| 98733 | 99275 | int ii; |
| 98734 | - sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 99276 | + sqlite3DecOrHexToI64(zRight, &sz); | |
| 98735 | 99277 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 98736 | 99278 | if( pId2->n==0 ) db->szMmap = sz; |
| 98737 | 99279 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 98738 | 99280 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 98739 | 99281 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | ||
| 99772 | 100314 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 99773 | 100315 | ** use -1. |
| 99774 | 100316 | */ |
| 99775 | 100317 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 99776 | 100318 | sqlite3_int64 N; |
| 99777 | - if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ | |
| 100319 | + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ | |
| 99778 | 100320 | sqlite3_soft_heap_limit64(N); |
| 99779 | 100321 | } |
| 99780 | 100322 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 99781 | 100323 | break; |
| 99782 | 100324 | } |
| @@ -112245,11 +112787,12 @@ | ||
| 112245 | 112787 | int nEq = pLoop->u.btree.nEq; |
| 112246 | 112788 | sqlite3 *db = pParse->db; |
| 112247 | 112789 | int nLower = -1; |
| 112248 | 112790 | int nUpper = p->nSample+1; |
| 112249 | 112791 | int rc = SQLITE_OK; |
| 112250 | - u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity; | |
| 112792 | + int iCol = p->aiColumn[nEq]; | |
| 112793 | + u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; | |
| 112251 | 112794 | CollSeq *pColl; |
| 112252 | 112795 | |
| 112253 | 112796 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112254 | 112797 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112255 | 112798 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | ||
| 113620 | 114163 | int regRowid = 0; /* Register holding rowid */ |
| 113621 | 114164 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 113622 | 114165 | int iRetInit; /* Address of regReturn init */ |
| 113623 | 114166 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 113624 | 114167 | int ii; /* Loop counter */ |
| 114168 | + u16 wctrlFlags; /* Flags for sub-WHERE clause */ | |
| 113625 | 114169 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 113626 | 114170 | Table *pTab = pTabItem->pTab; |
| 113627 | 114171 | |
| 113628 | 114172 | pTerm = pLoop->aLTerm[0]; |
| 113629 | 114173 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | ||
| 113715 | 114259 | |
| 113716 | 114260 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 113717 | 114261 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 113718 | 114262 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 113719 | 114263 | */ |
| 114264 | + wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | | |
| 114265 | + WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY; | |
| 113720 | 114266 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 113721 | 114267 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 113722 | 114268 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 113723 | 114269 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113724 | 114270 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | ||
| 113727 | 114273 | pAndExpr->pLeft = pOrExpr; |
| 113728 | 114274 | pOrExpr = pAndExpr; |
| 113729 | 114275 | } |
| 113730 | 114276 | /* Loop through table entries that match term pOrTerm. */ |
| 113731 | 114277 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 113732 | - WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | | |
| 113733 | - WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); | |
| 114278 | + wctrlFlags, iCovCur); | |
| 113734 | 114279 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 113735 | 114280 | if( pSubWInfo ){ |
| 113736 | 114281 | WhereLoop *pSubLoop; |
| 113737 | 114282 | explainOneScan( |
| 113738 | 114283 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | ||
| 113819 | 114364 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 113820 | 114365 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 113821 | 114366 | ){ |
| 113822 | 114367 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 113823 | 114368 | pCov = pSubLoop->u.btree.pIndex; |
| 114369 | + wctrlFlags |= WHERE_REOPEN_IDX; | |
| 113824 | 114370 | }else{ |
| 113825 | 114371 | pCov = 0; |
| 113826 | 114372 | } |
| 113827 | 114373 | |
| 113828 | 114374 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | ||
| 114425 | 114971 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114426 | 114972 | } |
| 114427 | 114973 | } |
| 114428 | 114974 | } |
| 114429 | 114975 | |
| 114976 | +/* | |
| 114977 | +** Adjust the cost C by the costMult facter T. This only occurs if | |
| 114978 | +** compiled with -DSQLITE_ENABLE_COSTMULT | |
| 114979 | +*/ | |
| 114980 | +#ifdef SQLITE_ENABLE_COSTMULT | |
| 114981 | +# define ApplyCostMultiplier(C,T) C += T | |
| 114982 | +#else | |
| 114983 | +# define ApplyCostMultiplier(C,T) | |
| 114984 | +#endif | |
| 114985 | + | |
| 114430 | 114986 | /* |
| 114431 | 114987 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114432 | 114988 | ** index pIndex. Try to match one more. |
| 114433 | 114989 | ** |
| 114434 | 114990 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | ||
| 114621 | 115177 | testcase( eOp & WO_ISNULL ); |
| 114622 | 115178 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 114623 | 115179 | }else{ |
| 114624 | 115180 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 114625 | 115181 | } |
| 114626 | - assert( rc!=SQLITE_OK || nOut>0 ); | |
| 114627 | 115182 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 114628 | 115183 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 114629 | 115184 | if( nOut ){ |
| 114630 | 115185 | pNew->nOut = sqlite3LogEst(nOut); |
| 114631 | 115186 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | ||
| 114653 | 115208 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 114654 | 115209 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 114655 | 115210 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 114656 | 115211 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 114657 | 115212 | } |
| 115213 | + ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); | |
| 114658 | 115214 | |
| 114659 | 115215 | nOutUnadjusted = pNew->nOut; |
| 114660 | 115216 | pNew->rRun += nInMul + nIn; |
| 114661 | 115217 | pNew->nOut += nInMul + nIn; |
| 114662 | 115218 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | ||
| 114772 | 115328 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 114773 | 115329 | ** |
| 114774 | 115330 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 114775 | 115331 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 114776 | 115332 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 115333 | +** | |
| 115334 | +** The estimated values (nRow, nVisit, nSeek) often contain a large amount | |
| 115335 | +** of uncertainty. For this reason, scoring is designed to pick plans that | |
| 115336 | +** "do the least harm" if the estimates are inaccurate. For example, a | |
| 115337 | +** log(nRow) factor is omitted from a non-covering index scan in order to | |
| 115338 | +** bias the scoring in favor of using an index, since the worst-case | |
| 115339 | +** performance of using an index is far better than the worst-case performance | |
| 115340 | +** of a full table scan. | |
| 114777 | 115341 | */ |
| 114778 | 115342 | static int whereLoopAddBtree( |
| 114779 | 115343 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114780 | 115344 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114781 | 115345 | ){ |
| @@ -114859,10 +115423,11 @@ | ||
| 114859 | 115423 | pNew->aLTerm[0] = pTerm; |
| 114860 | 115424 | /* TUNING: One-time cost for computing the automatic index is |
| 114861 | 115425 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 114862 | 115426 | ** the table being indexed. */ |
| 114863 | 115427 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 115428 | + ApplyCostMultiplier(pNew->rSetup, pTab->costMult); | |
| 114864 | 115429 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 114865 | 115430 | ** is more than the usual guess of 10 rows, since we have no way |
| 114866 | 115431 | ** of knowning how selective the index will ultimately be. It would |
| 114867 | 115432 | ** not be unreasonable to make this value much larger. */ |
| 114868 | 115433 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | ||
| 114900 | 115465 | |
| 114901 | 115466 | /* Full table scan */ |
| 114902 | 115467 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114903 | 115468 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 114904 | 115469 | pNew->rRun = rSize + 16; |
| 115470 | + ApplyCostMultiplier(pNew->rRun, pTab->costMult); | |
| 114905 | 115471 | whereLoopOutputAdjust(pWC, pNew); |
| 114906 | 115472 | rc = whereLoopInsert(pBuilder, pNew); |
| 114907 | 115473 | pNew->nOut = rSize; |
| 114908 | 115474 | if( rc ) break; |
| 114909 | 115475 | }else{ |
| @@ -114935,11 +115501,11 @@ | ||
| 114935 | 115501 | ** also add the cost of visiting table rows (N*3.0). */ |
| 114936 | 115502 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114937 | 115503 | if( m!=0 ){ |
| 114938 | 115504 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 114939 | 115505 | } |
| 114940 | - | |
| 115506 | + ApplyCostMultiplier(pNew->rRun, pTab->costMult); | |
| 114941 | 115507 | whereLoopOutputAdjust(pWC, pNew); |
| 114942 | 115508 | rc = whereLoopInsert(pBuilder, pNew); |
| 114943 | 115509 | pNew->nOut = rSize; |
| 114944 | 115510 | if( rc ) break; |
| 114945 | 115511 | } |
| @@ -116410,10 +116976,11 @@ | ||
| 116410 | 116976 | } |
| 116411 | 116977 | op = OP_OpenWrite; |
| 116412 | 116978 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116413 | 116979 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116414 | 116980 | iIndexCur = iIdxCur; |
| 116981 | + if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; | |
| 116415 | 116982 | }else{ |
| 116416 | 116983 | iIndexCur = pParse->nTab++; |
| 116417 | 116984 | } |
| 116418 | 116985 | pLevel->iIdxCur = iIndexCur; |
| 116419 | 116986 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | ||
| 120734 | 121301 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 120735 | 121302 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 120736 | 121303 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 120737 | 121304 | testcase( z[0]=='9' ); |
| 120738 | 121305 | *tokenType = TK_INTEGER; |
| 121306 | +#ifndef SQLITE_OMIT_HEX_INTEGER | |
| 121307 | + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ | |
| 121308 | + for(i=3; sqlite3Isxdigit(z[i]); i++){} | |
| 121309 | + return i; | |
| 121310 | + } | |
| 121311 | +#endif | |
| 120739 | 121312 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 120740 | 121313 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 120741 | 121314 | if( z[i]=='.' ){ |
| 120742 | 121315 | i++; |
| 120743 | 121316 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | ||
| 122410 | 122983 | |
| 122411 | 122984 | /* |
| 122412 | 122985 | ** Return a static string containing the name corresponding to the error code |
| 122413 | 122986 | ** specified in the argument. |
| 122414 | 122987 | */ |
| 122415 | -#if defined(SQLITE_TEST) | |
| 122988 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | |
| 122416 | 122989 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122417 | 122990 | const char *zName = 0; |
| 122418 | 122991 | int i, origRc = rc; |
| 122419 | 122992 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122420 | 122993 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | ||
| 123455 | 124028 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 123456 | 124029 | #endif |
| 123457 | 124030 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 123458 | 124031 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 123459 | 124032 | #endif |
| 123460 | -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 | |
| 123461 | -# error SQLITE_MAX_ATTACHED must be between 0 and 62 | |
| 124033 | +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 | |
| 124034 | +# error SQLITE_MAX_ATTACHED must be between 0 and 125 | |
| 123462 | 124035 | #endif |
| 123463 | 124036 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 123464 | 124037 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 123465 | 124038 | #endif |
| 123466 | 124039 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | ||
| 124715 | 125288 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 124716 | 125289 | #endif |
| 124717 | 125290 | break; |
| 124718 | 125291 | } |
| 124719 | 125292 | |
| 125293 | + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); | |
| 125294 | + ** | |
| 125295 | + ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if | |
| 125296 | + ** not. | |
| 125297 | + */ | |
| 125298 | + case SQLITE_TESTCTRL_ISINIT: { | |
| 125299 | + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; | |
| 125300 | + break; | |
| 125301 | + } | |
| 125302 | + | |
| 124720 | 125303 | } |
| 124721 | 125304 | va_end(ap); |
| 124722 | 125305 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 124723 | 125306 | return rc; |
| 124724 | 125307 | } |
| @@ -124763,11 +125346,11 @@ | ||
| 124763 | 125346 | const char *zParam, /* URI parameter sought */ |
| 124764 | 125347 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 124765 | 125348 | ){ |
| 124766 | 125349 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 124767 | 125350 | sqlite3_int64 v; |
| 124768 | - if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ | |
| 125351 | + if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ | |
| 124769 | 125352 | bDflt = v; |
| 124770 | 125353 | } |
| 124771 | 125354 | return bDflt; |
| 124772 | 125355 | } |
| 124773 | 125356 | |
| @@ -126294,11 +126877,11 @@ | ||
| 126294 | 126877 | |
| 126295 | 126878 | /* fts3_tokenize_vtab.c */ |
| 126296 | 126879 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126297 | 126880 | |
| 126298 | 126881 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126299 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 126882 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 126300 | 126883 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126301 | 126884 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126302 | 126885 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126303 | 126886 | #endif |
| 126304 | 126887 | |
| @@ -129764,11 +130347,11 @@ | ||
| 129764 | 130347 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 129765 | 130348 | ** And so on. |
| 129766 | 130349 | */ |
| 129767 | 130350 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129768 | 130351 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129769 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130352 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129770 | 130353 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 129771 | 130354 | #endif |
| 129772 | 130355 | #ifdef SQLITE_ENABLE_ICU |
| 129773 | 130356 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129774 | 130357 | #endif |
| @@ -129782,20 +130365,20 @@ | ||
| 129782 | 130365 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 129783 | 130366 | int rc = SQLITE_OK; |
| 129784 | 130367 | Fts3Hash *pHash = 0; |
| 129785 | 130368 | const sqlite3_tokenizer_module *pSimple = 0; |
| 129786 | 130369 | const sqlite3_tokenizer_module *pPorter = 0; |
| 129787 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130370 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129788 | 130371 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 129789 | 130372 | #endif |
| 129790 | 130373 | |
| 129791 | 130374 | #ifdef SQLITE_ENABLE_ICU |
| 129792 | 130375 | const sqlite3_tokenizer_module *pIcu = 0; |
| 129793 | 130376 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 129794 | 130377 | #endif |
| 129795 | 130378 | |
| 129796 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130379 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129797 | 130380 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 129798 | 130381 | #endif |
| 129799 | 130382 | |
| 129800 | 130383 | #ifdef SQLITE_TEST |
| 129801 | 130384 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | ||
| 129819 | 130402 | /* Load the built-in tokenizers into the hash table */ |
| 129820 | 130403 | if( rc==SQLITE_OK ){ |
| 129821 | 130404 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 129822 | 130405 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 129823 | 130406 | |
| 129824 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 130407 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 129825 | 130408 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 129826 | 130409 | #endif |
| 129827 | 130410 | #ifdef SQLITE_ENABLE_ICU |
| 129828 | 130411 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 129829 | 130412 | #endif |
| @@ -143079,11 +143662,11 @@ | ||
| 143079 | 143662 | ****************************************************************************** |
| 143080 | 143663 | ** |
| 143081 | 143664 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143082 | 143665 | */ |
| 143083 | 143666 | |
| 143084 | -#ifdef SQLITE_ENABLE_FTS4_UNICODE61 | |
| 143667 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 143085 | 143668 | |
| 143086 | 143669 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143087 | 143670 | |
| 143088 | 143671 | /* #include <assert.h> */ |
| 143089 | 143672 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | ||
| 143295 | 143878 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143296 | 143879 | pNew->bRemoveDiacritic = 1; |
| 143297 | 143880 | |
| 143298 | 143881 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143299 | 143882 | const char *z = azArg[i]; |
| 143300 | - int n = strlen(z); | |
| 143883 | + int n = (int)strlen(z); | |
| 143301 | 143884 | |
| 143302 | 143885 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143303 | 143886 | pNew->bRemoveDiacritic = 1; |
| 143304 | 143887 | } |
| 143305 | 143888 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | ||
| 143427 | 144010 | }while( unicodeIsAlnum(p, iCode) |
| 143428 | 144011 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 143429 | 144012 | ); |
| 143430 | 144013 | |
| 143431 | 144014 | /* Set the output variables and return. */ |
| 143432 | - pCsr->iOff = (z - pCsr->aInput); | |
| 144015 | + pCsr->iOff = (int)(z - pCsr->aInput); | |
| 143433 | 144016 | *paToken = pCsr->zToken; |
| 143434 | - *pnToken = zOut - pCsr->zToken; | |
| 143435 | - *piStart = (zStart - pCsr->aInput); | |
| 143436 | - *piEnd = (zEnd - pCsr->aInput); | |
| 144017 | + *pnToken = (int)(zOut - pCsr->zToken); | |
| 144018 | + *piStart = (int)(zStart - pCsr->aInput); | |
| 144019 | + *piEnd = (int)(zEnd - pCsr->aInput); | |
| 143437 | 144020 | *piPos = pCsr->iToken++; |
| 143438 | 144021 | return SQLITE_OK; |
| 143439 | 144022 | } |
| 143440 | 144023 | |
| 143441 | 144024 | /* |
| @@ -143454,11 +144037,11 @@ | ||
| 143454 | 144037 | }; |
| 143455 | 144038 | *ppModule = &module; |
| 143456 | 144039 | } |
| 143457 | 144040 | |
| 143458 | 144041 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 143459 | -#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ | |
| 144042 | +#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ | |
| 143460 | 144043 | |
| 143461 | 144044 | /************** End of fts3_unicode.c ****************************************/ |
| 143462 | 144045 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 143463 | 144046 | /* |
| 143464 | 144047 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | ||
| 143475 | 144058 | |
| 143476 | 144059 | /* |
| 143477 | 144060 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 143478 | 144061 | */ |
| 143479 | 144062 | |
| 143480 | -#if defined(SQLITE_ENABLE_FTS4_UNICODE61) | |
| 144063 | +#ifndef SQLITE_DISABLE_FTS3_UNICODE | |
| 143481 | 144064 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 143482 | 144065 | |
| 143483 | 144066 | /* #include <assert.h> */ |
| 143484 | 144067 | |
| 143485 | 144068 | /* |
| @@ -143822,11 +144405,11 @@ | ||
| 143822 | 144405 | } |
| 143823 | 144406 | |
| 143824 | 144407 | return ret; |
| 143825 | 144408 | } |
| 143826 | 144409 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 143827 | -#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ | |
| 144410 | +#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ | |
| 143828 | 144411 | |
| 143829 | 144412 | /************** End of fts3_unicode2.c ***************************************/ |
| 143830 | 144413 | /************** Begin file rtree.c *******************************************/ |
| 143831 | 144414 | /* |
| 143832 | 144415 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | ||
| 145359 | 145942 | int rc = SQLITE_OK; |
| 145360 | 145943 | int iCell = 0; |
| 145361 | 145944 | |
| 145362 | 145945 | rtreeReference(pRtree); |
| 145363 | 145946 | |
| 145947 | + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ | |
| 145364 | 145948 | freeCursorConstraints(pCsr); |
| 145949 | + sqlite3_free(pCsr->aPoint); | |
| 145950 | + memset(pCsr, 0, sizeof(RtreeCursor)); | |
| 145951 | + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; | |
| 145952 | + | |
| 145365 | 145953 | pCsr->iStrategy = idxNum; |
| 145366 | - | |
| 145367 | 145954 | if( idxNum==1 ){ |
| 145368 | 145955 | /* Special case - lookup by rowid. */ |
| 145369 | 145956 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145370 | 145957 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145371 | 145958 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145372 | 145959 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -2150,31 +2150,37 @@ | |
| 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | |
| 2152 | /* |
| 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | ** |
| 2155 | ** ^This routine sets a callback function that might be invoked whenever |
| 2156 | ** an attempt is made to open a database table that another thread |
| 2157 | ** or process has locked. |
| 2158 | ** |
| 2159 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2160 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2161 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2162 | ** |
| 2163 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2164 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2165 | ** the busy handler callback is the number of times that the busy handler has |
| 2166 | ** been invoked for this locking event. ^If the |
| 2167 | ** busy callback returns 0, then no additional attempts are made to |
| 2168 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. |
| 2169 | ** ^If the callback returns non-zero, then another attempt |
| 2170 | ** is made to open the database for reading and the cycle repeats. |
| 2171 | ** |
| 2172 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2173 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2174 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2175 | ** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. |
| 2176 | ** Consider a scenario where one process is holding a read lock that |
| 2177 | ** it is trying to promote to a reserved lock and |
| 2178 | ** a second process is holding a reserved lock that it is trying |
| 2179 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2180 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | |
| 2202 | ** this is important. |
| 2203 | ** |
| 2204 | ** ^(There can only be a single busy handler defined for each |
| 2205 | ** [database connection]. Setting a new busy handler clears any |
| 2206 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2207 | ** will also set or clear the busy handler. |
| 2208 | ** |
| 2209 | ** The busy callback should not take any actions which modify the |
| 2210 | ** database connection that invoked the busy handler. Any such actions |
| 2211 | ** result in undefined behavior. |
| 2212 | ** |
| 2213 | ** A busy handler must not close the database connection |
| 2214 | ** or [prepared statement] that invoked the busy handler. |
| 2215 | */ |
| @@ -2230,10 +2238,12 @@ | |
| 2230 | ** |
| 2231 | ** ^(There can only be a single busy handler for a particular |
| 2232 | ** [database connection] any any given moment. If another busy handler |
| 2233 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2234 | ** this routine, that other busy handler is cleared.)^ |
| 2235 | */ |
| 2236 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2237 | |
| 2238 | /* |
| 2239 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | |
| 4818 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4819 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4820 | ** will be placed in that directory.)^ ^If this variable |
| 4821 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4822 | ** temporary file directory. |
| 4823 | ** |
| 4824 | ** It is not safe to read or modify this variable in more than one |
| 4825 | ** thread at a time. It is not safe to read or modify this variable |
| 4826 | ** if a [database connection] is being used at the same time in a separate |
| 4827 | ** thread. |
| @@ -4837,10 +4854,15 @@ | |
| 4837 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4838 | ** using [sqlite3_free]. |
| 4839 | ** Hence, if this variable is modified directly, either it should be |
| 4840 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4841 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4842 | ** |
| 4843 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4844 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4845 | ** features that require the use of temporary files may fail. Here is an |
| 4846 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | |
| 5971 | ** <ul> |
| 5972 | ** <li> SQLITE_MUTEX_FAST |
| 5973 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5974 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5975 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5976 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 5977 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5978 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5979 | ** <li> SQLITE_MUTEX_STATIC_LRU2 |
| 5980 | ** </ul>)^ |
| 5981 | ** |
| 5982 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5983 | ** cause sqlite3_mutex_alloc() to create |
| 5984 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | |
| 6178 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6179 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6180 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6181 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6182 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6183 | |
| 6184 | /* |
| 6185 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6186 | ** |
| 6187 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | |
| 6273 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6274 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6275 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6276 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6277 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6278 | #define SQLITE_TESTCTRL_LAST 22 |
| 6279 | |
| 6280 | /* |
| 6281 | ** CAPI3REF: SQLite Runtime Status |
| 6282 | ** |
| 6283 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | |
| 7256 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7257 | ** configured by this function. |
| 7258 | ** |
| 7259 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7260 | ** from SQL. |
| 7261 | ** |
| 7262 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7263 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7264 | ** pages. The use of this interface |
| 7265 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | |
| 7273 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7274 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7275 | ** empty string, then a checkpoint is run on all databases of |
| 7276 | ** connection D. ^If the database connection D is not in |
| 7277 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7278 | ** |
| 7279 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7280 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7281 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7282 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | |
| 7295 | ** <dl> |
| 7296 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7297 | ** Checkpoint as many frames as possible without waiting for any database |
| 7298 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7299 | ** are checkpointed. This mode is the same as calling |
| 7300 | ** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. |
| 7301 | ** |
| 7302 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7303 | ** This mode blocks (calls the busy-handler callback) until there is no |
| 7304 | ** database writer and all readers are reading from the most recent database |
| 7305 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7306 | ** database file. This call blocks database writers while it is running, |
| 7307 | ** but not database readers. |
| 7308 | ** |
| 7309 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7310 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7311 | ** checkpointing the log file it blocks (calls the busy-handler callback) |
| 7312 | ** until all readers are reading from the database file only. This ensures |
| 7313 | ** that the next client to write to the database file restarts the log file |
| 7314 | ** from the beginning. This call blocks database writers while it is running, |
| 7315 | ** but not database readers. |
| 7316 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | |
| 9285 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9286 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9287 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9288 | #define OP_ReadCookie 50 |
| 9289 | #define OP_SetCookie 51 |
| 9290 | #define OP_OpenRead 52 /* synopsis: root=P2 iDb=P3 */ |
| 9291 | #define OP_OpenWrite 53 /* synopsis: root=P2 iDb=P3 */ |
| 9292 | #define OP_OpenAutoindex 54 /* synopsis: nColumn=P2 */ |
| 9293 | #define OP_OpenEphemeral 55 /* synopsis: nColumn=P2 */ |
| 9294 | #define OP_SorterOpen 56 |
| 9295 | #define OP_OpenPseudo 57 /* synopsis: P3 columns in r[P2] */ |
| 9296 | #define OP_Close 58 |
| 9297 | #define OP_SeekLT 59 |
| 9298 | #define OP_SeekLE 60 |
| 9299 | #define OP_SeekGE 61 |
| 9300 | #define OP_SeekGT 62 |
| 9301 | #define OP_Seek 63 /* synopsis: intkey=r[P2] */ |
| 9302 | #define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ |
| 9303 | #define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ |
| 9304 | #define OP_Found 66 /* synopsis: key=r[P3@P4] */ |
| 9305 | #define OP_NotExists 67 /* synopsis: intkey=r[P3] */ |
| 9306 | #define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9307 | #define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ |
| 9308 | #define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9309 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9310 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9311 | #define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ |
| 9312 | #define OP_Delete 74 |
| 9313 | #define OP_ResetCount 75 |
| 9314 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9315 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9316 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9317 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9318 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9319 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9320 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9321 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9322 | #define OP_SorterCompare 84 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ |
| 9323 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9324 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9325 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9326 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9327 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | |
| 9328 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9329 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9330 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9331 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9332 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9333 | #define OP_SorterData 95 /* synopsis: r[P2]=data */ |
| 9334 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9335 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9336 | #define OP_RowKey 98 /* synopsis: r[P2]=key */ |
| 9337 | #define OP_RowData 99 /* synopsis: r[P2]=data */ |
| 9338 | #define OP_Rowid 100 /* synopsis: r[P2]=rowid */ |
| 9339 | #define OP_NullRow 101 |
| 9340 | #define OP_Last 102 |
| 9341 | #define OP_SorterSort 103 |
| 9342 | #define OP_Sort 104 |
| 9343 | #define OP_Rewind 105 |
| 9344 | #define OP_SorterInsert 106 |
| 9345 | #define OP_IdxInsert 107 /* synopsis: key=r[P2] */ |
| 9346 | #define OP_IdxDelete 108 /* synopsis: key=r[P2@P3] */ |
| 9347 | #define OP_IdxRowid 109 /* synopsis: r[P2]=rowid */ |
| 9348 | #define OP_IdxLE 110 /* synopsis: key=r[P3@P4] */ |
| 9349 | #define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ |
| 9350 | #define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ |
| 9351 | #define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ |
| 9352 | #define OP_Destroy 114 |
| 9353 | #define OP_Clear 115 |
| 9354 | #define OP_ResetSorter 116 |
| 9355 | #define OP_CreateIndex 117 /* synopsis: r[P2]=root iDb=P1 */ |
| 9356 | #define OP_CreateTable 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9357 | #define OP_ParseSchema 119 |
| 9358 | #define OP_LoadAnalysis 120 |
| 9359 | #define OP_DropTable 121 |
| 9360 | #define OP_DropIndex 122 |
| 9361 | #define OP_DropTrigger 123 |
| 9362 | #define OP_IntegrityCk 124 |
| 9363 | #define OP_RowSetAdd 125 /* synopsis: rowset(P1)=r[P2] */ |
| 9364 | #define OP_RowSetRead 126 /* synopsis: r[P3]=rowset(P1) */ |
| 9365 | #define OP_RowSetTest 127 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9366 | #define OP_Program 128 |
| 9367 | #define OP_Param 129 |
| 9368 | #define OP_FkCounter 130 /* synopsis: fkctr[P1]+=P2 */ |
| 9369 | #define OP_FkIfZero 131 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9370 | #define OP_MemMax 132 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9371 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9372 | #define OP_IfPos 134 /* synopsis: if r[P1]>0 goto P2 */ |
| 9373 | #define OP_IfNeg 135 /* synopsis: if r[P1]<0 goto P2 */ |
| 9374 | #define OP_IfZero 136 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9375 | #define OP_AggFinal 137 /* synopsis: accum=r[P1] N=P2 */ |
| 9376 | #define OP_IncrVacuum 138 |
| 9377 | #define OP_Expire 139 |
| 9378 | #define OP_TableLock 140 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9379 | #define OP_VBegin 141 |
| 9380 | #define OP_VCreate 142 |
| 9381 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9382 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9383 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9384 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9385 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9386 | #define OP_VDestroy 148 |
| 9387 | #define OP_VOpen 149 |
| 9388 | #define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9389 | #define OP_VNext 151 |
| 9390 | #define OP_VRename 152 |
| 9391 | #define OP_Pagecount 153 |
| 9392 | #define OP_MaxPgcnt 154 |
| 9393 | #define OP_Init 155 /* synopsis: Start at P2 */ |
| 9394 | #define OP_Noop 156 |
| 9395 | #define OP_Explain 157 |
| 9396 | |
| 9397 | |
| 9398 | /* Properties such as "out2" or "jump" that are specified in |
| 9399 | ** comments following the "case" for each opcode in the vdbe.c |
| 9400 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | |
| 9412 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9413 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9414 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9415 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9416 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9417 | /* 56 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\ |
| 9418 | /* 64 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c,\ |
| 9419 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9420 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9421 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9422 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ |
| 9423 | /* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ |
| 9424 | /* 112 */ 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,\ |
| 9425 | /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15,\ |
| 9426 | /* 128 */ 0x01, 0x02, 0x00, 0x01, 0x08, 0x02, 0x05, 0x05,\ |
| 9427 | /* 136 */ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,\ |
| 9428 | /* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01,\ |
| 9429 | /* 152 */ 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9430 | |
| 9431 | /************** End of opcodes.h *********************************************/ |
| 9432 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9433 | |
| 9434 | /* |
| @@ -10932,10 +10971,13 @@ | |
| 10932 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10933 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10934 | i16 nCol; /* Number of columns in this table */ |
| 10935 | u16 nRef; /* Number of pointers to this Table */ |
| 10936 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10937 | u8 tabFlags; /* Mask of TF_* values */ |
| 10938 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10939 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10940 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10941 | #endif |
| @@ -11591,10 +11633,11 @@ | |
| 11591 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11592 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11593 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11594 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11595 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11596 | |
| 11597 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11598 | */ |
| 11599 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11600 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | |
| 11847 | |
| 11848 | /* |
| 11849 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11850 | */ |
| 11851 | #if SQLITE_MAX_ATTACHED>30 |
| 11852 | typedef sqlite3_uint64 yDbMask; |
| 11853 | #else |
| 11854 | typedef unsigned int yDbMask; |
| 11855 | #endif |
| 11856 | |
| 11857 | /* |
| 11858 | ** An SQL parser context. A copy of this structure is passed through |
| 11859 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | |
| 12522 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12523 | #else |
| 12524 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12525 | #endif |
| 12526 | |
| 12527 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12528 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12529 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12530 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12531 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | |
| 12772 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12773 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12774 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12775 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12776 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12777 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12778 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12779 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12780 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12781 | |
| @@ -12801,11 +12858,11 @@ | |
| 12801 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12802 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12803 | #else |
| 12804 | # define sqlite3FileSuffix3(X,Y) |
| 12805 | #endif |
| 12806 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int); |
| 12807 | |
| 12808 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12809 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12810 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12811 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | |
| 13876 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13877 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13878 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13879 | i16 nField; /* Number of fields in the header */ |
| 13880 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13881 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13882 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13883 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13884 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13885 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13886 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13887 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13888 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13889 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13890 | i64 seqCount; /* Sequence counter */ |
| 13891 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13892 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13893 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | |
| 18396 | /* |
| 18397 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18398 | */ |
| 18399 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18400 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18401 | if( sqlite3_initialize() ) return 0; |
| 18402 | #endif |
| 18403 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18404 | } |
| 18405 | |
| 18406 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | |
| 18577 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18578 | ** mutex and returns a pointer to it. If it returns NULL |
| 18579 | ** that means that a mutex could not be allocated. |
| 18580 | */ |
| 18581 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18582 | static sqlite3_debug_mutex aStatic[6]; |
| 18583 | sqlite3_debug_mutex *pNew = 0; |
| 18584 | switch( id ){ |
| 18585 | case SQLITE_MUTEX_FAST: |
| 18586 | case SQLITE_MUTEX_RECURSIVE: { |
| 18587 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | |
| 18774 | ** <ul> |
| 18775 | ** <li> SQLITE_MUTEX_FAST |
| 18776 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18777 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18778 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18779 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 18780 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18781 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18782 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18783 | ** </ul> |
| 18784 | ** |
| 18785 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18786 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18787 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | |
| 18806 | ** mutex types, the same mutex is returned on every call that has |
| 18807 | ** the same type number. |
| 18808 | */ |
| 18809 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18810 | static sqlite3_mutex staticMutexes[] = { |
| 18811 | SQLITE3_MUTEX_INITIALIZER, |
| 18812 | SQLITE3_MUTEX_INITIALIZER, |
| 18813 | SQLITE3_MUTEX_INITIALIZER, |
| 18814 | SQLITE3_MUTEX_INITIALIZER, |
| 18815 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | |
| 19041 | ** May you do good and not evil. |
| 19042 | ** May you find forgiveness for yourself and forgive others. |
| 19043 | ** May you share freely, never taking more than you give. |
| 19044 | ** |
| 19045 | ************************************************************************* |
| 19046 | ** This file contains the C functions that implement mutexes for win32 |
| 19047 | */ |
| 19048 | |
| 19049 | #if SQLITE_OS_WIN |
| 19050 | /* |
| 19051 | ** Include the header file for the Windows VFS. |
| 19052 | */ |
| 19053 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19054 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | |
| 19124 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19125 | #endif |
| 19126 | |
| 19127 | /* |
| 19128 | ** The code in this file is only used if we are compiling multithreaded |
| 19129 | ** on a win32 system. |
| 19130 | */ |
| 19131 | #ifdef SQLITE_MUTEX_W32 |
| 19132 | |
| 19133 | /* |
| 19134 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | |
| 19137 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19138 | int id; /* Mutex type */ |
| 19139 | #ifdef SQLITE_DEBUG |
| 19140 | volatile int nRef; /* Number of enterances */ |
| 19141 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19142 | int trace; /* True to trace changes */ |
| 19143 | #endif |
| 19144 | }; |
| 19145 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19146 | #ifdef SQLITE_DEBUG |
| 19147 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } |
| 19148 | #else |
| 19149 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19150 | #endif |
| 19151 | |
| 19152 | /* |
| 19153 | ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
| 19154 | ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
| 19155 | ** |
| 19156 | ** Here is an interesting observation: Win95, Win98, and WinME lack |
| 19157 | ** the LockFileEx() API. But we can still statically link against that |
| 19158 | ** API as long as we don't call it win running Win95/98/ME. A call to |
| 19159 | ** this routine is used to determine if the host is Win95/98/ME or |
| 19160 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 19161 | ** the LockFileEx() API. |
| 19162 | ** |
| 19163 | ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, |
| 19164 | ** which is only available if your application was compiled with |
| 19165 | ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only |
| 19166 | ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef |
| 19167 | ** this out as well. |
| 19168 | */ |
| 19169 | #if 0 |
| 19170 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 19171 | # define mutexIsNT() (1) |
| 19172 | #else |
| 19173 | static int mutexIsNT(void){ |
| 19174 | static int osType = 0; |
| 19175 | if( osType==0 ){ |
| 19176 | OSVERSIONINFO sInfo; |
| 19177 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 19178 | GetVersionEx(&sInfo); |
| 19179 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 19180 | } |
| 19181 | return osType==2; |
| 19182 | } |
| 19183 | #endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ |
| 19184 | #endif |
| 19185 | |
| 19186 | #ifdef SQLITE_DEBUG |
| 19187 | /* |
| 19188 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19189 | ** intended for use only inside assert() statements. |
| 19190 | */ |
| 19191 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19192 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19193 | } |
| 19194 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19195 | return p->nRef==0 || p->owner!=tid; |
| 19196 | } |
| 19197 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19198 | DWORD tid = GetCurrentThreadId(); |
| 19199 | return winMutexNotheld2(p, tid); |
| 19200 | } |
| 19201 | #endif |
| 19202 | |
| 19203 | |
| 19204 | /* |
| 19205 | ** Initialize and deinitialize the mutex subsystem. |
| 19206 | */ |
| 19207 | static sqlite3_mutex winMutex_staticMutexes[6] = { |
| 19208 | SQLITE3_MUTEX_INITIALIZER, |
| 19209 | SQLITE3_MUTEX_INITIALIZER, |
| 19210 | SQLITE3_MUTEX_INITIALIZER, |
| 19211 | SQLITE3_MUTEX_INITIALIZER, |
| 19212 | SQLITE3_MUTEX_INITIALIZER, |
| 19213 | SQLITE3_MUTEX_INITIALIZER |
| 19214 | }; |
| 19215 | static int winMutex_isInit = 0; |
| 19216 | /* As winMutexInit() and winMutexEnd() are called as part |
| 19217 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 19218 | ** processing, the "interlocked" magic is probably not |
| 19219 | ** strictly necessary. |
| 19220 | */ |
| 19221 | static LONG winMutex_lock = 0; |
| 19222 | |
| 19223 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19224 | |
| 19225 | static int winMutexInit(void){ |
| 19226 | /* The first to increment to 1 does actual initialization */ |
| 19227 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19228 | int i; |
| 19229 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19230 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | |
| 19233 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19234 | #endif |
| 19235 | } |
| 19236 | winMutex_isInit = 1; |
| 19237 | }else{ |
| 19238 | /* Someone else is in the process of initing the static mutexes */ |
| 19239 | while( !winMutex_isInit ){ |
| 19240 | sqlite3_win32_sleep(1); |
| 19241 | } |
| 19242 | } |
| 19243 | return SQLITE_OK; |
| 19244 | } |
| 19245 | |
| 19246 | static int winMutexEnd(void){ |
| 19247 | /* The first to decrement to 0 does actual shutdown |
| 19248 | ** (which should be the last to shutdown.) */ |
| 19249 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19250 | if( winMutex_isInit==1 ){ |
| 19251 | int i; |
| 19252 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | |
| 19253 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19254 | } |
| 19255 | winMutex_isInit = 0; |
| 19256 | } |
| 19257 | } |
| 19258 | return SQLITE_OK; |
| 19259 | } |
| 19260 | |
| 19261 | /* |
| 19262 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19263 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | |
| 19268 | ** <ul> |
| 19269 | ** <li> SQLITE_MUTEX_FAST |
| 19270 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19271 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19272 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19273 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 19274 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19275 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19276 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19277 | ** </ul> |
| 19278 | ** |
| 19279 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19280 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19281 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | |
| 19294 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19295 | ** SQLITE_MUTEX_RECURSIVE. |
| 19296 | ** |
| 19297 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19298 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19299 | ** returns a different mutex on every call. But for the static |
| 19300 | ** mutex types, the same mutex is returned on every call that has |
| 19301 | ** the same type number. |
| 19302 | */ |
| 19303 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19304 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | |
| 19305 | |
| 19306 | switch( iType ){ |
| 19307 | case SQLITE_MUTEX_FAST: |
| 19308 | case SQLITE_MUTEX_RECURSIVE: { |
| 19309 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19310 | if( p ){ |
| 19311 | #ifdef SQLITE_DEBUG |
| 19312 | p->id = iType; |
| 19313 | #endif |
| 19314 | #if SQLITE_OS_WINRT |
| 19315 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19316 | #else |
| 19317 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | |
| 19318 | #endif |
| 19319 | } |
| 19320 | break; |
| 19321 | } |
| 19322 | default: { |
| 19323 | assert( winMutex_isInit==1 ); |
| 19324 | assert( iType-2 >= 0 ); |
| 19325 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19326 | p = &winMutex_staticMutexes[iType-2]; |
| 19327 | #ifdef SQLITE_DEBUG |
| 19328 | p->id = iType; |
| 19329 | #endif |
| 19330 | break; |
| 19331 | } |
| 19332 | } |
| 19333 | return p; |
| @@ -19339,12 +19610,15 @@ | |
| 19339 | ** allocated mutex. SQLite is careful to deallocate every |
| 19340 | ** mutex that it allocates. |
| 19341 | */ |
| 19342 | static void winMutexFree(sqlite3_mutex *p){ |
| 19343 | assert( p ); |
| 19344 | assert( p->nRef==0 && p->owner==0 ); |
| 19345 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19346 | DeleteCriticalSection(&p->mutex); |
| 19347 | sqlite3_free(p); |
| 19348 | } |
| 19349 | |
| 19350 | /* |
| @@ -19357,53 +19631,71 @@ | |
| 19357 | ** mutex must be exited an equal number of times before another thread |
| 19358 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19359 | ** more than once, the behavior is undefined. |
| 19360 | */ |
| 19361 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19362 | #ifdef SQLITE_DEBUG |
| 19363 | DWORD tid = GetCurrentThreadId(); |
| 19364 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19365 | #endif |
| 19366 | EnterCriticalSection(&p->mutex); |
| 19367 | #ifdef SQLITE_DEBUG |
| 19368 | assert( p->nRef>0 || p->owner==0 ); |
| 19369 | p->owner = tid; |
| 19370 | p->nRef++; |
| 19371 | if( p->trace ){ |
| 19372 | printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19373 | } |
| 19374 | #endif |
| 19375 | } |
| 19376 | static int winMutexTry(sqlite3_mutex *p){ |
| 19377 | #ifndef NDEBUG |
| 19378 | DWORD tid = GetCurrentThreadId(); |
| 19379 | #endif |
| 19380 | int rc = SQLITE_BUSY; |
| 19381 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19382 | /* |
| 19383 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19384 | ** is used it is merely an optimization. So it is OK for it to always |
| 19385 | ** fail. |
| 19386 | ** |
| 19387 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19388 | ** And some windows compilers complain if you try to use it without |
| 19389 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19390 | ** For that reason, we will omit this optimization for now. See |
| 19391 | ** ticket #2685. |
| 19392 | */ |
| 19393 | #if 0 |
| 19394 | if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ |
| 19395 | p->owner = tid; |
| 19396 | p->nRef++; |
| 19397 | rc = SQLITE_OK; |
| 19398 | } |
| 19399 | #else |
| 19400 | UNUSED_PARAMETER(p); |
| 19401 | #endif |
| 19402 | #ifdef SQLITE_DEBUG |
| 19403 | if( rc==SQLITE_OK && p->trace ){ |
| 19404 | printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19405 | } |
| 19406 | #endif |
| 19407 | return rc; |
| 19408 | } |
| 19409 | |
| @@ -19412,22 +19704,27 @@ | |
| 19412 | ** previously entered by the same thread. The behavior |
| 19413 | ** is undefined if the mutex is not currently entered or |
| 19414 | ** is not currently allocated. SQLite will never do either. |
| 19415 | */ |
| 19416 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19417 | #ifndef NDEBUG |
| 19418 | DWORD tid = GetCurrentThreadId(); |
| 19419 | assert( p->nRef>0 ); |
| 19420 | assert( p->owner==tid ); |
| 19421 | p->nRef--; |
| 19422 | if( p->nRef==0 ) p->owner = 0; |
| 19423 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19424 | #endif |
| 19425 | LeaveCriticalSection(&p->mutex); |
| 19426 | #ifdef SQLITE_DEBUG |
| 19427 | if( p->trace ){ |
| 19428 | printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 19429 | } |
| 19430 | #endif |
| 19431 | } |
| 19432 | |
| 19433 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | |
| 19445 | #else |
| 19446 | 0, |
| 19447 | 0 |
| 19448 | #endif |
| 19449 | }; |
| 19450 | |
| 19451 | return &sMutex; |
| 19452 | } |
| 19453 | #endif /* SQLITE_MUTEX_W32 */ |
| 19454 | |
| 19455 | /************** End of mutex_w32.c *******************************************/ |
| 19456 | /************** Begin file malloc.c ******************************************/ |
| 19457 | /* |
| @@ -22422,13 +22719,13 @@ | |
| 22422 | testcase( c==(+1) ); |
| 22423 | } |
| 22424 | return c; |
| 22425 | } |
| 22426 | |
| 22427 | |
| 22428 | /* |
| 22429 | ** Convert zNum to a 64-bit signed integer. |
| 22430 | ** |
| 22431 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22432 | ** integer, then write that value into *pNum and return 0. |
| 22433 | ** |
| 22434 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | |
| 22511 | assert( u-1==LARGEST_INT64 ); |
| 22512 | return neg ? 0 : 2; |
| 22513 | } |
| 22514 | } |
| 22515 | } |
| 22516 | |
| 22517 | /* |
| 22518 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22519 | ** *pValue to that integer and return true. Otherwise return false. |
| 22520 | ** |
| 22521 | ** Any non-numeric characters that following zNum are ignored. |
| 22522 | ** This is different from sqlite3Atoi64() which requires the |
| 22523 | ** input number to be zero-terminated. |
| 22524 | */ |
| @@ -22530,11 +22861,29 @@ | |
| 22530 | neg = 1; |
| 22531 | zNum++; |
| 22532 | }else if( zNum[0]=='+' ){ |
| 22533 | zNum++; |
| 22534 | } |
| 22535 | while( zNum[0]=='0' ) zNum++; |
| 22536 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22537 | v = v*10 + c; |
| 22538 | } |
| 22539 | |
| 22540 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | |
| 23606 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23607 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23608 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23609 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23610 | /* 51 */ "SetCookie" OpHelp(""), |
| 23611 | /* 52 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23612 | /* 53 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23613 | /* 54 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23614 | /* 55 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23615 | /* 56 */ "SorterOpen" OpHelp(""), |
| 23616 | /* 57 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 23617 | /* 58 */ "Close" OpHelp(""), |
| 23618 | /* 59 */ "SeekLT" OpHelp(""), |
| 23619 | /* 60 */ "SeekLE" OpHelp(""), |
| 23620 | /* 61 */ "SeekGE" OpHelp(""), |
| 23621 | /* 62 */ "SeekGT" OpHelp(""), |
| 23622 | /* 63 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23623 | /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23624 | /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23625 | /* 66 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23626 | /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23627 | /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23628 | /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23629 | /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23630 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23631 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23632 | /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23633 | /* 74 */ "Delete" OpHelp(""), |
| 23634 | /* 75 */ "ResetCount" OpHelp(""), |
| 23635 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23636 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23637 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23638 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23639 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23640 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23641 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23642 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23643 | /* 84 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), |
| 23644 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23645 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23646 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23647 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23648 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | |
| 23649 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23650 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 23651 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23652 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 23653 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 23654 | /* 95 */ "SorterData" OpHelp("r[P2]=data"), |
| 23655 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 23656 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 23657 | /* 98 */ "RowKey" OpHelp("r[P2]=key"), |
| 23658 | /* 99 */ "RowData" OpHelp("r[P2]=data"), |
| 23659 | /* 100 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 23660 | /* 101 */ "NullRow" OpHelp(""), |
| 23661 | /* 102 */ "Last" OpHelp(""), |
| 23662 | /* 103 */ "SorterSort" OpHelp(""), |
| 23663 | /* 104 */ "Sort" OpHelp(""), |
| 23664 | /* 105 */ "Rewind" OpHelp(""), |
| 23665 | /* 106 */ "SorterInsert" OpHelp(""), |
| 23666 | /* 107 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 23667 | /* 108 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 23668 | /* 109 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 23669 | /* 110 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 23670 | /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 23671 | /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 23672 | /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 23673 | /* 114 */ "Destroy" OpHelp(""), |
| 23674 | /* 115 */ "Clear" OpHelp(""), |
| 23675 | /* 116 */ "ResetSorter" OpHelp(""), |
| 23676 | /* 117 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23677 | /* 118 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23678 | /* 119 */ "ParseSchema" OpHelp(""), |
| 23679 | /* 120 */ "LoadAnalysis" OpHelp(""), |
| 23680 | /* 121 */ "DropTable" OpHelp(""), |
| 23681 | /* 122 */ "DropIndex" OpHelp(""), |
| 23682 | /* 123 */ "DropTrigger" OpHelp(""), |
| 23683 | /* 124 */ "IntegrityCk" OpHelp(""), |
| 23684 | /* 125 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23685 | /* 126 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23686 | /* 127 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23687 | /* 128 */ "Program" OpHelp(""), |
| 23688 | /* 129 */ "Param" OpHelp(""), |
| 23689 | /* 130 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23690 | /* 131 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23691 | /* 132 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23692 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23693 | /* 134 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 23694 | /* 135 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23695 | /* 136 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 23696 | /* 137 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23697 | /* 138 */ "IncrVacuum" OpHelp(""), |
| 23698 | /* 139 */ "Expire" OpHelp(""), |
| 23699 | /* 140 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23700 | /* 141 */ "VBegin" OpHelp(""), |
| 23701 | /* 142 */ "VCreate" OpHelp(""), |
| 23702 | /* 143 */ "ToText" OpHelp(""), |
| 23703 | /* 144 */ "ToBlob" OpHelp(""), |
| 23704 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23705 | /* 146 */ "ToInt" OpHelp(""), |
| 23706 | /* 147 */ "ToReal" OpHelp(""), |
| 23707 | /* 148 */ "VDestroy" OpHelp(""), |
| 23708 | /* 149 */ "VOpen" OpHelp(""), |
| 23709 | /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23710 | /* 151 */ "VNext" OpHelp(""), |
| 23711 | /* 152 */ "VRename" OpHelp(""), |
| 23712 | /* 153 */ "Pagecount" OpHelp(""), |
| 23713 | /* 154 */ "MaxPgcnt" OpHelp(""), |
| 23714 | /* 155 */ "Init" OpHelp("Start at P2"), |
| 23715 | /* 156 */ "Noop" OpHelp(""), |
| 23716 | /* 157 */ "Explain" OpHelp(""), |
| 23717 | }; |
| 23718 | return azName[i]; |
| 23719 | } |
| 23720 | #endif |
| 23721 | |
| @@ -32066,14 +32416,14 @@ | |
| 32066 | ** |
| 32067 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32068 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32069 | */ |
| 32070 | #ifdef SQLITE_TEST |
| 32071 | SQLITE_API int sqlite3_os_type = 0; |
| 32072 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32073 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32074 | static int sqlite3_os_type = 0; |
| 32075 | #endif |
| 32076 | |
| 32077 | #ifndef SYSCALL |
| 32078 | # define SYSCALL sqlite3_syscall_ptr |
| 32079 | #endif |
| @@ -32699,10 +33049,15 @@ | |
| 32699 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 32700 | #endif |
| 32701 | |
| 32702 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 32703 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 32704 | |
| 32705 | }; /* End of the overrideable system calls */ |
| 32706 | |
| 32707 | /* |
| 32708 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | |
| 32950 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32951 | # define osIsNT() (1) |
| 32952 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32953 | # define osIsNT() (0) |
| 32954 | #else |
| 32955 | static int osIsNT(void){ |
| 32956 | if( sqlite3_os_type==0 ){ |
| 32957 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 32958 | OSVERSIONINFOW sInfo; |
| 32959 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 32960 | osGetVersionExW(&sInfo); |
| 32961 | #else |
| 32962 | OSVERSIONINFOA sInfo; |
| 32963 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 32964 | osGetVersionExA(&sInfo); |
| 32965 | #endif |
| 32966 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 32967 | } |
| 32968 | return sqlite3_os_type==2; |
| 32969 | } |
| 32970 | #endif |
| 32971 | |
| 32972 | #ifdef SQLITE_WIN32_MALLOC |
| 32973 | /* |
| 32974 | ** Allocate nBytes of memory. |
| 32975 | */ |
| @@ -37121,11 +37483,11 @@ | |
| 37121 | }; |
| 37122 | #endif |
| 37123 | |
| 37124 | /* Double-check that the aSyscall[] array has been constructed |
| 37125 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37126 | assert( ArraySize(aSyscall)==76 ); |
| 37127 | |
| 37128 | /* get memory map allocation granularity */ |
| 37129 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37130 | #if SQLITE_OS_WINRT |
| 37131 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | |
| 52813 | return pBt->nPage; |
| 52814 | } |
| 52815 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 52816 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52817 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 52818 | return (int)btreePagecount(p->pBt); |
| 52819 | } |
| 52820 | |
| 52821 | /* |
| 52822 | ** Get a page from the pager and initialize it. This routine is just a |
| 52823 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | |
| 62354 | } |
| 62355 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62356 | pParse->aLabel = 0; |
| 62357 | pParse->nLabel = 0; |
| 62358 | *pMaxFuncArgs = nMaxArgs; |
| 62359 | assert( p->bIsReader!=0 || p->btreeMask==0 ); |
| 62360 | } |
| 62361 | |
| 62362 | /* |
| 62363 | ** Return the address of the next instruction to be inserted. |
| 62364 | */ |
| @@ -62381,11 +62743,11 @@ | |
| 62381 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62382 | VdbeOp *aOp = p->aOp; |
| 62383 | assert( aOp && !p->db->mallocFailed ); |
| 62384 | |
| 62385 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62386 | assert( p->btreeMask==0 ); |
| 62387 | |
| 62388 | resolveP2Values(p, pnMaxArg); |
| 62389 | *pnOp = p->nOp; |
| 62390 | p->aOp = 0; |
| 62391 | return aOp; |
| @@ -62966,13 +63328,13 @@ | |
| 62966 | ** p->btreeMask of databases that will require a lock. |
| 62967 | */ |
| 62968 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 62969 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 62970 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 62971 | p->btreeMask |= ((yDbMask)1)<<i; |
| 62972 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 62973 | p->lockMask |= ((yDbMask)1)<<i; |
| 62974 | } |
| 62975 | } |
| 62976 | |
| 62977 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 62978 | /* |
| @@ -62996,20 +63358,19 @@ | |
| 62996 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 62997 | ** be a problem. |
| 62998 | */ |
| 62999 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63000 | int i; |
| 63001 | yDbMask mask; |
| 63002 | sqlite3 *db; |
| 63003 | Db *aDb; |
| 63004 | int nDb; |
| 63005 | if( p->lockMask==0 ) return; /* The common case */ |
| 63006 | db = p->db; |
| 63007 | aDb = db->aDb; |
| 63008 | nDb = db->nDb; |
| 63009 | for(i=0, mask=1; i<nDb; i++, mask += mask){ |
| 63010 | if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ |
| 63011 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63012 | } |
| 63013 | } |
| 63014 | } |
| 63015 | #endif |
| @@ -63018,20 +63379,19 @@ | |
| 63018 | /* |
| 63019 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63020 | */ |
| 63021 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63022 | int i; |
| 63023 | yDbMask mask; |
| 63024 | sqlite3 *db; |
| 63025 | Db *aDb; |
| 63026 | int nDb; |
| 63027 | if( p->lockMask==0 ) return; /* The common case */ |
| 63028 | db = p->db; |
| 63029 | aDb = db->aDb; |
| 63030 | nDb = db->nDb; |
| 63031 | for(i=0, mask=1; i<nDb; i++, mask += mask){ |
| 63032 | if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ |
| 63033 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63034 | } |
| 63035 | } |
| 63036 | } |
| 63037 | #endif |
| @@ -63998,11 +64358,11 @@ | |
| 63998 | int cnt = 0; |
| 63999 | int nWrite = 0; |
| 64000 | int nRead = 0; |
| 64001 | p = db->pVdbe; |
| 64002 | while( p ){ |
| 64003 | if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ |
| 64004 | cnt++; |
| 64005 | if( p->readOnly==0 ) nWrite++; |
| 64006 | if( p->bIsReader ) nRead++; |
| 64007 | } |
| 64008 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | |
| 64643 | /* |
| 64644 | ** Return the serial-type for the value stored in pMem. |
| 64645 | */ |
| 64646 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 64647 | int flags = pMem->flags; |
| 64648 | int n; |
| 64649 | |
| 64650 | if( flags&MEM_Null ){ |
| 64651 | return 0; |
| 64652 | } |
| 64653 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | |
| 64673 | } |
| 64674 | if( flags&MEM_Real ){ |
| 64675 | return 7; |
| 64676 | } |
| 64677 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 64678 | n = pMem->n; |
| 64679 | if( flags & MEM_Zero ){ |
| 64680 | n += pMem->u.nZero; |
| 64681 | } |
| 64682 | assert( n>=0 ); |
| 64683 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 64684 | } |
| 64685 | |
| 64686 | /* |
| 64687 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | |
| 67195 | /* |
| 67196 | ** Return true if the prepared statement is in need of being reset. |
| 67197 | */ |
| 67198 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67199 | Vdbe *v = (Vdbe*)pStmt; |
| 67200 | return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; |
| 67201 | } |
| 67202 | |
| 67203 | /* |
| 67204 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67205 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | |
| 67753 | ** do so without loss of information. In other words, if the string |
| 67754 | ** looks like a number, convert it into a number. If it does not |
| 67755 | ** look like a number, leave it alone. |
| 67756 | */ |
| 67757 | static void applyNumericAffinity(Mem *pRec){ |
| 67758 | if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ |
| 67759 | double rValue; |
| 67760 | i64 iValue; |
| 67761 | u8 enc = pRec->enc; |
| 67762 | if( (pRec->flags&MEM_Str)==0 ) return; |
| 67763 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; |
| 67764 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ |
| 67765 | pRec->u.i = iValue; |
| 67766 | pRec->flags |= MEM_Int; |
| 67767 | }else{ |
| 67768 | pRec->r = rValue; |
| 67769 | pRec->flags |= MEM_Real; |
| 67770 | } |
| 67771 | } |
| 67772 | } |
| 67773 | |
| 67774 | /* |
| 67775 | ** Processing is determine by the affinity parameter: |
| 67776 | ** |
| 67777 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | |
| 67804 | } |
| 67805 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 67806 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 67807 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 67808 | || affinity==SQLITE_AFF_NUMERIC ); |
| 67809 | applyNumericAffinity(pRec); |
| 67810 | if( pRec->flags & MEM_Real ){ |
| 67811 | sqlite3VdbeIntegerAffinity(pRec); |
| 67812 | } |
| 67813 | } |
| 67814 | } |
| @@ -68385,16 +68745,18 @@ | |
| 68385 | break; |
| 68386 | } |
| 68387 | |
| 68388 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68389 | ** |
| 68390 | ** Set up register P1 so that it will OP_Yield to the co-routine |
| 68391 | ** located at address P3. |
| 68392 | ** |
| 68393 | ** If P2!=0 then the co-routine implementation immediately follows |
| 68394 | ** this opcode. So jump over the co-routine implementation to |
| 68395 | ** address P2. |
| 68396 | */ |
| 68397 | case OP_InitCoroutine: { /* jump */ |
| 68398 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68399 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68400 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | |
| 68406 | break; |
| 68407 | } |
| 68408 | |
| 68409 | /* Opcode: EndCoroutine P1 * * * * |
| 68410 | ** |
| 68411 | ** The instruction at the address in register P1 is an OP_Yield. |
| 68412 | ** Jump to the P2 parameter of that OP_Yield. |
| 68413 | ** After the jump, register P1 becomes undefined. |
| 68414 | */ |
| 68415 | case OP_EndCoroutine: { /* in1 */ |
| 68416 | VdbeOp *pCaller; |
| 68417 | pIn1 = &aMem[pOp->p1]; |
| 68418 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | |
| 68425 | break; |
| 68426 | } |
| 68427 | |
| 68428 | /* Opcode: Yield P1 P2 * * * |
| 68429 | ** |
| 68430 | ** Swap the program counter with the value in register P1. |
| 68431 | ** |
| 68432 | ** If the co-routine ends with OP_Yield or OP_Return then continue |
| 68433 | ** to the next instruction. But if the co-routine ends with |
| 68434 | ** OP_EndCoroutine, jump immediately to P2. |
| 68435 | */ |
| 68436 | case OP_Yield: { /* in1, jump */ |
| 68437 | int pcDest; |
| 68438 | pIn1 = &aMem[pOp->p1]; |
| 68439 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | |
| 69814 | break; |
| 69815 | } |
| 69816 | |
| 69817 | /* Opcode: Once P1 P2 * * * |
| 69818 | ** |
| 69819 | ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, |
| 69820 | ** set the flag and fall through to the next instruction. In other words, |
| 69821 | ** this opcode causes all following opcodes up through P2 (but not including |
| 69822 | ** P2) to run just once and to be skipped on subsequent times through the loop. |
| 69823 | */ |
| 69824 | case OP_Once: { /* jump */ |
| 69825 | assert( pOp->p1<p->nOnceFlag ); |
| 69826 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 69827 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | |
| 70652 | int iGen; |
| 70653 | |
| 70654 | assert( p->bIsReader ); |
| 70655 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 70656 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70657 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 70658 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 70659 | rc = SQLITE_READONLY; |
| 70660 | goto abort_due_to_error; |
| 70661 | } |
| 70662 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | |
| 70747 | iDb = pOp->p1; |
| 70748 | iCookie = pOp->p3; |
| 70749 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 70750 | assert( iDb>=0 && iDb<db->nDb ); |
| 70751 | assert( db->aDb[iDb].pBt!=0 ); |
| 70752 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 70753 | |
| 70754 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 70755 | pOut->u.i = iMeta; |
| 70756 | break; |
| 70757 | } |
| @@ -70768,11 +71141,11 @@ | |
| 70768 | */ |
| 70769 | case OP_SetCookie: { /* in3 */ |
| 70770 | Db *pDb; |
| 70771 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 70772 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70773 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 70774 | assert( p->readOnly==0 ); |
| 70775 | pDb = &db->aDb[pOp->p1]; |
| 70776 | assert( pDb->pBt!=0 ); |
| 70777 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 70778 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | |
| 70823 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 70824 | ** structure, then said structure defines the content and collating |
| 70825 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 70826 | ** value, it is set to the number of columns in the table. |
| 70827 | ** |
| 70828 | ** See also OpenWrite. |
| 70829 | */ |
| 70830 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 70831 | ** Synopsis: root=P2 iDb=P3 |
| 70832 | ** |
| 70833 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | |
| 70845 | ** in read/write mode. For a given table, there can be one or more read-only |
| 70846 | ** cursors or a single read/write cursor but not both. |
| 70847 | ** |
| 70848 | ** See also OpenRead. |
| 70849 | */ |
| 70850 | case OP_OpenRead: |
| 70851 | case OP_OpenWrite: { |
| 70852 | int nField; |
| 70853 | KeyInfo *pKeyInfo; |
| 70854 | int p2; |
| @@ -70859,11 +71259,12 @@ | |
| 70859 | Db *pDb; |
| 70860 | |
| 70861 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 70862 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 70863 | assert( p->bIsReader ); |
| 70864 | assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); |
| 70865 | |
| 70866 | if( p->expired ){ |
| 70867 | rc = SQLITE_ABORT; |
| 70868 | break; |
| 70869 | } |
| @@ -70871,11 +71272,11 @@ | |
| 70871 | nField = 0; |
| 70872 | pKeyInfo = 0; |
| 70873 | p2 = pOp->p2; |
| 70874 | iDb = pOp->p3; |
| 70875 | assert( iDb>=0 && iDb<db->nDb ); |
| 70876 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 70877 | pDb = &db->aDb[iDb]; |
| 70878 | pX = pDb->pBt; |
| 70879 | assert( pX!=0 ); |
| 70880 | if( pOp->opcode==OP_OpenWrite ){ |
| 70881 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | |
| 70916 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 70917 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 70918 | if( pCur==0 ) goto no_mem; |
| 70919 | pCur->nullRow = 1; |
| 70920 | pCur->isOrdered = 1; |
| 70921 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 70922 | pCur->pKeyInfo = pKeyInfo; |
| 70923 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 70924 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 70925 | |
| @@ -71070,11 +71472,11 @@ | |
| 71070 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71071 | p->apCsr[pOp->p1] = 0; |
| 71072 | break; |
| 71073 | } |
| 71074 | |
| 71075 | /* Opcode: SeekGe P1 P2 P3 P4 * |
| 71076 | ** Synopsis: key=r[P3@P4] |
| 71077 | ** |
| 71078 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71079 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71080 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | |
| 71081 | ** that are used as an unpacked index key. |
| 71082 | ** |
| 71083 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71084 | ** is greater than or equal to the key value. If there are no records |
| 71085 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71086 | ** |
| 71087 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71088 | */ |
| 71089 | /* Opcode: SeekGt P1 P2 P3 P4 * |
| 71090 | ** Synopsis: key=r[P3@P4] |
| 71091 | ** |
| 71092 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71093 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71094 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | |
| 71095 | ** that are used as an unpacked index key. |
| 71096 | ** |
| 71097 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71098 | ** is greater than the key value. If there are no records greater than |
| 71099 | ** the key and P2 is not zero, then jump to P2. |
| 71100 | ** |
| 71101 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71102 | */ |
| 71103 | /* Opcode: SeekLt P1 P2 P3 P4 * |
| 71104 | ** Synopsis: key=r[P3@P4] |
| 71105 | ** |
| 71106 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71107 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71108 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | |
| 71109 | ** that are used as an unpacked index key. |
| 71110 | ** |
| 71111 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71112 | ** is less than the key value. If there are no records less than |
| 71113 | ** the key and P2 is not zero, then jump to P2. |
| 71114 | ** |
| 71115 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71116 | */ |
| 71117 | /* Opcode: SeekLe P1 P2 P3 P4 * |
| 71118 | ** Synopsis: key=r[P3@P4] |
| 71119 | ** |
| 71120 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71121 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71122 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | |
| 71123 | ** that are used as an unpacked index key. |
| 71124 | ** |
| 71125 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71126 | ** is less than or equal to the key value. If there are no records |
| 71127 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71128 | ** |
| 71129 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71130 | */ |
| 71131 | case OP_SeekLT: /* jump, in3 */ |
| 71132 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | |
| 71149 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71150 | assert( pC->isOrdered ); |
| 71151 | assert( pC->pCursor!=0 ); |
| 71152 | oc = pOp->opcode; |
| 71153 | pC->nullRow = 0; |
| 71154 | if( pC->isTable ){ |
| 71155 | /* The input value in P3 might be of any type: integer, real, string, |
| 71156 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71157 | ** the seek, so covert it. */ |
| 71158 | pIn3 = &aMem[pOp->p3]; |
| 71159 | applyNumericAffinity(pIn3); |
| 71160 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71161 | pC->rowidIsValid = 0; |
| 71162 | |
| 71163 | /* If the P3 value could not be converted into an integer without |
| 71164 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | |
| 71303 | ** record. |
| 71304 | ** |
| 71305 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71306 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71307 | ** P1 is left pointing at the matching entry. |
| 71308 | ** |
| 71309 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71310 | */ |
| 71311 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71312 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | |
| 71318 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71319 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71320 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71321 | ** falls through to the next instruction and P1 is left pointing at the |
| 71322 | ** matching entry. |
| 71323 | ** |
| 71324 | ** See also: Found, NotExists, NoConflict |
| 71325 | */ |
| 71326 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71327 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | |
| 71337 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71338 | ** cursor pointing to the matching row. |
| 71339 | ** |
| 71340 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71341 | ** branch is always taken if any part of the search key input is NULL. |
| 71342 | ** |
| 71343 | ** See also: NotFound, Found, NotExists |
| 71344 | */ |
| 71345 | case OP_NoConflict: /* jump, in3 */ |
| 71346 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | |
| 71360 | |
| 71361 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71362 | assert( pOp->p4type==P4_INT32 ); |
| 71363 | pC = p->apCsr[pOp->p1]; |
| 71364 | assert( pC!=0 ); |
| 71365 | pIn3 = &aMem[pOp->p3]; |
| 71366 | assert( pC->pCursor!=0 ); |
| 71367 | assert( pC->isTable==0 ); |
| 71368 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71369 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | |
| 71430 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71431 | ** through to the next instruction. |
| 71432 | ** |
| 71433 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71434 | ** (with arbitrary multi-value keys). |
| 71435 | ** |
| 71436 | ** See also: Found, NotFound, NoConflict |
| 71437 | */ |
| 71438 | case OP_NotExists: { /* jump, in3 */ |
| 71439 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | |
| 71444 | pIn3 = &aMem[pOp->p3]; |
| 71445 | assert( pIn3->flags & MEM_Int ); |
| 71446 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71447 | pC = p->apCsr[pOp->p1]; |
| 71448 | assert( pC!=0 ); |
| 71449 | assert( pC->isTable ); |
| 71450 | assert( pC->pseudoTableReg==0 ); |
| 71451 | pCrsr = pC->pCursor; |
| 71452 | assert( pCrsr!=0 ); |
| 71453 | res = 0; |
| @@ -71806,16 +72249,16 @@ | |
| 71806 | p->nChange = 0; |
| 71807 | break; |
| 71808 | } |
| 71809 | |
| 71810 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 71811 | ** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 |
| 71812 | ** |
| 71813 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 71814 | ** the record blob in register P3 against a prefix of the entry that |
| 71815 | ** the sorter cursor currently points to. The final P4 fields of both |
| 71816 | ** the P3 and sorter record are ignored. |
| 71817 | ** |
| 71818 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 71819 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 71820 | ** the comparison is assumed to be equal. |
| 71821 | ** |
| @@ -71823,18 +72266,18 @@ | |
| 71823 | ** each other. Jump to P2 if they are different. |
| 71824 | */ |
| 71825 | case OP_SorterCompare: { |
| 71826 | VdbeCursor *pC; |
| 71827 | int res; |
| 71828 | int nIgnore; |
| 71829 | |
| 71830 | pC = p->apCsr[pOp->p1]; |
| 71831 | assert( isSorter(pC) ); |
| 71832 | assert( pOp->p4type==P4_INT32 ); |
| 71833 | pIn3 = &aMem[pOp->p3]; |
| 71834 | nIgnore = pOp->p4.i; |
| 71835 | rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); |
| 71836 | VdbeBranchTaken(res!=0,2); |
| 71837 | if( res ){ |
| 71838 | pc = pOp->p2-1; |
| 71839 | } |
| 71840 | break; |
| @@ -72010,15 +72453,19 @@ | |
| 72010 | break; |
| 72011 | } |
| 72012 | |
| 72013 | /* Opcode: Last P1 P2 * * * |
| 72014 | ** |
| 72015 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72016 | ** will refer to the last entry in the database table or index. |
| 72017 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72018 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72019 | ** to the following instruction. |
| 72020 | */ |
| 72021 | case OP_Last: { /* jump */ |
| 72022 | VdbeCursor *pC; |
| 72023 | BtCursor *pCrsr; |
| 72024 | int res; |
| @@ -72032,10 +72479,13 @@ | |
| 72032 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72033 | pC->nullRow = (u8)res; |
| 72034 | pC->deferredMoveto = 0; |
| 72035 | pC->rowidIsValid = 0; |
| 72036 | pC->cacheStatus = CACHE_STALE; |
| 72037 | if( pOp->p2>0 ){ |
| 72038 | VdbeBranchTaken(res!=0,2); |
| 72039 | if( res ) pc = pOp->p2 - 1; |
| 72040 | } |
| 72041 | break; |
| @@ -72068,10 +72518,14 @@ | |
| 72068 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72069 | ** will refer to the first entry in the database table or index. |
| 72070 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72071 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72072 | ** to the following instruction. |
| 72073 | */ |
| 72074 | case OP_Rewind: { /* jump */ |
| 72075 | VdbeCursor *pC; |
| 72076 | BtCursor *pCrsr; |
| 72077 | int res; |
| @@ -72079,10 +72533,13 @@ | |
| 72079 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72080 | pC = p->apCsr[pOp->p1]; |
| 72081 | assert( pC!=0 ); |
| 72082 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72083 | res = 1; |
| 72084 | if( isSorter(pC) ){ |
| 72085 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72086 | }else{ |
| 72087 | pCrsr = pC->pCursor; |
| 72088 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | |
| 72104 | ** |
| 72105 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72106 | ** table or index. If there are no more key/value pairs then fall through |
| 72107 | ** to the following instruction. But if the cursor advance was successful, |
| 72108 | ** jump immediately to P2. |
| 72109 | ** |
| 72110 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72111 | ** been opened prior to this opcode or the program will segfault. |
| 72112 | ** |
| 72113 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | |
| 72123 | ** |
| 72124 | ** See also: Prev, NextIfOpen |
| 72125 | */ |
| 72126 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72127 | ** |
| 72128 | ** This opcode works just like OP_Next except that if cursor P1 is not |
| 72129 | ** open it behaves a no-op. |
| 72130 | */ |
| 72131 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72132 | ** |
| 72133 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72134 | ** table or index. If there is no previous key/value pairs then fall through |
| 72135 | ** to the following instruction. But if the cursor backup was successful, |
| 72136 | ** jump immediately to P2. |
| 72137 | ** |
| 72138 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72139 | ** not open then the behavior is undefined. |
| 72140 | ** |
| 72141 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72142 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | |
| 72149 | ** If P5 is positive and the jump is taken, then event counter |
| 72150 | ** number P5-1 in the prepared statement is incremented. |
| 72151 | */ |
| 72152 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72153 | ** |
| 72154 | ** This opcode works just like OP_Prev except that if cursor P1 is not |
| 72155 | ** open it behaves a no-op. |
| 72156 | */ |
| 72157 | case OP_SorterNext: { /* jump */ |
| 72158 | VdbeCursor *pC; |
| 72159 | int res; |
| @@ -72180,10 +72646,20 @@ | |
| 72180 | testcase( res==1 ); |
| 72181 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72182 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72183 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72184 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72185 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72186 | next_tail: |
| 72187 | pC->cacheStatus = CACHE_STALE; |
| 72188 | VdbeBranchTaken(res==0,2); |
| 72189 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | |
| 72462 | rc = SQLITE_LOCKED; |
| 72463 | p->errorAction = OE_Abort; |
| 72464 | }else{ |
| 72465 | iDb = pOp->p3; |
| 72466 | assert( iCnt==1 ); |
| 72467 | assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 72468 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72469 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72470 | pOut->flags = MEM_Int; |
| 72471 | pOut->u.i = iMoved; |
| 72472 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | |
| 72502 | case OP_Clear: { |
| 72503 | int nChange; |
| 72504 | |
| 72505 | nChange = 0; |
| 72506 | assert( p->readOnly==0 ); |
| 72507 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 72508 | rc = sqlite3BtreeClearTable( |
| 72509 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72510 | ); |
| 72511 | if( pOp->p3 ){ |
| 72512 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | |
| 72572 | int flags; |
| 72573 | Db *pDb; |
| 72574 | |
| 72575 | pgno = 0; |
| 72576 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72577 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 72578 | assert( p->readOnly==0 ); |
| 72579 | pDb = &db->aDb[pOp->p1]; |
| 72580 | assert( pDb->pBt!=0 ); |
| 72581 | if( pOp->opcode==OP_CreateTable ){ |
| 72582 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | |
| 72660 | |
| 72661 | /* Opcode: DropTable P1 * * P4 * |
| 72662 | ** |
| 72663 | ** Remove the internal (in-memory) data structures that describe |
| 72664 | ** the table named P4 in database P1. This is called after a table |
| 72665 | ** is dropped in order to keep the internal representation of the |
| 72666 | ** schema consistent with what is on disk. |
| 72667 | */ |
| 72668 | case OP_DropTable: { |
| 72669 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 72670 | break; |
| @@ -72672,11 +73149,12 @@ | |
| 72672 | |
| 72673 | /* Opcode: DropIndex P1 * * P4 * |
| 72674 | ** |
| 72675 | ** Remove the internal (in-memory) data structures that describe |
| 72676 | ** the index named P4 in database P1. This is called after an index |
| 72677 | ** is dropped in order to keep the internal representation of the |
| 72678 | ** schema consistent with what is on disk. |
| 72679 | */ |
| 72680 | case OP_DropIndex: { |
| 72681 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 72682 | break; |
| @@ -72684,11 +73162,12 @@ | |
| 72684 | |
| 72685 | /* Opcode: DropTrigger P1 * * P4 * |
| 72686 | ** |
| 72687 | ** Remove the internal (in-memory) data structures that describe |
| 72688 | ** the trigger named P4 in database P1. This is called after a trigger |
| 72689 | ** is dropped in order to keep the internal representation of the |
| 72690 | ** schema consistent with what is on disk. |
| 72691 | */ |
| 72692 | case OP_DropTrigger: { |
| 72693 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 72694 | break; |
| @@ -72737,11 +73216,11 @@ | |
| 72737 | for(j=0; j<nRoot; j++){ |
| 72738 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 72739 | } |
| 72740 | aRoot[j] = 0; |
| 72741 | assert( pOp->p5<db->nDb ); |
| 72742 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 72743 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 72744 | (int)pnErr->u.i, &nErr); |
| 72745 | sqlite3DbFree(db, aRoot); |
| 72746 | pnErr->u.i -= nErr; |
| 72747 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | |
| 73397 | */ |
| 73398 | case OP_IncrVacuum: { /* jump */ |
| 73399 | Btree *pBt; |
| 73400 | |
| 73401 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73402 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 73403 | assert( p->readOnly==0 ); |
| 73404 | pBt = db->aDb[pOp->p1].pBt; |
| 73405 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73406 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73407 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | |
| 73412 | } |
| 73413 | #endif |
| 73414 | |
| 73415 | /* Opcode: Expire P1 * * * * |
| 73416 | ** |
| 73417 | ** Cause precompiled statements to become expired. An expired statement |
| 73418 | ** fails with an error code of SQLITE_SCHEMA if it is ever executed |
| 73419 | ** (via sqlite3_step()). |
| 73420 | ** |
| 73421 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73422 | ** then only the currently executing statement is affected. |
| 73423 | */ |
| 73424 | case OP_Expire: { |
| 73425 | if( !pOp->p1 ){ |
| 73426 | sqlite3ExpirePreparedStatements(db); |
| 73427 | }else{ |
| @@ -73449,11 +73929,11 @@ | |
| 73449 | case OP_TableLock: { |
| 73450 | u8 isWriteLock = (u8)pOp->p3; |
| 73451 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73452 | int p1 = pOp->p1; |
| 73453 | assert( p1>=0 && p1<db->nDb ); |
| 73454 | assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); |
| 73455 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73456 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73457 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73458 | const char *z = pOp->p4.z; |
| 73459 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | |
| 73899 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 73900 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 73901 | if( zTrace ){ |
| 73902 | int i; |
| 73903 | for(i=0; i<db->nDb; i++){ |
| 73904 | if( (MASKBIT(i) & p->btreeMask)==0 ) continue; |
| 73905 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 73906 | } |
| 73907 | } |
| 73908 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 73909 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | |
| 74889 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 74890 | ** has been allocated and contains an unpacked record that is used as key2. |
| 74891 | */ |
| 74892 | static void vdbeSorterCompare( |
| 74893 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 74894 | int nIgnore, /* Ignore the last nIgnore fields */ |
| 74895 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 74896 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 74897 | int *pRes /* OUT: Result of comparison */ |
| 74898 | ){ |
| 74899 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | |
| 74903 | |
| 74904 | if( pKey2 ){ |
| 74905 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 74906 | } |
| 74907 | |
| 74908 | if( nIgnore ){ |
| 74909 | r2->nField = pKeyInfo->nField - nIgnore; |
| 74910 | assert( r2->nField>0 ); |
| 74911 | for(i=0; i<r2->nField; i++){ |
| 74912 | if( r2->aMem[i].flags & MEM_Null ){ |
| 74913 | *pRes = -1; |
| 74914 | return; |
| 74915 | } |
| 74916 | } |
| @@ -75588,18 +76067,18 @@ | |
| 75588 | ** key. |
| 75589 | */ |
| 75590 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 75591 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 75592 | Mem *pVal, /* Value to compare to current sorter key */ |
| 75593 | int nIgnore, /* Ignore this many fields at the end */ |
| 75594 | int *pRes /* OUT: Result of comparison */ |
| 75595 | ){ |
| 75596 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75597 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 75598 | |
| 75599 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 75600 | vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes); |
| 75601 | return SQLITE_OK; |
| 75602 | } |
| 75603 | |
| 75604 | /************** End of vdbesort.c ********************************************/ |
| 75605 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | |
| 79352 | } |
| 79353 | } |
| 79354 | } |
| 79355 | |
| 79356 | if( eType==0 ){ |
| 79357 | /* Could not found an existing table or index to use as the RHS b-tree. |
| 79358 | ** We will have to generate an ephemeral table to do the job. |
| 79359 | */ |
| 79360 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79361 | int rMayHaveNull = 0; |
| 79362 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | |
| 79482 | /* Case 1: expr IN (SELECT ...) |
| 79483 | ** |
| 79484 | ** Generate code to write the results of the select into the temporary |
| 79485 | ** table allocated and opened above. |
| 79486 | */ |
| 79487 | SelectDest dest; |
| 79488 | ExprList *pEList; |
| 79489 | |
| 79490 | assert( !isRowid ); |
| 79491 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79492 | dest.affSdst = (u8)affinity; |
| 79493 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79494 | pExpr->x.pSelect->iLimit = 0; |
| 79495 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79496 | if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ |
| 79497 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79498 | return 0; |
| 79499 | } |
| 79500 | pEList = pExpr->x.pSelect->pEList; |
| 79501 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79502 | assert( pEList!=0 ); |
| 79503 | assert( pEList->nExpr>0 ); |
| 79504 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79505 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | |
| 79803 | }else{ |
| 79804 | int c; |
| 79805 | i64 value; |
| 79806 | const char *z = pExpr->u.zToken; |
| 79807 | assert( z!=0 ); |
| 79808 | c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); |
| 79809 | if( c==0 || (c==2 && negFlag) ){ |
| 79810 | char *zV; |
| 79811 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 79812 | zV = dup8bytes(v, (char*)&value); |
| 79813 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 79814 | }else{ |
| 79815 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 79816 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 79817 | #else |
| 79818 | codeReal(v, z, negFlag, iMem); |
| 79819 | #endif |
| 79820 | } |
| 79821 | } |
| 79822 | } |
| 79823 | |
| @@ -83186,19 +83675,24 @@ | |
| 83186 | } |
| 83187 | |
| 83188 | /* |
| 83189 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83190 | ** are: |
| 83191 | ** N: The number of columns in the index including the rowid/pk |
| 83192 | ** K: The number of columns in the index excluding the rowid/pk |
| 83193 | ** C: The number of rows in the index |
| 83194 | ** |
| 83195 | ** C is only used for STAT3 and STAT4. |
| 83196 | ** |
| 83197 | ** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables, |
| 83198 | ** N=K+P where P is the number of columns in the primary key. For the |
| 83199 | ** covering index that implements the original WITHOUT ROWID table, N==K. |
| 83200 | ** |
| 83201 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83202 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83203 | ** the size of the blob is sizeof(void*) bytes). |
| 83204 | */ |
| @@ -83504,11 +83998,14 @@ | |
| 83504 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83505 | ** C Index of left-most column to differ from previous row |
| 83506 | ** R Rowid for the current row. Might be a key record for |
| 83507 | ** WITHOUT ROWID tables. |
| 83508 | ** |
| 83509 | ** The SQL function always returns NULL. |
| 83510 | ** |
| 83511 | ** The R parameter is only used for STAT3 and STAT4 |
| 83512 | */ |
| 83513 | static void statPush( |
| 83514 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | |
| 83598 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 83599 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 83600 | |
| 83601 | /* |
| 83602 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 83603 | ** used to query the results. Content is returned for parameter J |
| 83604 | ** which is one of the STAT_GET_xxxx values defined above. |
| 83605 | ** |
| 83606 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 83607 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 83608 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | |
| 83817 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 83818 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 83819 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 83820 | |
| 83821 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 83822 | int nCol; /* Number of columns indexed by pIdx */ |
| 83823 | int *aGotoChng; /* Array of jump instruction addresses */ |
| 83824 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 83825 | int addrGotoChng0; /* Address of "Goto addr_chng_0" */ |
| 83826 | int addrNextRow; /* Address of "next_row:" */ |
| 83827 | const char *zIdxName; /* Name of the index */ |
| 83828 | |
| 83829 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 83830 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 83831 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 83832 | nCol = pIdx->nKeyCol; |
| 83833 | zIdxName = pTab->zName; |
| 83834 | }else{ |
| 83835 | nCol = pIdx->nColumn; |
| 83836 | zIdxName = pIdx->zName; |
| 83837 | } |
| 83838 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 83839 | if( aGotoChng==0 ) continue; |
| 83840 | |
| 83841 | /* Populate the register containing the index name. */ |
| 83842 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 83843 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 83844 | |
| @@ -83863,11 +84362,11 @@ | |
| 83863 | ** regPrev(0) = idx(0) |
| 83864 | ** chng_addr_1: |
| 83865 | ** regPrev(1) = idx(1) |
| 83866 | ** ... |
| 83867 | ** |
| 83868 | ** chng_addr_N: |
| 83869 | ** regRowid = idx(rowid) |
| 83870 | ** stat_push(P, regChng, regRowid) |
| 83871 | ** Next csr |
| 83872 | ** if !eof(csr) goto next_row; |
| 83873 | ** |
| @@ -83876,24 +84375,27 @@ | |
| 83876 | |
| 83877 | /* Make sure there are enough memory cells allocated to accommodate |
| 83878 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 83879 | ** when building a record to insert into the sample column of |
| 83880 | ** the sqlite_stat4 table. */ |
| 83881 | pParse->nMem = MAX(pParse->nMem, regPrev+nCol); |
| 83882 | |
| 83883 | /* Open a read-only cursor on the index being analyzed. */ |
| 83884 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 83885 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 83886 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 83887 | VdbeComment((v, "%s", pIdx->zName)); |
| 83888 | |
| 83889 | /* Invoke the stat_init() function. The arguments are: |
| 83890 | ** |
| 83891 | ** (1) the number of columns in the index including the rowid, |
| 83892 | ** (2) the number of rows in the index, |
| 83893 | ** |
| 83894 | ** The second argument is only used for STAT3 and STAT4 |
| 83895 | */ |
| 83896 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83897 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 83898 | #endif |
| 83899 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | |
| 83911 | ** |
| 83912 | */ |
| 83913 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 83914 | VdbeCoverage(v); |
| 83915 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 83916 | addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 83917 | |
| 83918 | /* |
| 83919 | ** next_row: |
| 83920 | ** regChng = 0 |
| 83921 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 83922 | ** regChng = 1 |
| 83923 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 83924 | ** ... |
| 83925 | ** regChng = N |
| 83926 | ** goto chng_addr_N |
| 83927 | */ |
| 83928 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 83929 | for(i=0; i<nCol; i++){ |
| 83930 | char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 83931 | sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 83932 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 83933 | aGotoChng[i] = |
| 83934 | sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 83935 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 83936 | VdbeCoverage(v); |
| 83937 | } |
| 83938 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); |
| 83939 | aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); |
| 83940 | |
| 83941 | /* |
| 83942 | ** chng_addr_0: |
| 83943 | ** regPrev(0) = idx(0) |
| 83944 | ** chng_addr_1: |
| 83945 | ** regPrev(1) = idx(1) |
| 83946 | ** ... |
| 83947 | */ |
| 83948 | sqlite3VdbeJumpHere(v, addrGotoChng0); |
| 83949 | for(i=0; i<nCol; i++){ |
| 83950 | sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 83951 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 83952 | } |
| 83953 | |
| 83954 | /* |
| 83955 | ** chng_addr_N: |
| 83956 | ** regRowid = idx(rowid) // STAT34 only |
| 83957 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 83958 | ** Next csr |
| 83959 | ** if !eof(csr) goto next_row; |
| 83960 | */ |
| 83961 | sqlite3VdbeJumpHere(v, aGotoChng[nCol]); |
| 83962 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83963 | assert( regRowid==(regStat4+2) ); |
| 83964 | if( HasRowid(pTab) ){ |
| 83965 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 83966 | }else{ |
| @@ -84034,11 +84553,10 @@ | |
| 84034 | } |
| 84035 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84036 | |
| 84037 | /* End of analysis */ |
| 84038 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84039 | sqlite3DbFree(db, aGotoChng); |
| 84040 | } |
| 84041 | |
| 84042 | |
| 84043 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84044 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | |
| 84135 | int i; |
| 84136 | char *z, *zDb; |
| 84137 | Table *pTab; |
| 84138 | Index *pIdx; |
| 84139 | Token *pTableName; |
| 84140 | |
| 84141 | /* Read the database schema. If an error occurs, leave an error message |
| 84142 | ** and code in pParse and return NULL. */ |
| 84143 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84144 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | |
| 84182 | } |
| 84183 | sqlite3DbFree(db, z); |
| 84184 | } |
| 84185 | } |
| 84186 | } |
| 84187 | } |
| 84188 | |
| 84189 | /* |
| 84190 | ** Used to pass information from the analyzer reader through to the |
| 84191 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | |
| 84240 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84241 | assert( pIndex!=0 ); |
| 84242 | #else |
| 84243 | if( pIndex ) |
| 84244 | #endif |
| 84245 | { |
| 84246 | if( strcmp(z, "unordered")==0 ){ |
| 84247 | pIndex->bUnordered = 1; |
| 84248 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84249 | int v32 = 0; |
| 84250 | sqlite3GetInt32(z+3, &v32); |
| 84251 | pIndex->szIdxRow = sqlite3LogEst(v32); |
| 84252 | } |
| 84253 | } |
| 84254 | } |
| 84255 | |
| 84256 | /* |
| 84257 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | |
| 84288 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84289 | } |
| 84290 | z = argv[2]; |
| 84291 | |
| 84292 | if( pIndex ){ |
| 84293 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84294 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84295 | }else{ |
| 84296 | Index fakeIdx; |
| 84297 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84298 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84299 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84300 | } |
| 84301 | |
| 84302 | return 0; |
| @@ -85568,10 +86098,23 @@ | |
| 85568 | } |
| 85569 | #else |
| 85570 | #define codeTableLocks(x) |
| 85571 | #endif |
| 85572 | |
| 85573 | /* |
| 85574 | ** This routine is called after a single SQL statement has been |
| 85575 | ** parsed and a VDBE program to execute that statement has been |
| 85576 | ** prepared. This routine puts the finishing touches on the |
| 85577 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | |
| 85604 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 85605 | ** set for each database that is used. Generate code to start a |
| 85606 | ** transaction on each used database and to verify the schema cookie |
| 85607 | ** on each used database. |
| 85608 | */ |
| 85609 | if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ |
| 85610 | yDbMask mask; |
| 85611 | int iDb, i; |
| 85612 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 85613 | sqlite3VdbeJumpHere(v, 0); |
| 85614 | for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ |
| 85615 | if( (mask & pParse->cookieMask)==0 ) continue; |
| 85616 | sqlite3VdbeUsesBtree(v, iDb); |
| 85617 | sqlite3VdbeAddOp4Int(v, |
| 85618 | OP_Transaction, /* Opcode */ |
| 85619 | iDb, /* P1 */ |
| 85620 | (mask & pParse->writeMask)!=0, /* P2 */ |
| 85621 | pParse->cookieValue[iDb], /* P3 */ |
| 85622 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 85623 | ); |
| 85624 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 85625 | } |
| @@ -85671,11 +86215,11 @@ | |
| 85671 | } |
| 85672 | pParse->nTab = 0; |
| 85673 | pParse->nMem = 0; |
| 85674 | pParse->nSet = 0; |
| 85675 | pParse->nVar = 0; |
| 85676 | pParse->cookieMask = 0; |
| 85677 | } |
| 85678 | |
| 85679 | /* |
| 85680 | ** Run the parser and code generator recursively in order to generate |
| 85681 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | |
| 88153 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88154 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88155 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88156 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88157 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88158 | pKey->nField - pIndex->nKeyCol); VdbeCoverage(v); |
| 88159 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88160 | }else{ |
| 88161 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88162 | } |
| 88163 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | |
| 89298 | ** later, by sqlite3FinishCoding(). |
| 89299 | */ |
| 89300 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89301 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89302 | sqlite3 *db = pToplevel->db; |
| 89303 | yDbMask mask; |
| 89304 | |
| 89305 | assert( iDb>=0 && iDb<db->nDb ); |
| 89306 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89307 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89308 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89309 | mask = ((yDbMask)1)<<iDb; |
| 89310 | if( (pToplevel->cookieMask & mask)==0 ){ |
| 89311 | pToplevel->cookieMask |= mask; |
| 89312 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89313 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89314 | sqlite3OpenTempDatabase(pToplevel); |
| 89315 | } |
| 89316 | } |
| @@ -89345,11 +89887,11 @@ | |
| 89345 | ** necessary to undo a write and the checkpoint should not be set. |
| 89346 | */ |
| 89347 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89348 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89349 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89350 | pToplevel->writeMask |= ((yDbMask)1)<<iDb; |
| 89351 | pToplevel->isMultiWrite |= setStatement; |
| 89352 | } |
| 89353 | |
| 89354 | /* |
| 89355 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | |
| 98033 | ** Note that the values returned are one less that the values that |
| 98034 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98035 | ** to support legacy SQL code. The safety level used to be boolean |
| 98036 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98037 | */ |
| 98038 | static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ |
| 98039 | /* 123456789 123456789 */ |
| 98040 | static const char zText[] = "onoffalseyestruefull"; |
| 98041 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98042 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98043 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | |
| 98055 | } |
| 98056 | |
| 98057 | /* |
| 98058 | ** Interpret the given string as a boolean value. |
| 98059 | */ |
| 98060 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){ |
| 98061 | return getSafetyLevel(z,1,dflt)!=0; |
| 98062 | } |
| 98063 | |
| 98064 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98065 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | |
| 98601 | */ |
| 98602 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 98603 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 98604 | i64 iLimit = -2; |
| 98605 | if( zRight ){ |
| 98606 | sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 98607 | if( iLimit<-1 ) iLimit = -1; |
| 98608 | } |
| 98609 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 98610 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 98611 | break; |
| @@ -98729,11 +99271,11 @@ | |
| 98729 | sqlite3_int64 sz; |
| 98730 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 98731 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 98732 | if( zRight ){ |
| 98733 | int ii; |
| 98734 | sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 98735 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 98736 | if( pId2->n==0 ) db->szMmap = sz; |
| 98737 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 98738 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 98739 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | |
| 99772 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 99773 | ** use -1. |
| 99774 | */ |
| 99775 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 99776 | sqlite3_int64 N; |
| 99777 | if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ |
| 99778 | sqlite3_soft_heap_limit64(N); |
| 99779 | } |
| 99780 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 99781 | break; |
| 99782 | } |
| @@ -112245,11 +112787,12 @@ | |
| 112245 | int nEq = pLoop->u.btree.nEq; |
| 112246 | sqlite3 *db = pParse->db; |
| 112247 | int nLower = -1; |
| 112248 | int nUpper = p->nSample+1; |
| 112249 | int rc = SQLITE_OK; |
| 112250 | u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity; |
| 112251 | CollSeq *pColl; |
| 112252 | |
| 112253 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112254 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112255 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | |
| 113620 | int regRowid = 0; /* Register holding rowid */ |
| 113621 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 113622 | int iRetInit; /* Address of regReturn init */ |
| 113623 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 113624 | int ii; /* Loop counter */ |
| 113625 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 113626 | Table *pTab = pTabItem->pTab; |
| 113627 | |
| 113628 | pTerm = pLoop->aLTerm[0]; |
| 113629 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | |
| 113715 | |
| 113716 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 113717 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 113718 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 113719 | */ |
| 113720 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 113721 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 113722 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 113723 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113724 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | |
| 113727 | pAndExpr->pLeft = pOrExpr; |
| 113728 | pOrExpr = pAndExpr; |
| 113729 | } |
| 113730 | /* Loop through table entries that match term pOrTerm. */ |
| 113731 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 113732 | WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | |
| 113733 | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); |
| 113734 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 113735 | if( pSubWInfo ){ |
| 113736 | WhereLoop *pSubLoop; |
| 113737 | explainOneScan( |
| 113738 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | |
| 113819 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 113820 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 113821 | ){ |
| 113822 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 113823 | pCov = pSubLoop->u.btree.pIndex; |
| 113824 | }else{ |
| 113825 | pCov = 0; |
| 113826 | } |
| 113827 | |
| 113828 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | |
| 114425 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114426 | } |
| 114427 | } |
| 114428 | } |
| 114429 | |
| 114430 | /* |
| 114431 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114432 | ** index pIndex. Try to match one more. |
| 114433 | ** |
| 114434 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | |
| 114621 | testcase( eOp & WO_ISNULL ); |
| 114622 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 114623 | }else{ |
| 114624 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 114625 | } |
| 114626 | assert( rc!=SQLITE_OK || nOut>0 ); |
| 114627 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 114628 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 114629 | if( nOut ){ |
| 114630 | pNew->nOut = sqlite3LogEst(nOut); |
| 114631 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | |
| 114653 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 114654 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 114655 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 114656 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 114657 | } |
| 114658 | |
| 114659 | nOutUnadjusted = pNew->nOut; |
| 114660 | pNew->rRun += nInMul + nIn; |
| 114661 | pNew->nOut += nInMul + nIn; |
| 114662 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | |
| 114772 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 114773 | ** |
| 114774 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 114775 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 114776 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 114777 | */ |
| 114778 | static int whereLoopAddBtree( |
| 114779 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114780 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114781 | ){ |
| @@ -114859,10 +115423,11 @@ | |
| 114859 | pNew->aLTerm[0] = pTerm; |
| 114860 | /* TUNING: One-time cost for computing the automatic index is |
| 114861 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 114862 | ** the table being indexed. */ |
| 114863 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 114864 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 114865 | ** is more than the usual guess of 10 rows, since we have no way |
| 114866 | ** of knowning how selective the index will ultimately be. It would |
| 114867 | ** not be unreasonable to make this value much larger. */ |
| 114868 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | |
| 114900 | |
| 114901 | /* Full table scan */ |
| 114902 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114903 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 114904 | pNew->rRun = rSize + 16; |
| 114905 | whereLoopOutputAdjust(pWC, pNew); |
| 114906 | rc = whereLoopInsert(pBuilder, pNew); |
| 114907 | pNew->nOut = rSize; |
| 114908 | if( rc ) break; |
| 114909 | }else{ |
| @@ -114935,11 +115501,11 @@ | |
| 114935 | ** also add the cost of visiting table rows (N*3.0). */ |
| 114936 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114937 | if( m!=0 ){ |
| 114938 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 114939 | } |
| 114940 | |
| 114941 | whereLoopOutputAdjust(pWC, pNew); |
| 114942 | rc = whereLoopInsert(pBuilder, pNew); |
| 114943 | pNew->nOut = rSize; |
| 114944 | if( rc ) break; |
| 114945 | } |
| @@ -116410,10 +116976,11 @@ | |
| 116410 | } |
| 116411 | op = OP_OpenWrite; |
| 116412 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116413 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116414 | iIndexCur = iIdxCur; |
| 116415 | }else{ |
| 116416 | iIndexCur = pParse->nTab++; |
| 116417 | } |
| 116418 | pLevel->iIdxCur = iIndexCur; |
| 116419 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | |
| 120734 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 120735 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 120736 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 120737 | testcase( z[0]=='9' ); |
| 120738 | *tokenType = TK_INTEGER; |
| 120739 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 120740 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 120741 | if( z[i]=='.' ){ |
| 120742 | i++; |
| 120743 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | |
| 122410 | |
| 122411 | /* |
| 122412 | ** Return a static string containing the name corresponding to the error code |
| 122413 | ** specified in the argument. |
| 122414 | */ |
| 122415 | #if defined(SQLITE_TEST) |
| 122416 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122417 | const char *zName = 0; |
| 122418 | int i, origRc = rc; |
| 122419 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122420 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | |
| 123455 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 123456 | #endif |
| 123457 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 123458 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 123459 | #endif |
| 123460 | #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 |
| 123461 | # error SQLITE_MAX_ATTACHED must be between 0 and 62 |
| 123462 | #endif |
| 123463 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 123464 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 123465 | #endif |
| 123466 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | |
| 124715 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 124716 | #endif |
| 124717 | break; |
| 124718 | } |
| 124719 | |
| 124720 | } |
| 124721 | va_end(ap); |
| 124722 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 124723 | return rc; |
| 124724 | } |
| @@ -124763,11 +125346,11 @@ | |
| 124763 | const char *zParam, /* URI parameter sought */ |
| 124764 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 124765 | ){ |
| 124766 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 124767 | sqlite3_int64 v; |
| 124768 | if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ |
| 124769 | bDflt = v; |
| 124770 | } |
| 124771 | return bDflt; |
| 124772 | } |
| 124773 | |
| @@ -126294,11 +126877,11 @@ | |
| 126294 | |
| 126295 | /* fts3_tokenize_vtab.c */ |
| 126296 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126297 | |
| 126298 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126299 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 126300 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126301 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126302 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126303 | #endif |
| 126304 | |
| @@ -129764,11 +130347,11 @@ | |
| 129764 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 129765 | ** And so on. |
| 129766 | */ |
| 129767 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129768 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129769 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129770 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 129771 | #endif |
| 129772 | #ifdef SQLITE_ENABLE_ICU |
| 129773 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 129774 | #endif |
| @@ -129782,20 +130365,20 @@ | |
| 129782 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 129783 | int rc = SQLITE_OK; |
| 129784 | Fts3Hash *pHash = 0; |
| 129785 | const sqlite3_tokenizer_module *pSimple = 0; |
| 129786 | const sqlite3_tokenizer_module *pPorter = 0; |
| 129787 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129788 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 129789 | #endif |
| 129790 | |
| 129791 | #ifdef SQLITE_ENABLE_ICU |
| 129792 | const sqlite3_tokenizer_module *pIcu = 0; |
| 129793 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 129794 | #endif |
| 129795 | |
| 129796 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129797 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 129798 | #endif |
| 129799 | |
| 129800 | #ifdef SQLITE_TEST |
| 129801 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | |
| 129819 | /* Load the built-in tokenizers into the hash table */ |
| 129820 | if( rc==SQLITE_OK ){ |
| 129821 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 129822 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 129823 | |
| 129824 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 129825 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 129826 | #endif |
| 129827 | #ifdef SQLITE_ENABLE_ICU |
| 129828 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 129829 | #endif |
| @@ -143079,11 +143662,11 @@ | |
| 143079 | ****************************************************************************** |
| 143080 | ** |
| 143081 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143082 | */ |
| 143083 | |
| 143084 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 143085 | |
| 143086 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143087 | |
| 143088 | /* #include <assert.h> */ |
| 143089 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | |
| 143295 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143296 | pNew->bRemoveDiacritic = 1; |
| 143297 | |
| 143298 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143299 | const char *z = azArg[i]; |
| 143300 | int n = strlen(z); |
| 143301 | |
| 143302 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143303 | pNew->bRemoveDiacritic = 1; |
| 143304 | } |
| 143305 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | |
| 143427 | }while( unicodeIsAlnum(p, iCode) |
| 143428 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 143429 | ); |
| 143430 | |
| 143431 | /* Set the output variables and return. */ |
| 143432 | pCsr->iOff = (z - pCsr->aInput); |
| 143433 | *paToken = pCsr->zToken; |
| 143434 | *pnToken = zOut - pCsr->zToken; |
| 143435 | *piStart = (zStart - pCsr->aInput); |
| 143436 | *piEnd = (zEnd - pCsr->aInput); |
| 143437 | *piPos = pCsr->iToken++; |
| 143438 | return SQLITE_OK; |
| 143439 | } |
| 143440 | |
| 143441 | /* |
| @@ -143454,11 +144037,11 @@ | |
| 143454 | }; |
| 143455 | *ppModule = &module; |
| 143456 | } |
| 143457 | |
| 143458 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 143459 | #endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ |
| 143460 | |
| 143461 | /************** End of fts3_unicode.c ****************************************/ |
| 143462 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 143463 | /* |
| 143464 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | |
| 143475 | |
| 143476 | /* |
| 143477 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 143478 | */ |
| 143479 | |
| 143480 | #if defined(SQLITE_ENABLE_FTS4_UNICODE61) |
| 143481 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 143482 | |
| 143483 | /* #include <assert.h> */ |
| 143484 | |
| 143485 | /* |
| @@ -143822,11 +144405,11 @@ | |
| 143822 | } |
| 143823 | |
| 143824 | return ret; |
| 143825 | } |
| 143826 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 143827 | #endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ |
| 143828 | |
| 143829 | /************** End of fts3_unicode2.c ***************************************/ |
| 143830 | /************** Begin file rtree.c *******************************************/ |
| 143831 | /* |
| 143832 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | |
| 145359 | int rc = SQLITE_OK; |
| 145360 | int iCell = 0; |
| 145361 | |
| 145362 | rtreeReference(pRtree); |
| 145363 | |
| 145364 | freeCursorConstraints(pCsr); |
| 145365 | pCsr->iStrategy = idxNum; |
| 145366 | |
| 145367 | if( idxNum==1 ){ |
| 145368 | /* Special case - lookup by rowid. */ |
| 145369 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145370 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145371 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145372 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -2150,31 +2150,37 @@ | |
| 2150 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2151 | |
| 2152 | /* |
| 2153 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2154 | ** |
| 2155 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2156 | ** that might be invoked with argument P whenever |
| 2157 | ** an attempt is made to access a database table associated with |
| 2158 | ** [database connection] D when another thread |
| 2159 | ** or process has the table locked. |
| 2160 | ** The sqlite3_busy_handler() interface is used to implement |
| 2161 | ** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. |
| 2162 | ** |
| 2163 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2164 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2165 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2166 | ** |
| 2167 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2168 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2169 | ** the busy handler callback is the number of times that the busy handler has |
| 2170 | ** been invoked for the same locking event. ^If the |
| 2171 | ** busy callback returns 0, then no additional attempts are made to |
| 2172 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned |
| 2173 | ** to the application. |
| 2174 | ** ^If the callback returns non-zero, then another attempt |
| 2175 | ** is made to access the database and the cycle repeats. |
| 2176 | ** |
| 2177 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2178 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2179 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2180 | ** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the |
| 2181 | ** busy handler. |
| 2182 | ** Consider a scenario where one process is holding a read lock that |
| 2183 | ** it is trying to promote to a reserved lock and |
| 2184 | ** a second process is holding a reserved lock that it is trying |
| 2185 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2186 | ** because it is blocked by the second and the second process cannot |
| @@ -2202,14 +2208,16 @@ | |
| 2208 | ** this is important. |
| 2209 | ** |
| 2210 | ** ^(There can only be a single busy handler defined for each |
| 2211 | ** [database connection]. Setting a new busy handler clears any |
| 2212 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2213 | ** or evaluating [PRAGMA busy_timeout=N] will change the |
| 2214 | ** busy handler and thus clear any previously set busy handler. |
| 2215 | ** |
| 2216 | ** The busy callback should not take any actions which modify the |
| 2217 | ** database connection that invoked the busy handler. In other words, |
| 2218 | ** the busy handler is not reentrant. Any such actions |
| 2219 | ** result in undefined behavior. |
| 2220 | ** |
| 2221 | ** A busy handler must not close the database connection |
| 2222 | ** or [prepared statement] that invoked the busy handler. |
| 2223 | */ |
| @@ -2230,10 +2238,12 @@ | |
| 2238 | ** |
| 2239 | ** ^(There can only be a single busy handler for a particular |
| 2240 | ** [database connection] any any given moment. If another busy handler |
| 2241 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2242 | ** this routine, that other busy handler is cleared.)^ |
| 2243 | ** |
| 2244 | ** See also: [PRAGMA busy_timeout] |
| 2245 | */ |
| 2246 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2247 | |
| 2248 | /* |
| 2249 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4818,10 +4828,17 @@ | |
| 4828 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4829 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4830 | ** will be placed in that directory.)^ ^If this variable |
| 4831 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4832 | ** temporary file directory. |
| 4833 | ** |
| 4834 | ** Applications are strongly discouraged from using this global variable. |
| 4835 | ** It is required to set a temporary folder on Windows Runtime (WinRT). |
| 4836 | ** But for all other platforms, it is highly recommended that applications |
| 4837 | ** neither read nor write this variable. This global variable is a relic |
| 4838 | ** that exists for backwards compatibility of legacy applications and should |
| 4839 | ** be avoided in new projects. |
| 4840 | ** |
| 4841 | ** It is not safe to read or modify this variable in more than one |
| 4842 | ** thread at a time. It is not safe to read or modify this variable |
| 4843 | ** if a [database connection] is being used at the same time in a separate |
| 4844 | ** thread. |
| @@ -4837,10 +4854,15 @@ | |
| 4854 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4855 | ** using [sqlite3_free]. |
| 4856 | ** Hence, if this variable is modified directly, either it should be |
| 4857 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4858 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4859 | ** Except when requested by the [temp_store_directory pragma], SQLite |
| 4860 | ** does not free the memory that sqlite3_temp_directory points to. If |
| 4861 | ** the application wants that memory to be freed, it must do |
| 4862 | ** so itself, taking care to only do so after all [database connection] |
| 4863 | ** objects have been destroyed. |
| 4864 | ** |
| 4865 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4866 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4867 | ** features that require the use of temporary files may fail. Here is an |
| 4868 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5971,14 +5993,16 @@ | |
| 5993 | ** <ul> |
| 5994 | ** <li> SQLITE_MUTEX_FAST |
| 5995 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5996 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5997 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5998 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 5999 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 6000 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 6001 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 6002 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 6003 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 6004 | ** </ul>)^ |
| 6005 | ** |
| 6006 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 6007 | ** cause sqlite3_mutex_alloc() to create |
| 6008 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6178,10 +6202,13 @@ | |
| 6202 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6203 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6204 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6205 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6206 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6207 | #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ |
| 6208 | #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ |
| 6209 | #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ |
| 6210 | |
| 6211 | /* |
| 6212 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6213 | ** |
| 6214 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6273,11 +6300,12 @@ | |
| 6300 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6301 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6302 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6303 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6304 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6305 | #define SQLITE_TESTCTRL_ISINIT 23 |
| 6306 | #define SQLITE_TESTCTRL_LAST 23 |
| 6307 | |
| 6308 | /* |
| 6309 | ** CAPI3REF: SQLite Runtime Status |
| 6310 | ** |
| 6311 | ** ^This interface is used to retrieve runtime status information |
| @@ -7256,10 +7284,13 @@ | |
| 7284 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7285 | ** configured by this function. |
| 7286 | ** |
| 7287 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7288 | ** from SQL. |
| 7289 | ** |
| 7290 | ** ^Checkpoints initiated by this mechanism are |
| 7291 | ** [sqlite3_wal_checkpoint_v2|PASSIVE]. |
| 7292 | ** |
| 7293 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7294 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7295 | ** pages. The use of this interface |
| 7296 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7273,10 +7304,14 @@ | |
| 7304 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7305 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7306 | ** empty string, then a checkpoint is run on all databases of |
| 7307 | ** connection D. ^If the database connection D is not in |
| 7308 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7309 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a |
| 7310 | ** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. |
| 7311 | ** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL |
| 7312 | ** or RESET checkpoint. |
| 7313 | ** |
| 7314 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7315 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7316 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7317 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7295,22 +7330,25 @@ | |
| 7330 | ** <dl> |
| 7331 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7332 | ** Checkpoint as many frames as possible without waiting for any database |
| 7333 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7334 | ** are checkpointed. This mode is the same as calling |
| 7335 | ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] |
| 7336 | ** is never invoked. |
| 7337 | ** |
| 7338 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7339 | ** This mode blocks (it invokes the |
| 7340 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7341 | ** database writer and all readers are reading from the most recent database |
| 7342 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7343 | ** database file. This call blocks database writers while it is running, |
| 7344 | ** but not database readers. |
| 7345 | ** |
| 7346 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7347 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7348 | ** checkpointing the log file it blocks (calls the |
| 7349 | ** [sqlite3_busy_handler|busy-handler callback]) |
| 7350 | ** until all readers are reading from the database file only. This ensures |
| 7351 | ** that the next client to write to the database file restarts the log file |
| 7352 | ** from the beginning. This call blocks database writers while it is running, |
| 7353 | ** but not database readers. |
| 7354 | ** </dl> |
| @@ -9285,43 +9323,43 @@ | |
| 9323 | #define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9324 | #define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9325 | #define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9326 | #define OP_ReadCookie 50 |
| 9327 | #define OP_SetCookie 51 |
| 9328 | #define OP_ReopenIdx 52 /* synopsis: root=P2 iDb=P3 */ |
| 9329 | #define OP_OpenRead 53 /* synopsis: root=P2 iDb=P3 */ |
| 9330 | #define OP_OpenWrite 54 /* synopsis: root=P2 iDb=P3 */ |
| 9331 | #define OP_OpenAutoindex 55 /* synopsis: nColumn=P2 */ |
| 9332 | #define OP_OpenEphemeral 56 /* synopsis: nColumn=P2 */ |
| 9333 | #define OP_SorterOpen 57 |
| 9334 | #define OP_OpenPseudo 58 /* synopsis: P3 columns in r[P2] */ |
| 9335 | #define OP_Close 59 |
| 9336 | #define OP_SeekLT 60 /* synopsis: key=r[P3@P4] */ |
| 9337 | #define OP_SeekLE 61 /* synopsis: key=r[P3@P4] */ |
| 9338 | #define OP_SeekGE 62 /* synopsis: key=r[P3@P4] */ |
| 9339 | #define OP_SeekGT 63 /* synopsis: key=r[P3@P4] */ |
| 9340 | #define OP_Seek 64 /* synopsis: intkey=r[P2] */ |
| 9341 | #define OP_NoConflict 65 /* synopsis: key=r[P3@P4] */ |
| 9342 | #define OP_NotFound 66 /* synopsis: key=r[P3@P4] */ |
| 9343 | #define OP_Found 67 /* synopsis: key=r[P3@P4] */ |
| 9344 | #define OP_NotExists 68 /* synopsis: intkey=r[P3] */ |
| 9345 | #define OP_Sequence 69 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9346 | #define OP_NewRowid 70 /* synopsis: r[P2]=rowid */ |
| 9347 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9348 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9349 | #define OP_Insert 73 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9350 | #define OP_InsertInt 74 /* synopsis: intkey=P3 data=r[P2] */ |
| 9351 | #define OP_Delete 75 |
| 9352 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9353 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9354 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9355 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9356 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9357 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9358 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9359 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9360 | #define OP_ResetCount 84 |
| 9361 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9362 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9363 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9364 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9365 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| @@ -9328,73 +9366,74 @@ | |
| 9366 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9367 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9368 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9369 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9370 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9371 | #define OP_SorterCompare 95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 9372 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9373 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9374 | #define OP_SorterData 98 /* synopsis: r[P2]=data */ |
| 9375 | #define OP_RowKey 99 /* synopsis: r[P2]=key */ |
| 9376 | #define OP_RowData 100 /* synopsis: r[P2]=data */ |
| 9377 | #define OP_Rowid 101 /* synopsis: r[P2]=rowid */ |
| 9378 | #define OP_NullRow 102 |
| 9379 | #define OP_Last 103 |
| 9380 | #define OP_SorterSort 104 |
| 9381 | #define OP_Sort 105 |
| 9382 | #define OP_Rewind 106 |
| 9383 | #define OP_SorterInsert 107 |
| 9384 | #define OP_IdxInsert 108 /* synopsis: key=r[P2] */ |
| 9385 | #define OP_IdxDelete 109 /* synopsis: key=r[P2@P3] */ |
| 9386 | #define OP_IdxRowid 110 /* synopsis: r[P2]=rowid */ |
| 9387 | #define OP_IdxLE 111 /* synopsis: key=r[P3@P4] */ |
| 9388 | #define OP_IdxGT 112 /* synopsis: key=r[P3@P4] */ |
| 9389 | #define OP_IdxLT 113 /* synopsis: key=r[P3@P4] */ |
| 9390 | #define OP_IdxGE 114 /* synopsis: key=r[P3@P4] */ |
| 9391 | #define OP_Destroy 115 |
| 9392 | #define OP_Clear 116 |
| 9393 | #define OP_ResetSorter 117 |
| 9394 | #define OP_CreateIndex 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9395 | #define OP_CreateTable 119 /* synopsis: r[P2]=root iDb=P1 */ |
| 9396 | #define OP_ParseSchema 120 |
| 9397 | #define OP_LoadAnalysis 121 |
| 9398 | #define OP_DropTable 122 |
| 9399 | #define OP_DropIndex 123 |
| 9400 | #define OP_DropTrigger 124 |
| 9401 | #define OP_IntegrityCk 125 |
| 9402 | #define OP_RowSetAdd 126 /* synopsis: rowset(P1)=r[P2] */ |
| 9403 | #define OP_RowSetRead 127 /* synopsis: r[P3]=rowset(P1) */ |
| 9404 | #define OP_RowSetTest 128 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9405 | #define OP_Program 129 |
| 9406 | #define OP_Param 130 |
| 9407 | #define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9408 | #define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9410 | #define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9411 | #define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9412 | #define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ |
| 9413 | #define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9414 | #define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9415 | #define OP_IncrVacuum 139 |
| 9416 | #define OP_Expire 140 |
| 9417 | #define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9418 | #define OP_VBegin 142 |
| 9419 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9420 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9421 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9422 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9423 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9424 | #define OP_VCreate 148 |
| 9425 | #define OP_VDestroy 149 |
| 9426 | #define OP_VOpen 150 |
| 9427 | #define OP_VColumn 151 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9428 | #define OP_VNext 152 |
| 9429 | #define OP_VRename 153 |
| 9430 | #define OP_Pagecount 154 |
| 9431 | #define OP_MaxPgcnt 155 |
| 9432 | #define OP_Init 156 /* synopsis: Start at P2 */ |
| 9433 | #define OP_Noop 157 |
| 9434 | #define OP_Explain 158 |
| 9435 | |
| 9436 | |
| 9437 | /* Properties such as "out2" or "jump" that are specified in |
| 9438 | ** comments following the "case" for each opcode in the vdbe.c |
| 9439 | ** are encoded into bitvectors as follows: |
| @@ -9412,23 +9451,23 @@ | |
| 9451 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9452 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9453 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9454 | /* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9455 | /* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9456 | /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\ |
| 9457 | /* 64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\ |
| 9458 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9459 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9460 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9461 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ |
| 9462 | /* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\ |
| 9463 | /* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\ |
| 9464 | /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ |
| 9465 | /* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\ |
| 9466 | /* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\ |
| 9467 | /* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\ |
| 9468 | /* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9469 | |
| 9470 | /************** End of opcodes.h *********************************************/ |
| 9471 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9472 | |
| 9473 | /* |
| @@ -10932,10 +10971,13 @@ | |
| 10971 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10972 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10973 | i16 nCol; /* Number of columns in this table */ |
| 10974 | u16 nRef; /* Number of pointers to this Table */ |
| 10975 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10976 | #ifdef SQLITE_ENABLE_COSTMULT |
| 10977 | LogEst costMult; /* Cost multiplier for using this table */ |
| 10978 | #endif |
| 10979 | u8 tabFlags; /* Mask of TF_* values */ |
| 10980 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10981 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10982 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10983 | #endif |
| @@ -11591,10 +11633,11 @@ | |
| 11633 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11634 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11635 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11636 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11637 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11638 | #define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ |
| 11639 | |
| 11640 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11641 | */ |
| 11642 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11643 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -11847,13 +11890,23 @@ | |
| 11890 | |
| 11891 | /* |
| 11892 | ** The yDbMask datatype for the bitmask of all attached databases. |
| 11893 | */ |
| 11894 | #if SQLITE_MAX_ATTACHED>30 |
| 11895 | typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; |
| 11896 | # define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) |
| 11897 | # define DbMaskZero(M) memset((M),0,sizeof(M)) |
| 11898 | # define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) |
| 11899 | # define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) |
| 11900 | # define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) |
| 11901 | #else |
| 11902 | typedef unsigned int yDbMask; |
| 11903 | # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) |
| 11904 | # define DbMaskZero(M) (M)=0 |
| 11905 | # define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) |
| 11906 | # define DbMaskAllZero(M) (M)==0 |
| 11907 | # define DbMaskNonZero(M) (M)!=0 |
| 11908 | #endif |
| 11909 | |
| 11910 | /* |
| 11911 | ** An SQL parser context. A copy of this structure is passed through |
| 11912 | ** the parser and down into all the parser action routine in order to |
| @@ -12522,10 +12575,13 @@ | |
| 12575 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); |
| 12576 | #else |
| 12577 | # define sqlite3ViewGetColumnNames(A,B) 0 |
| 12578 | #endif |
| 12579 | |
| 12580 | #if SQLITE_MAX_ATTACHED>30 |
| 12581 | SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); |
| 12582 | #endif |
| 12583 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 12584 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 12585 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 12586 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 12587 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -12772,10 +12828,11 @@ | |
| 12828 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 12829 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12830 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12831 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12832 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12833 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 12834 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12835 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12836 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12837 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12838 | |
| @@ -12801,11 +12858,11 @@ | |
| 12858 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 12859 | SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); |
| 12860 | #else |
| 12861 | # define sqlite3FileSuffix3(X,Y) |
| 12862 | #endif |
| 12863 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); |
| 12864 | |
| 12865 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 12866 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 12867 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12868 | void(*)(void*)); |
| @@ -13876,18 +13933,22 @@ | |
| 13933 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13934 | int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13935 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13936 | i16 nField; /* Number of fields in the header */ |
| 13937 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13938 | #ifdef SQLITE_DEBUG |
| 13939 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| 13940 | #endif |
| 13941 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13942 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13943 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13944 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13945 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13946 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13947 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13948 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13949 | Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 13950 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13951 | i64 seqCount; /* Sequence counter */ |
| 13952 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13953 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13954 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| @@ -18396,11 +18457,11 @@ | |
| 18457 | /* |
| 18458 | ** Retrieve a pointer to a static mutex or allocate a new dynamic one. |
| 18459 | */ |
| 18460 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ |
| 18461 | #ifndef SQLITE_OMIT_AUTOINIT |
| 18462 | if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; |
| 18463 | #endif |
| 18464 | return sqlite3GlobalConfig.mutex.xMutexAlloc(id); |
| 18465 | } |
| 18466 | |
| 18467 | SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ |
| @@ -18577,11 +18638,11 @@ | |
| 18638 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 18639 | ** mutex and returns a pointer to it. If it returns NULL |
| 18640 | ** that means that a mutex could not be allocated. |
| 18641 | */ |
| 18642 | static sqlite3_mutex *debugMutexAlloc(int id){ |
| 18643 | static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1]; |
| 18644 | sqlite3_debug_mutex *pNew = 0; |
| 18645 | switch( id ){ |
| 18646 | case SQLITE_MUTEX_FAST: |
| 18647 | case SQLITE_MUTEX_RECURSIVE: { |
| 18648 | pNew = sqlite3Malloc(sizeof(*pNew)); |
| @@ -18774,14 +18835,17 @@ | |
| 18835 | ** <ul> |
| 18836 | ** <li> SQLITE_MUTEX_FAST |
| 18837 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 18838 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 18839 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 18840 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 18841 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 18842 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 18843 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 18844 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 18845 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 18846 | ** <li> SQLITE_MUTEX_STATIC_APP3 |
| 18847 | ** </ul> |
| 18848 | ** |
| 18849 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 18850 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 18851 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -18806,10 +18870,13 @@ | |
| 18870 | ** mutex types, the same mutex is returned on every call that has |
| 18871 | ** the same type number. |
| 18872 | */ |
| 18873 | static sqlite3_mutex *pthreadMutexAlloc(int iType){ |
| 18874 | static sqlite3_mutex staticMutexes[] = { |
| 18875 | SQLITE3_MUTEX_INITIALIZER, |
| 18876 | SQLITE3_MUTEX_INITIALIZER, |
| 18877 | SQLITE3_MUTEX_INITIALIZER, |
| 18878 | SQLITE3_MUTEX_INITIALIZER, |
| 18879 | SQLITE3_MUTEX_INITIALIZER, |
| 18880 | SQLITE3_MUTEX_INITIALIZER, |
| 18881 | SQLITE3_MUTEX_INITIALIZER, |
| 18882 | SQLITE3_MUTEX_INITIALIZER, |
| @@ -19041,14 +19108,227 @@ | |
| 19108 | ** May you do good and not evil. |
| 19109 | ** May you find forgiveness for yourself and forgive others. |
| 19110 | ** May you share freely, never taking more than you give. |
| 19111 | ** |
| 19112 | ************************************************************************* |
| 19113 | ** This file contains the C functions that implement mutexes for Win32. |
| 19114 | */ |
| 19115 | |
| 19116 | #if SQLITE_OS_WIN |
| 19117 | /* |
| 19118 | ** Include code that is common to all os_*.c files |
| 19119 | */ |
| 19120 | /************** Include os_common.h in the middle of mutex_w32.c *************/ |
| 19121 | /************** Begin file os_common.h ***************************************/ |
| 19122 | /* |
| 19123 | ** 2004 May 22 |
| 19124 | ** |
| 19125 | ** The author disclaims copyright to this source code. In place of |
| 19126 | ** a legal notice, here is a blessing: |
| 19127 | ** |
| 19128 | ** May you do good and not evil. |
| 19129 | ** May you find forgiveness for yourself and forgive others. |
| 19130 | ** May you share freely, never taking more than you give. |
| 19131 | ** |
| 19132 | ****************************************************************************** |
| 19133 | ** |
| 19134 | ** This file contains macros and a little bit of code that is common to |
| 19135 | ** all of the platform-specific files (os_*.c) and is #included into those |
| 19136 | ** files. |
| 19137 | ** |
| 19138 | ** This file should be #included by the os_*.c files only. It is not a |
| 19139 | ** general purpose header file. |
| 19140 | */ |
| 19141 | #ifndef _OS_COMMON_H_ |
| 19142 | #define _OS_COMMON_H_ |
| 19143 | |
| 19144 | /* |
| 19145 | ** At least two bugs have slipped in because we changed the MEMORY_DEBUG |
| 19146 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the |
| 19147 | ** switch. The following code should catch this problem at compile-time. |
| 19148 | */ |
| 19149 | #ifdef MEMORY_DEBUG |
| 19150 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 19151 | #endif |
| 19152 | |
| 19153 | #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 19154 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 19155 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 19156 | # endif |
| 19157 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 19158 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| 19159 | #else |
| 19160 | # define OSTRACE(X) |
| 19161 | #endif |
| 19162 | |
| 19163 | /* |
| 19164 | ** Macros for performance tracing. Normally turned off. Only works |
| 19165 | ** on i486 hardware. |
| 19166 | */ |
| 19167 | #ifdef SQLITE_PERFORMANCE_TRACE |
| 19168 | |
| 19169 | /* |
| 19170 | ** hwtime.h contains inline assembler code for implementing |
| 19171 | ** high-performance timing routines. |
| 19172 | */ |
| 19173 | /************** Include hwtime.h in the middle of os_common.h ****************/ |
| 19174 | /************** Begin file hwtime.h ******************************************/ |
| 19175 | /* |
| 19176 | ** 2008 May 27 |
| 19177 | ** |
| 19178 | ** The author disclaims copyright to this source code. In place of |
| 19179 | ** a legal notice, here is a blessing: |
| 19180 | ** |
| 19181 | ** May you do good and not evil. |
| 19182 | ** May you find forgiveness for yourself and forgive others. |
| 19183 | ** May you share freely, never taking more than you give. |
| 19184 | ** |
| 19185 | ****************************************************************************** |
| 19186 | ** |
| 19187 | ** This file contains inline asm code for retrieving "high-performance" |
| 19188 | ** counters for x86 class CPUs. |
| 19189 | */ |
| 19190 | #ifndef _HWTIME_H_ |
| 19191 | #define _HWTIME_H_ |
| 19192 | |
| 19193 | /* |
| 19194 | ** The following routine only works on pentium-class (or newer) processors. |
| 19195 | ** It uses the RDTSC opcode to read the cycle count value out of the |
| 19196 | ** processor and returns that value. This can be used for high-res |
| 19197 | ** profiling. |
| 19198 | */ |
| 19199 | #if (defined(__GNUC__) || defined(_MSC_VER)) && \ |
| 19200 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) |
| 19201 | |
| 19202 | #if defined(__GNUC__) |
| 19203 | |
| 19204 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19205 | unsigned int lo, hi; |
| 19206 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); |
| 19207 | return (sqlite_uint64)hi << 32 | lo; |
| 19208 | } |
| 19209 | |
| 19210 | #elif defined(_MSC_VER) |
| 19211 | |
| 19212 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ |
| 19213 | __asm { |
| 19214 | rdtsc |
| 19215 | ret ; return value at EDX:EAX |
| 19216 | } |
| 19217 | } |
| 19218 | |
| 19219 | #endif |
| 19220 | |
| 19221 | #elif (defined(__GNUC__) && defined(__x86_64__)) |
| 19222 | |
| 19223 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19224 | unsigned long val; |
| 19225 | __asm__ __volatile__ ("rdtsc" : "=A" (val)); |
| 19226 | return val; |
| 19227 | } |
| 19228 | |
| 19229 | #elif (defined(__GNUC__) && defined(__ppc__)) |
| 19230 | |
| 19231 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ |
| 19232 | unsigned long long retval; |
| 19233 | unsigned long junk; |
| 19234 | __asm__ __volatile__ ("\n\ |
| 19235 | 1: mftbu %1\n\ |
| 19236 | mftb %L0\n\ |
| 19237 | mftbu %0\n\ |
| 19238 | cmpw %0,%1\n\ |
| 19239 | bne 1b" |
| 19240 | : "=r" (retval), "=r" (junk)); |
| 19241 | return retval; |
| 19242 | } |
| 19243 | |
| 19244 | #else |
| 19245 | |
| 19246 | #error Need implementation of sqlite3Hwtime() for your platform. |
| 19247 | |
| 19248 | /* |
| 19249 | ** To compile without implementing sqlite3Hwtime() for your platform, |
| 19250 | ** you can remove the above #error and use the following |
| 19251 | ** stub function. You will lose timing support for many |
| 19252 | ** of the debugging and testing utilities, but it should at |
| 19253 | ** least compile and run. |
| 19254 | */ |
| 19255 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } |
| 19256 | |
| 19257 | #endif |
| 19258 | |
| 19259 | #endif /* !defined(_HWTIME_H_) */ |
| 19260 | |
| 19261 | /************** End of hwtime.h **********************************************/ |
| 19262 | /************** Continuing where we left off in os_common.h ******************/ |
| 19263 | |
| 19264 | static sqlite_uint64 g_start; |
| 19265 | static sqlite_uint64 g_elapsed; |
| 19266 | #define TIMER_START g_start=sqlite3Hwtime() |
| 19267 | #define TIMER_END g_elapsed=sqlite3Hwtime()-g_start |
| 19268 | #define TIMER_ELAPSED g_elapsed |
| 19269 | #else |
| 19270 | #define TIMER_START |
| 19271 | #define TIMER_END |
| 19272 | #define TIMER_ELAPSED ((sqlite_uint64)0) |
| 19273 | #endif |
| 19274 | |
| 19275 | /* |
| 19276 | ** If we compile with the SQLITE_TEST macro set, then the following block |
| 19277 | ** of code will give us the ability to simulate a disk I/O error. This |
| 19278 | ** is used for testing the I/O recovery logic. |
| 19279 | */ |
| 19280 | #ifdef SQLITE_TEST |
| 19281 | SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ |
| 19282 | SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ |
| 19283 | SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ |
| 19284 | SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ |
| 19285 | SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ |
| 19286 | SQLITE_API int sqlite3_diskfull_pending = 0; |
| 19287 | SQLITE_API int sqlite3_diskfull = 0; |
| 19288 | #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) |
| 19289 | #define SimulateIOError(CODE) \ |
| 19290 | if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ |
| 19291 | || sqlite3_io_error_pending-- == 1 ) \ |
| 19292 | { local_ioerr(); CODE; } |
| 19293 | static void local_ioerr(){ |
| 19294 | IOTRACE(("IOERR\n")); |
| 19295 | sqlite3_io_error_hit++; |
| 19296 | if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; |
| 19297 | } |
| 19298 | #define SimulateDiskfullError(CODE) \ |
| 19299 | if( sqlite3_diskfull_pending ){ \ |
| 19300 | if( sqlite3_diskfull_pending == 1 ){ \ |
| 19301 | local_ioerr(); \ |
| 19302 | sqlite3_diskfull = 1; \ |
| 19303 | sqlite3_io_error_hit = 1; \ |
| 19304 | CODE; \ |
| 19305 | }else{ \ |
| 19306 | sqlite3_diskfull_pending--; \ |
| 19307 | } \ |
| 19308 | } |
| 19309 | #else |
| 19310 | #define SimulateIOErrorBenign(X) |
| 19311 | #define SimulateIOError(A) |
| 19312 | #define SimulateDiskfullError(A) |
| 19313 | #endif |
| 19314 | |
| 19315 | /* |
| 19316 | ** When testing, keep a count of the number of open files. |
| 19317 | */ |
| 19318 | #ifdef SQLITE_TEST |
| 19319 | SQLITE_API int sqlite3_open_file_count = 0; |
| 19320 | #define OpenCounter(X) sqlite3_open_file_count+=(X) |
| 19321 | #else |
| 19322 | #define OpenCounter(X) |
| 19323 | #endif |
| 19324 | |
| 19325 | #endif /* !defined(_OS_COMMON_H_) */ |
| 19326 | |
| 19327 | /************** End of os_common.h *******************************************/ |
| 19328 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19329 | |
| 19330 | /* |
| 19331 | ** Include the header file for the Windows VFS. |
| 19332 | */ |
| 19333 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19334 | /************** Begin file os_win.h ******************************************/ |
| @@ -19124,11 +19404,11 @@ | |
| 19404 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19405 | #endif |
| 19406 | |
| 19407 | /* |
| 19408 | ** The code in this file is only used if we are compiling multithreaded |
| 19409 | ** on a Win32 system. |
| 19410 | */ |
| 19411 | #ifdef SQLITE_MUTEX_W32 |
| 19412 | |
| 19413 | /* |
| 19414 | ** Each recursive mutex is an instance of the following structure. |
| @@ -19137,94 +19417,75 @@ | |
| 19417 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 19418 | int id; /* Mutex type */ |
| 19419 | #ifdef SQLITE_DEBUG |
| 19420 | volatile int nRef; /* Number of enterances */ |
| 19421 | volatile DWORD owner; /* Thread holding this mutex */ |
| 19422 | volatile int trace; /* True to trace changes */ |
| 19423 | #endif |
| 19424 | }; |
| 19425 | |
| 19426 | /* |
| 19427 | ** These are the initializer values used when declaring a "static" mutex |
| 19428 | ** on Win32. It should be noted that all mutexes require initialization |
| 19429 | ** on the Win32 platform. |
| 19430 | */ |
| 19431 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 19432 | |
| 19433 | #ifdef SQLITE_DEBUG |
| 19434 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ |
| 19435 | 0L, (DWORD)0, 0 } |
| 19436 | #else |
| 19437 | #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } |
| 19438 | #endif |
| 19439 | |
| 19440 | #ifdef SQLITE_DEBUG |
| 19441 | /* |
| 19442 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 19443 | ** intended for use only inside assert() statements. |
| 19444 | */ |
| 19445 | static int winMutexHeld(sqlite3_mutex *p){ |
| 19446 | return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
| 19447 | } |
| 19448 | |
| 19449 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 19450 | return p->nRef==0 || p->owner!=tid; |
| 19451 | } |
| 19452 | |
| 19453 | static int winMutexNotheld(sqlite3_mutex *p){ |
| 19454 | DWORD tid = GetCurrentThreadId(); |
| 19455 | return winMutexNotheld2(p, tid); |
| 19456 | } |
| 19457 | #endif |
| 19458 | |
| 19459 | /* |
| 19460 | ** Initialize and deinitialize the mutex subsystem. |
| 19461 | */ |
| 19462 | static sqlite3_mutex winMutex_staticMutexes[] = { |
| 19463 | SQLITE3_MUTEX_INITIALIZER, |
| 19464 | SQLITE3_MUTEX_INITIALIZER, |
| 19465 | SQLITE3_MUTEX_INITIALIZER, |
| 19466 | SQLITE3_MUTEX_INITIALIZER, |
| 19467 | SQLITE3_MUTEX_INITIALIZER, |
| 19468 | SQLITE3_MUTEX_INITIALIZER, |
| 19469 | SQLITE3_MUTEX_INITIALIZER, |
| 19470 | SQLITE3_MUTEX_INITIALIZER, |
| 19471 | SQLITE3_MUTEX_INITIALIZER |
| 19472 | }; |
| 19473 | |
| 19474 | static int winMutex_isInit = 0; |
| 19475 | static int winMutex_isNt = -1; /* <0 means "need to query" */ |
| 19476 | |
| 19477 | /* As the winMutexInit() and winMutexEnd() functions are called as part |
| 19478 | ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the |
| 19479 | ** "interlocked" magic used here is probably not strictly necessary. |
| 19480 | */ |
| 19481 | static LONG volatile winMutex_lock = 0; |
| 19482 | |
| 19483 | SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ |
| 19484 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19485 | |
| 19486 | static int winMutexInit(void){ |
| 19487 | /* The first to increment to 1 does actual initialization */ |
| 19488 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 19489 | int i; |
| 19490 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 19491 | #if SQLITE_OS_WINRT |
| @@ -19233,20 +19494,21 @@ | |
| 19494 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19495 | #endif |
| 19496 | } |
| 19497 | winMutex_isInit = 1; |
| 19498 | }else{ |
| 19499 | /* Another thread is (in the process of) initializing the static |
| 19500 | ** mutexes */ |
| 19501 | while( !winMutex_isInit ){ |
| 19502 | sqlite3_win32_sleep(1); |
| 19503 | } |
| 19504 | } |
| 19505 | return SQLITE_OK; |
| 19506 | } |
| 19507 | |
| 19508 | static int winMutexEnd(void){ |
| 19509 | /* The first to decrement to 0 does actual shutdown |
| 19510 | ** (which should be the last to shutdown.) */ |
| 19511 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
| 19512 | if( winMutex_isInit==1 ){ |
| 19513 | int i; |
| 19514 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| @@ -19253,11 +19515,11 @@ | |
| 19515 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 19516 | } |
| 19517 | winMutex_isInit = 0; |
| 19518 | } |
| 19519 | } |
| 19520 | return SQLITE_OK; |
| 19521 | } |
| 19522 | |
| 19523 | /* |
| 19524 | ** The sqlite3_mutex_alloc() routine allocates a new |
| 19525 | ** mutex and returns a pointer to it. If it returns NULL |
| @@ -19268,14 +19530,17 @@ | |
| 19530 | ** <ul> |
| 19531 | ** <li> SQLITE_MUTEX_FAST |
| 19532 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 19533 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 19534 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 19535 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 19536 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 19537 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 19538 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 19539 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 19540 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 19541 | ** <li> SQLITE_MUTEX_STATIC_APP3 |
| 19542 | ** </ul> |
| 19543 | ** |
| 19544 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 19545 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 19546 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| @@ -19294,11 +19559,11 @@ | |
| 19559 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 19560 | ** SQLITE_MUTEX_RECURSIVE. |
| 19561 | ** |
| 19562 | ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |
| 19563 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |
| 19564 | ** returns a different mutex on every call. But for the static |
| 19565 | ** mutex types, the same mutex is returned on every call that has |
| 19566 | ** the same type number. |
| 19567 | */ |
| 19568 | static sqlite3_mutex *winMutexAlloc(int iType){ |
| 19569 | sqlite3_mutex *p; |
| @@ -19305,13 +19570,16 @@ | |
| 19570 | |
| 19571 | switch( iType ){ |
| 19572 | case SQLITE_MUTEX_FAST: |
| 19573 | case SQLITE_MUTEX_RECURSIVE: { |
| 19574 | p = sqlite3MallocZero( sizeof(*p) ); |
| 19575 | if( p ){ |
| 19576 | #ifdef SQLITE_DEBUG |
| 19577 | p->id = iType; |
| 19578 | #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC |
| 19579 | p->trace = 1; |
| 19580 | #endif |
| 19581 | #endif |
| 19582 | #if SQLITE_OS_WINRT |
| 19583 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 19584 | #else |
| 19585 | InitializeCriticalSection(&p->mutex); |
| @@ -19318,16 +19586,19 @@ | |
| 19586 | #endif |
| 19587 | } |
| 19588 | break; |
| 19589 | } |
| 19590 | default: { |
| 19591 | assert( iType-2 >= 0 ); |
| 19592 | assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
| 19593 | assert( winMutex_isInit==1 ); |
| 19594 | p = &winMutex_staticMutexes[iType-2]; |
| 19595 | #ifdef SQLITE_DEBUG |
| 19596 | p->id = iType; |
| 19597 | #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC |
| 19598 | p->trace = 1; |
| 19599 | #endif |
| 19600 | #endif |
| 19601 | break; |
| 19602 | } |
| 19603 | } |
| 19604 | return p; |
| @@ -19339,12 +19610,15 @@ | |
| 19610 | ** allocated mutex. SQLite is careful to deallocate every |
| 19611 | ** mutex that it allocates. |
| 19612 | */ |
| 19613 | static void winMutexFree(sqlite3_mutex *p){ |
| 19614 | assert( p ); |
| 19615 | #ifdef SQLITE_DEBUG |
| 19616 | assert( p->nRef==0 && p->owner==0 ); |
| 19617 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19618 | #endif |
| 19619 | assert( winMutex_isInit==1 ); |
| 19620 | DeleteCriticalSection(&p->mutex); |
| 19621 | sqlite3_free(p); |
| 19622 | } |
| 19623 | |
| 19624 | /* |
| @@ -19357,53 +19631,71 @@ | |
| 19631 | ** mutex must be exited an equal number of times before another thread |
| 19632 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 19633 | ** more than once, the behavior is undefined. |
| 19634 | */ |
| 19635 | static void winMutexEnter(sqlite3_mutex *p){ |
| 19636 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19637 | DWORD tid = GetCurrentThreadId(); |
| 19638 | #endif |
| 19639 | #ifdef SQLITE_DEBUG |
| 19640 | assert( p ); |
| 19641 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19642 | #else |
| 19643 | assert( p ); |
| 19644 | #endif |
| 19645 | assert( winMutex_isInit==1 ); |
| 19646 | EnterCriticalSection(&p->mutex); |
| 19647 | #ifdef SQLITE_DEBUG |
| 19648 | assert( p->nRef>0 || p->owner==0 ); |
| 19649 | p->owner = tid; |
| 19650 | p->nRef++; |
| 19651 | if( p->trace ){ |
| 19652 | OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", |
| 19653 | tid, p, p->trace, p->nRef)); |
| 19654 | } |
| 19655 | #endif |
| 19656 | } |
| 19657 | |
| 19658 | static int winMutexTry(sqlite3_mutex *p){ |
| 19659 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19660 | DWORD tid = GetCurrentThreadId(); |
| 19661 | #endif |
| 19662 | int rc = SQLITE_BUSY; |
| 19663 | assert( p ); |
| 19664 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 19665 | /* |
| 19666 | ** The sqlite3_mutex_try() routine is very rarely used, and when it |
| 19667 | ** is used it is merely an optimization. So it is OK for it to always |
| 19668 | ** fail. |
| 19669 | ** |
| 19670 | ** The TryEnterCriticalSection() interface is only available on WinNT. |
| 19671 | ** And some windows compilers complain if you try to use it without |
| 19672 | ** first doing some #defines that prevent SQLite from building on Win98. |
| 19673 | ** For that reason, we will omit this optimization for now. See |
| 19674 | ** ticket #2685. |
| 19675 | */ |
| 19676 | #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 |
| 19677 | assert( winMutex_isInit==1 ); |
| 19678 | assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); |
| 19679 | if( winMutex_isNt<0 ){ |
| 19680 | winMutex_isNt = sqlite3_win32_is_nt(); |
| 19681 | } |
| 19682 | assert( winMutex_isNt==0 || winMutex_isNt==1 ); |
| 19683 | if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ |
| 19684 | #ifdef SQLITE_DEBUG |
| 19685 | p->owner = tid; |
| 19686 | p->nRef++; |
| 19687 | #endif |
| 19688 | rc = SQLITE_OK; |
| 19689 | } |
| 19690 | #else |
| 19691 | UNUSED_PARAMETER(p); |
| 19692 | #endif |
| 19693 | #ifdef SQLITE_DEBUG |
| 19694 | if( p->trace ){ |
| 19695 | OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", |
| 19696 | tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); |
| 19697 | } |
| 19698 | #endif |
| 19699 | return rc; |
| 19700 | } |
| 19701 | |
| @@ -19412,22 +19704,27 @@ | |
| 19704 | ** previously entered by the same thread. The behavior |
| 19705 | ** is undefined if the mutex is not currently entered or |
| 19706 | ** is not currently allocated. SQLite will never do either. |
| 19707 | */ |
| 19708 | static void winMutexLeave(sqlite3_mutex *p){ |
| 19709 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 19710 | DWORD tid = GetCurrentThreadId(); |
| 19711 | #endif |
| 19712 | assert( p ); |
| 19713 | #ifdef SQLITE_DEBUG |
| 19714 | assert( p->nRef>0 ); |
| 19715 | assert( p->owner==tid ); |
| 19716 | p->nRef--; |
| 19717 | if( p->nRef==0 ) p->owner = 0; |
| 19718 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 19719 | #endif |
| 19720 | assert( winMutex_isInit==1 ); |
| 19721 | LeaveCriticalSection(&p->mutex); |
| 19722 | #ifdef SQLITE_DEBUG |
| 19723 | if( p->trace ){ |
| 19724 | OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", |
| 19725 | tid, p, p->trace, p->nRef)); |
| 19726 | } |
| 19727 | #endif |
| 19728 | } |
| 19729 | |
| 19730 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| @@ -19445,13 +19742,13 @@ | |
| 19742 | #else |
| 19743 | 0, |
| 19744 | 0 |
| 19745 | #endif |
| 19746 | }; |
| 19747 | return &sMutex; |
| 19748 | } |
| 19749 | |
| 19750 | #endif /* SQLITE_MUTEX_W32 */ |
| 19751 | |
| 19752 | /************** End of mutex_w32.c *******************************************/ |
| 19753 | /************** Begin file malloc.c ******************************************/ |
| 19754 | /* |
| @@ -22422,13 +22719,13 @@ | |
| 22719 | testcase( c==(+1) ); |
| 22720 | } |
| 22721 | return c; |
| 22722 | } |
| 22723 | |
| 22724 | /* |
| 22725 | ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This |
| 22726 | ** routine does *not* accept hexadecimal notation. |
| 22727 | ** |
| 22728 | ** If the zNum value is representable as a 64-bit twos-complement |
| 22729 | ** integer, then write that value into *pNum and return 0. |
| 22730 | ** |
| 22731 | ** If zNum is exactly 9223372036854775808, return 2. This special |
| @@ -22511,14 +22808,48 @@ | |
| 22808 | assert( u-1==LARGEST_INT64 ); |
| 22809 | return neg ? 0 : 2; |
| 22810 | } |
| 22811 | } |
| 22812 | } |
| 22813 | |
| 22814 | /* |
| 22815 | ** Transform a UTF-8 integer literal, in either decimal or hexadecimal, |
| 22816 | ** into a 64-bit signed integer. This routine accepts hexadecimal literals, |
| 22817 | ** whereas sqlite3Atoi64() does not. |
| 22818 | ** |
| 22819 | ** Returns: |
| 22820 | ** |
| 22821 | ** 0 Successful transformation. Fits in a 64-bit signed integer. |
| 22822 | ** 1 Integer too large for a 64-bit signed integer or is malformed |
| 22823 | ** 2 Special case of 9223372036854775808 |
| 22824 | */ |
| 22825 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ |
| 22826 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 22827 | if( z[0]=='0' |
| 22828 | && (z[1]=='x' || z[1]=='X') |
| 22829 | && sqlite3Isxdigit(z[2]) |
| 22830 | ){ |
| 22831 | u64 u = 0; |
| 22832 | int i, k; |
| 22833 | for(i=2; z[i]=='0'; i++){} |
| 22834 | for(k=i; sqlite3Isxdigit(z[k]); k++){ |
| 22835 | u = u*16 + sqlite3HexToInt(z[k]); |
| 22836 | } |
| 22837 | memcpy(pOut, &u, 8); |
| 22838 | return (z[k]==0 && k-i<=16) ? 0 : 1; |
| 22839 | }else |
| 22840 | #endif /* SQLITE_OMIT_HEX_INTEGER */ |
| 22841 | { |
| 22842 | return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); |
| 22843 | } |
| 22844 | } |
| 22845 | |
| 22846 | /* |
| 22847 | ** If zNum represents an integer that will fit in 32-bits, then set |
| 22848 | ** *pValue to that integer and return true. Otherwise return false. |
| 22849 | ** |
| 22850 | ** This routine accepts both decimal and hexadecimal notation for integers. |
| 22851 | ** |
| 22852 | ** Any non-numeric characters that following zNum are ignored. |
| 22853 | ** This is different from sqlite3Atoi64() which requires the |
| 22854 | ** input number to be zero-terminated. |
| 22855 | */ |
| @@ -22530,11 +22861,29 @@ | |
| 22861 | neg = 1; |
| 22862 | zNum++; |
| 22863 | }else if( zNum[0]=='+' ){ |
| 22864 | zNum++; |
| 22865 | } |
| 22866 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 22867 | else if( zNum[0]=='0' |
| 22868 | && (zNum[1]=='x' || zNum[1]=='X') |
| 22869 | && sqlite3Isxdigit(zNum[2]) |
| 22870 | ){ |
| 22871 | u32 u = 0; |
| 22872 | zNum += 2; |
| 22873 | while( zNum[0]=='0' ) zNum++; |
| 22874 | for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ |
| 22875 | u = u*16 + sqlite3HexToInt(zNum[i]); |
| 22876 | } |
| 22877 | if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ |
| 22878 | memcpy(pValue, &u, 4); |
| 22879 | return 1; |
| 22880 | }else{ |
| 22881 | return 0; |
| 22882 | } |
| 22883 | } |
| 22884 | #endif |
| 22885 | for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ |
| 22886 | v = v*10 + c; |
| 22887 | } |
| 22888 | |
| 22889 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
| @@ -23606,43 +23955,43 @@ | |
| 23955 | /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23956 | /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23957 | /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23958 | /* 50 */ "ReadCookie" OpHelp(""), |
| 23959 | /* 51 */ "SetCookie" OpHelp(""), |
| 23960 | /* 52 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 23961 | /* 53 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23962 | /* 54 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23963 | /* 55 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23964 | /* 56 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23965 | /* 57 */ "SorterOpen" OpHelp(""), |
| 23966 | /* 58 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 23967 | /* 59 */ "Close" OpHelp(""), |
| 23968 | /* 60 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 23969 | /* 61 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 23970 | /* 62 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 23971 | /* 63 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 23972 | /* 64 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23973 | /* 65 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23974 | /* 66 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23975 | /* 67 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23976 | /* 68 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23977 | /* 69 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23978 | /* 70 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23979 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23980 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23981 | /* 73 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23982 | /* 74 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23983 | /* 75 */ "Delete" OpHelp(""), |
| 23984 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23985 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23986 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23987 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23988 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23989 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23990 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23991 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23992 | /* 84 */ "ResetCount" OpHelp(""), |
| 23993 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23994 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23995 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23996 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23997 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| @@ -23649,73 +23998,74 @@ | |
| 23998 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23999 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 24000 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 24001 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 24002 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 24003 | /* 95 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 24004 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 24005 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 24006 | /* 98 */ "SorterData" OpHelp("r[P2]=data"), |
| 24007 | /* 99 */ "RowKey" OpHelp("r[P2]=key"), |
| 24008 | /* 100 */ "RowData" OpHelp("r[P2]=data"), |
| 24009 | /* 101 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 24010 | /* 102 */ "NullRow" OpHelp(""), |
| 24011 | /* 103 */ "Last" OpHelp(""), |
| 24012 | /* 104 */ "SorterSort" OpHelp(""), |
| 24013 | /* 105 */ "Sort" OpHelp(""), |
| 24014 | /* 106 */ "Rewind" OpHelp(""), |
| 24015 | /* 107 */ "SorterInsert" OpHelp(""), |
| 24016 | /* 108 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 24017 | /* 109 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 24018 | /* 110 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 24019 | /* 111 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 24020 | /* 112 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 24021 | /* 113 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 24022 | /* 114 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 24023 | /* 115 */ "Destroy" OpHelp(""), |
| 24024 | /* 116 */ "Clear" OpHelp(""), |
| 24025 | /* 117 */ "ResetSorter" OpHelp(""), |
| 24026 | /* 118 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 24027 | /* 119 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 24028 | /* 120 */ "ParseSchema" OpHelp(""), |
| 24029 | /* 121 */ "LoadAnalysis" OpHelp(""), |
| 24030 | /* 122 */ "DropTable" OpHelp(""), |
| 24031 | /* 123 */ "DropIndex" OpHelp(""), |
| 24032 | /* 124 */ "DropTrigger" OpHelp(""), |
| 24033 | /* 125 */ "IntegrityCk" OpHelp(""), |
| 24034 | /* 126 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 24035 | /* 127 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 24036 | /* 128 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 24037 | /* 129 */ "Program" OpHelp(""), |
| 24038 | /* 130 */ "Param" OpHelp(""), |
| 24039 | /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24040 | /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24041 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24042 | /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24043 | /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24044 | /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 24045 | /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24046 | /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24047 | /* 139 */ "IncrVacuum" OpHelp(""), |
| 24048 | /* 140 */ "Expire" OpHelp(""), |
| 24049 | /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 24050 | /* 142 */ "VBegin" OpHelp(""), |
| 24051 | /* 143 */ "ToText" OpHelp(""), |
| 24052 | /* 144 */ "ToBlob" OpHelp(""), |
| 24053 | /* 145 */ "ToNumeric" OpHelp(""), |
| 24054 | /* 146 */ "ToInt" OpHelp(""), |
| 24055 | /* 147 */ "ToReal" OpHelp(""), |
| 24056 | /* 148 */ "VCreate" OpHelp(""), |
| 24057 | /* 149 */ "VDestroy" OpHelp(""), |
| 24058 | /* 150 */ "VOpen" OpHelp(""), |
| 24059 | /* 151 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 24060 | /* 152 */ "VNext" OpHelp(""), |
| 24061 | /* 153 */ "VRename" OpHelp(""), |
| 24062 | /* 154 */ "Pagecount" OpHelp(""), |
| 24063 | /* 155 */ "MaxPgcnt" OpHelp(""), |
| 24064 | /* 156 */ "Init" OpHelp("Start at P2"), |
| 24065 | /* 157 */ "Noop" OpHelp(""), |
| 24066 | /* 158 */ "Explain" OpHelp(""), |
| 24067 | }; |
| 24068 | return azName[i]; |
| 24069 | } |
| 24070 | #endif |
| 24071 | |
| @@ -32066,14 +32416,14 @@ | |
| 32416 | ** |
| 32417 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32418 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32419 | */ |
| 32420 | #ifdef SQLITE_TEST |
| 32421 | SQLITE_API LONG volatile sqlite3_os_type = 0; |
| 32422 | #elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 32423 | defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 32424 | static LONG volatile sqlite3_os_type = 0; |
| 32425 | #endif |
| 32426 | |
| 32427 | #ifndef SYSCALL |
| 32428 | # define SYSCALL sqlite3_syscall_ptr |
| 32429 | #endif |
| @@ -32699,10 +33049,15 @@ | |
| 33049 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 33050 | #endif |
| 33051 | |
| 33052 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 33053 | LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) |
| 33054 | |
| 33055 | { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, |
| 33056 | |
| 33057 | #define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \ |
| 33058 | LONG,LONG))aSyscall[76].pCurrent) |
| 33059 | |
| 33060 | }; /* End of the overrideable system calls */ |
| 33061 | |
| 33062 | /* |
| 33063 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -32950,26 +33305,33 @@ | |
| 33305 | #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 33306 | # define osIsNT() (1) |
| 33307 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 33308 | # define osIsNT() (0) |
| 33309 | #else |
| 33310 | # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) |
| 33311 | #endif |
| 33312 | |
| 33313 | /* |
| 33314 | ** This function determines if the machine is running a version of Windows |
| 33315 | ** based on the NT kernel. |
| 33316 | */ |
| 33317 | SQLITE_API int sqlite3_win32_is_nt(void){ |
| 33318 | if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ |
| 33319 | #if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 33320 | OSVERSIONINFOW sInfo; |
| 33321 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 33322 | osGetVersionExW(&sInfo); |
| 33323 | #else |
| 33324 | OSVERSIONINFOA sInfo; |
| 33325 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 33326 | osGetVersionExA(&sInfo); |
| 33327 | #endif |
| 33328 | osInterlockedCompareExchange(&sqlite3_os_type, |
| 33329 | (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); |
| 33330 | } |
| 33331 | return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; |
| 33332 | } |
| 33333 | |
| 33334 | #ifdef SQLITE_WIN32_MALLOC |
| 33335 | /* |
| 33336 | ** Allocate nBytes of memory. |
| 33337 | */ |
| @@ -37121,11 +37483,11 @@ | |
| 37483 | }; |
| 37484 | #endif |
| 37485 | |
| 37486 | /* Double-check that the aSyscall[] array has been constructed |
| 37487 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 37488 | assert( ArraySize(aSyscall)==77 ); |
| 37489 | |
| 37490 | /* get memory map allocation granularity */ |
| 37491 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 37492 | #if SQLITE_OS_WINRT |
| 37493 | osGetNativeSystemInfo(&winSysInfo); |
| @@ -52813,11 +53175,11 @@ | |
| 53175 | return pBt->nPage; |
| 53176 | } |
| 53177 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ |
| 53178 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 53179 | assert( ((p->pBt->nPage)&0x8000000)==0 ); |
| 53180 | return btreePagecount(p->pBt); |
| 53181 | } |
| 53182 | |
| 53183 | /* |
| 53184 | ** Get a page from the pager and initialize it. This routine is just a |
| 53185 | ** convenience wrapper around separate calls to btreeGetPage() and |
| @@ -62354,11 +62716,11 @@ | |
| 62716 | } |
| 62717 | sqlite3DbFree(p->db, pParse->aLabel); |
| 62718 | pParse->aLabel = 0; |
| 62719 | pParse->nLabel = 0; |
| 62720 | *pMaxFuncArgs = nMaxArgs; |
| 62721 | assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); |
| 62722 | } |
| 62723 | |
| 62724 | /* |
| 62725 | ** Return the address of the next instruction to be inserted. |
| 62726 | */ |
| @@ -62381,11 +62743,11 @@ | |
| 62743 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ |
| 62744 | VdbeOp *aOp = p->aOp; |
| 62745 | assert( aOp && !p->db->mallocFailed ); |
| 62746 | |
| 62747 | /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ |
| 62748 | assert( DbMaskAllZero(p->btreeMask) ); |
| 62749 | |
| 62750 | resolveP2Values(p, pnMaxArg); |
| 62751 | *pnOp = p->nOp; |
| 62752 | p->aOp = 0; |
| 62753 | return aOp; |
| @@ -62966,13 +63328,13 @@ | |
| 63328 | ** p->btreeMask of databases that will require a lock. |
| 63329 | */ |
| 63330 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 63331 | assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); |
| 63332 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 63333 | DbMaskSet(p->btreeMask, i); |
| 63334 | if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ |
| 63335 | DbMaskSet(p->lockMask, i); |
| 63336 | } |
| 63337 | } |
| 63338 | |
| 63339 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 63340 | /* |
| @@ -62996,20 +63358,19 @@ | |
| 63358 | ** this routine is N*N. But as N is rarely more than 1, this should not |
| 63359 | ** be a problem. |
| 63360 | */ |
| 63361 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ |
| 63362 | int i; |
| 63363 | sqlite3 *db; |
| 63364 | Db *aDb; |
| 63365 | int nDb; |
| 63366 | if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ |
| 63367 | db = p->db; |
| 63368 | aDb = db->aDb; |
| 63369 | nDb = db->nDb; |
| 63370 | for(i=0; i<nDb; i++){ |
| 63371 | if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ |
| 63372 | sqlite3BtreeEnter(aDb[i].pBt); |
| 63373 | } |
| 63374 | } |
| 63375 | } |
| 63376 | #endif |
| @@ -63018,20 +63379,19 @@ | |
| 63379 | /* |
| 63380 | ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). |
| 63381 | */ |
| 63382 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ |
| 63383 | int i; |
| 63384 | sqlite3 *db; |
| 63385 | Db *aDb; |
| 63386 | int nDb; |
| 63387 | if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ |
| 63388 | db = p->db; |
| 63389 | aDb = db->aDb; |
| 63390 | nDb = db->nDb; |
| 63391 | for(i=0; i<nDb; i++){ |
| 63392 | if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ |
| 63393 | sqlite3BtreeLeave(aDb[i].pBt); |
| 63394 | } |
| 63395 | } |
| 63396 | } |
| 63397 | #endif |
| @@ -63998,11 +64358,11 @@ | |
| 64358 | int cnt = 0; |
| 64359 | int nWrite = 0; |
| 64360 | int nRead = 0; |
| 64361 | p = db->pVdbe; |
| 64362 | while( p ){ |
| 64363 | if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ |
| 64364 | cnt++; |
| 64365 | if( p->readOnly==0 ) nWrite++; |
| 64366 | if( p->bIsReader ) nRead++; |
| 64367 | } |
| 64368 | p = p->pNext; |
| @@ -64643,11 +65003,11 @@ | |
| 65003 | /* |
| 65004 | ** Return the serial-type for the value stored in pMem. |
| 65005 | */ |
| 65006 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ |
| 65007 | int flags = pMem->flags; |
| 65008 | u32 n; |
| 65009 | |
| 65010 | if( flags&MEM_Null ){ |
| 65011 | return 0; |
| 65012 | } |
| 65013 | if( flags&MEM_Int ){ |
| @@ -64673,15 +65033,15 @@ | |
| 65033 | } |
| 65034 | if( flags&MEM_Real ){ |
| 65035 | return 7; |
| 65036 | } |
| 65037 | assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); |
| 65038 | assert( pMem->n>=0 ); |
| 65039 | n = (u32)pMem->n; |
| 65040 | if( flags & MEM_Zero ){ |
| 65041 | n += pMem->u.nZero; |
| 65042 | } |
| 65043 | return ((n*2) + 12 + ((flags&MEM_Str)!=0)); |
| 65044 | } |
| 65045 | |
| 65046 | /* |
| 65047 | ** Return the length of the data corresponding to the supplied serial-type. |
| @@ -67195,11 +67555,11 @@ | |
| 67555 | /* |
| 67556 | ** Return true if the prepared statement is in need of being reset. |
| 67557 | */ |
| 67558 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| 67559 | Vdbe *v = (Vdbe*)pStmt; |
| 67560 | return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; |
| 67561 | } |
| 67562 | |
| 67563 | /* |
| 67564 | ** Return a pointer to the next prepared statement after pStmt associated |
| 67565 | ** with database connection pDb. If pStmt is NULL, return the first |
| @@ -67753,25 +68113,25 @@ | |
| 68113 | ** do so without loss of information. In other words, if the string |
| 68114 | ** looks like a number, convert it into a number. If it does not |
| 68115 | ** look like a number, leave it alone. |
| 68116 | */ |
| 68117 | static void applyNumericAffinity(Mem *pRec){ |
| 68118 | double rValue; |
| 68119 | i64 iValue; |
| 68120 | u8 enc = pRec->enc; |
| 68121 | if( (pRec->flags&MEM_Str)==0 ) return; |
| 68122 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; |
| 68123 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ |
| 68124 | pRec->u.i = iValue; |
| 68125 | pRec->flags |= MEM_Int; |
| 68126 | }else{ |
| 68127 | pRec->r = rValue; |
| 68128 | pRec->flags |= MEM_Real; |
| 68129 | } |
| 68130 | } |
| 68131 | #define ApplyNumericAffinity(X) \ |
| 68132 | if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} |
| 68133 | |
| 68134 | /* |
| 68135 | ** Processing is determine by the affinity parameter: |
| 68136 | ** |
| 68137 | ** SQLITE_AFF_INTEGER: |
| @@ -67804,11 +68164,11 @@ | |
| 68164 | } |
| 68165 | pRec->flags &= ~(MEM_Real|MEM_Int); |
| 68166 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 68167 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 68168 | || affinity==SQLITE_AFF_NUMERIC ); |
| 68169 | ApplyNumericAffinity(pRec); |
| 68170 | if( pRec->flags & MEM_Real ){ |
| 68171 | sqlite3VdbeIntegerAffinity(pRec); |
| 68172 | } |
| 68173 | } |
| 68174 | } |
| @@ -68385,16 +68745,18 @@ | |
| 68745 | break; |
| 68746 | } |
| 68747 | |
| 68748 | /* Opcode: InitCoroutine P1 P2 P3 * * |
| 68749 | ** |
| 68750 | ** Set up register P1 so that it will Yield to the coroutine |
| 68751 | ** located at address P3. |
| 68752 | ** |
| 68753 | ** If P2!=0 then the coroutine implementation immediately follows |
| 68754 | ** this opcode. So jump over the coroutine implementation to |
| 68755 | ** address P2. |
| 68756 | ** |
| 68757 | ** See also: EndCoroutine |
| 68758 | */ |
| 68759 | case OP_InitCoroutine: { /* jump */ |
| 68760 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 68761 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 68762 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -68406,13 +68768,15 @@ | |
| 68768 | break; |
| 68769 | } |
| 68770 | |
| 68771 | /* Opcode: EndCoroutine P1 * * * * |
| 68772 | ** |
| 68773 | ** The instruction at the address in register P1 is an Yield. |
| 68774 | ** Jump to the P2 parameter of that Yield. |
| 68775 | ** After the jump, register P1 becomes undefined. |
| 68776 | ** |
| 68777 | ** See also: InitCoroutine |
| 68778 | */ |
| 68779 | case OP_EndCoroutine: { /* in1 */ |
| 68780 | VdbeOp *pCaller; |
| 68781 | pIn1 = &aMem[pOp->p1]; |
| 68782 | assert( pIn1->flags==MEM_Int ); |
| @@ -68425,15 +68789,20 @@ | |
| 68789 | break; |
| 68790 | } |
| 68791 | |
| 68792 | /* Opcode: Yield P1 P2 * * * |
| 68793 | ** |
| 68794 | ** Swap the program counter with the value in register P1. This |
| 68795 | ** has the effect of yielding to a coroutine. |
| 68796 | ** |
| 68797 | ** If the coroutine that is launched by this instruction ends with |
| 68798 | ** Yield or Return then continue to the next instruction. But if |
| 68799 | ** the coroutine launched by this instruction ends with |
| 68800 | ** EndCoroutine, then jump to P2 rather than continuing with the |
| 68801 | ** next instruction. |
| 68802 | ** |
| 68803 | ** See also: InitCoroutine |
| 68804 | */ |
| 68805 | case OP_Yield: { /* in1, jump */ |
| 68806 | int pcDest; |
| 68807 | pIn1 = &aMem[pOp->p1]; |
| 68808 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -69814,14 +70183,18 @@ | |
| 70183 | break; |
| 70184 | } |
| 70185 | |
| 70186 | /* Opcode: Once P1 P2 * * * |
| 70187 | ** |
| 70188 | ** Check the "once" flag number P1. If it is set, jump to instruction P2. |
| 70189 | ** Otherwise, set the flag and fall through to the next instruction. |
| 70190 | ** In other words, this opcode causes all following opcodes up through P2 |
| 70191 | ** (but not including P2) to run just once and to be skipped on subsequent |
| 70192 | ** times through the loop. |
| 70193 | ** |
| 70194 | ** All "once" flags are initially cleared whenever a prepared statement |
| 70195 | ** first begins to run. |
| 70196 | */ |
| 70197 | case OP_Once: { /* jump */ |
| 70198 | assert( pOp->p1<p->nOnceFlag ); |
| 70199 | VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); |
| 70200 | if( p->aOnceFlag[pOp->p1] ){ |
| @@ -70652,11 +71025,11 @@ | |
| 71025 | int iGen; |
| 71026 | |
| 71027 | assert( p->bIsReader ); |
| 71028 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 71029 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 71030 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 71031 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 71032 | rc = SQLITE_READONLY; |
| 71033 | goto abort_due_to_error; |
| 71034 | } |
| 71035 | pBt = db->aDb[pOp->p1].pBt; |
| @@ -70747,11 +71120,11 @@ | |
| 71120 | iDb = pOp->p1; |
| 71121 | iCookie = pOp->p3; |
| 71122 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 71123 | assert( iDb>=0 && iDb<db->nDb ); |
| 71124 | assert( db->aDb[iDb].pBt!=0 ); |
| 71125 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 71126 | |
| 71127 | sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 71128 | pOut->u.i = iMeta; |
| 71129 | break; |
| 71130 | } |
| @@ -70768,11 +71141,11 @@ | |
| 71141 | */ |
| 71142 | case OP_SetCookie: { /* in3 */ |
| 71143 | Db *pDb; |
| 71144 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 71145 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 71146 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 71147 | assert( p->readOnly==0 ); |
| 71148 | pDb = &db->aDb[pOp->p1]; |
| 71149 | assert( pDb->pBt!=0 ); |
| 71150 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 71151 | pIn3 = &aMem[pOp->p3]; |
| @@ -70823,11 +71196,25 @@ | |
| 71196 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
| 71197 | ** structure, then said structure defines the content and collating |
| 71198 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
| 71199 | ** value, it is set to the number of columns in the table. |
| 71200 | ** |
| 71201 | ** See also: OpenWrite, ReopenIdx |
| 71202 | */ |
| 71203 | /* Opcode: ReopenIdx P1 P2 P3 P4 P5 |
| 71204 | ** Synopsis: root=P2 iDb=P3 |
| 71205 | ** |
| 71206 | ** The ReopenIdx opcode works exactly like ReadOpen except that it first |
| 71207 | ** checks to see if the cursor on P1 is already open with a root page |
| 71208 | ** number of P2 and if it is this opcode becomes a no-op. In other words, |
| 71209 | ** if the cursor is already open, do not reopen it. |
| 71210 | ** |
| 71211 | ** The ReopenIdx opcode may only be used with P5==0 and with P4 being |
| 71212 | ** a P4_KEYINFO object. Furthermore, the P3 value must be the same as |
| 71213 | ** every other ReopenIdx or OpenRead for the same cursor number. |
| 71214 | ** |
| 71215 | ** See the OpenRead opcode documentation for additional information. |
| 71216 | */ |
| 71217 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
| 71218 | ** Synopsis: root=P2 iDb=P3 |
| 71219 | ** |
| 71220 | ** Open a read/write cursor named P1 on the table or index whose root |
| @@ -70845,10 +71232,23 @@ | |
| 71232 | ** in read/write mode. For a given table, there can be one or more read-only |
| 71233 | ** cursors or a single read/write cursor but not both. |
| 71234 | ** |
| 71235 | ** See also OpenRead. |
| 71236 | */ |
| 71237 | case OP_ReopenIdx: { |
| 71238 | VdbeCursor *pCur; |
| 71239 | |
| 71240 | assert( pOp->p5==0 ); |
| 71241 | assert( pOp->p4type==P4_KEYINFO ); |
| 71242 | pCur = p->apCsr[pOp->p1]; |
| 71243 | if( pCur && pCur->pgnoRoot==pOp->p2 ){ |
| 71244 | assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ |
| 71245 | break; |
| 71246 | } |
| 71247 | /* If the cursor is not currently open or is open on a different |
| 71248 | ** index, then fall through into OP_OpenRead to force a reopen */ |
| 71249 | } |
| 71250 | case OP_OpenRead: |
| 71251 | case OP_OpenWrite: { |
| 71252 | int nField; |
| 71253 | KeyInfo *pKeyInfo; |
| 71254 | int p2; |
| @@ -70859,11 +71259,12 @@ | |
| 71259 | Db *pDb; |
| 71260 | |
| 71261 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 71262 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 71263 | assert( p->bIsReader ); |
| 71264 | assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx |
| 71265 | || p->readOnly==0 ); |
| 71266 | |
| 71267 | if( p->expired ){ |
| 71268 | rc = SQLITE_ABORT; |
| 71269 | break; |
| 71270 | } |
| @@ -70871,11 +71272,11 @@ | |
| 71272 | nField = 0; |
| 71273 | pKeyInfo = 0; |
| 71274 | p2 = pOp->p2; |
| 71275 | iDb = pOp->p3; |
| 71276 | assert( iDb>=0 && iDb<db->nDb ); |
| 71277 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 71278 | pDb = &db->aDb[iDb]; |
| 71279 | pX = pDb->pBt; |
| 71280 | assert( pX!=0 ); |
| 71281 | if( pOp->opcode==OP_OpenWrite ){ |
| 71282 | wrFlag = 1; |
| @@ -70916,10 +71317,11 @@ | |
| 71317 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 71318 | pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 71319 | if( pCur==0 ) goto no_mem; |
| 71320 | pCur->nullRow = 1; |
| 71321 | pCur->isOrdered = 1; |
| 71322 | pCur->pgnoRoot = p2; |
| 71323 | rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 71324 | pCur->pKeyInfo = pKeyInfo; |
| 71325 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 71326 | sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 71327 | |
| @@ -71070,11 +71472,11 @@ | |
| 71472 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 71473 | p->apCsr[pOp->p1] = 0; |
| 71474 | break; |
| 71475 | } |
| 71476 | |
| 71477 | /* Opcode: SeekGE P1 P2 P3 P4 * |
| 71478 | ** Synopsis: key=r[P3@P4] |
| 71479 | ** |
| 71480 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71481 | ** use the value in register P3 as the key. If cursor P1 refers |
| 71482 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71081,14 +71483,18 @@ | |
| 71483 | ** that are used as an unpacked index key. |
| 71484 | ** |
| 71485 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71486 | ** is greater than or equal to the key value. If there are no records |
| 71487 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71488 | ** |
| 71489 | ** This opcode leaves the cursor configured to move in forward order, |
| 71490 | ** from the begining toward the end. In other words, the cursor is |
| 71491 | ** configured to use Next, not Prev. |
| 71492 | ** |
| 71493 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71494 | */ |
| 71495 | /* Opcode: SeekGT P1 P2 P3 P4 * |
| 71496 | ** Synopsis: key=r[P3@P4] |
| 71497 | ** |
| 71498 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71499 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71500 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71095,14 +71501,18 @@ | |
| 71501 | ** that are used as an unpacked index key. |
| 71502 | ** |
| 71503 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71504 | ** is greater than the key value. If there are no records greater than |
| 71505 | ** the key and P2 is not zero, then jump to P2. |
| 71506 | ** |
| 71507 | ** This opcode leaves the cursor configured to move in forward order, |
| 71508 | ** from the begining toward the end. In other words, the cursor is |
| 71509 | ** configured to use Next, not Prev. |
| 71510 | ** |
| 71511 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 71512 | */ |
| 71513 | /* Opcode: SeekLT P1 P2 P3 P4 * |
| 71514 | ** Synopsis: key=r[P3@P4] |
| 71515 | ** |
| 71516 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71517 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71518 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71109,14 +71519,18 @@ | |
| 71519 | ** that are used as an unpacked index key. |
| 71520 | ** |
| 71521 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71522 | ** is less than the key value. If there are no records less than |
| 71523 | ** the key and P2 is not zero, then jump to P2. |
| 71524 | ** |
| 71525 | ** This opcode leaves the cursor configured to move in reverse order, |
| 71526 | ** from the end toward the beginning. In other words, the cursor is |
| 71527 | ** configured to use Prev, not Next. |
| 71528 | ** |
| 71529 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 71530 | */ |
| 71531 | /* Opcode: SeekLE P1 P2 P3 P4 * |
| 71532 | ** Synopsis: key=r[P3@P4] |
| 71533 | ** |
| 71534 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| 71535 | ** use the value in register P3 as a key. If cursor P1 refers |
| 71536 | ** to an SQL index, then P3 is the first in an array of P4 registers |
| @@ -71123,10 +71537,14 @@ | |
| 71537 | ** that are used as an unpacked index key. |
| 71538 | ** |
| 71539 | ** Reposition cursor P1 so that it points to the largest entry that |
| 71540 | ** is less than or equal to the key value. If there are no records |
| 71541 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 71542 | ** |
| 71543 | ** This opcode leaves the cursor configured to move in reverse order, |
| 71544 | ** from the end toward the beginning. In other words, the cursor is |
| 71545 | ** configured to use Prev, not Next. |
| 71546 | ** |
| 71547 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 71548 | */ |
| 71549 | case OP_SeekLT: /* jump, in3 */ |
| 71550 | case OP_SeekLE: /* jump, in3 */ |
| @@ -71149,16 +71567,19 @@ | |
| 71567 | assert( OP_SeekGT == OP_SeekLT+3 ); |
| 71568 | assert( pC->isOrdered ); |
| 71569 | assert( pC->pCursor!=0 ); |
| 71570 | oc = pOp->opcode; |
| 71571 | pC->nullRow = 0; |
| 71572 | #ifdef SQLITE_DEBUG |
| 71573 | pC->seekOp = pOp->opcode; |
| 71574 | #endif |
| 71575 | if( pC->isTable ){ |
| 71576 | /* The input value in P3 might be of any type: integer, real, string, |
| 71577 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71578 | ** the seek, so covert it. */ |
| 71579 | pIn3 = &aMem[pOp->p3]; |
| 71580 | ApplyNumericAffinity(pIn3); |
| 71581 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71582 | pC->rowidIsValid = 0; |
| 71583 | |
| 71584 | /* If the P3 value could not be converted into an integer without |
| 71585 | ** loss of information, then special processing is required... */ |
| @@ -71303,10 +71724,14 @@ | |
| 71724 | ** record. |
| 71725 | ** |
| 71726 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71727 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71728 | ** P1 is left pointing at the matching entry. |
| 71729 | ** |
| 71730 | ** This operation leaves the cursor in a state where it cannot be |
| 71731 | ** advanced in either direction. In other words, the Next and Prev |
| 71732 | ** opcodes do not work after this operation. |
| 71733 | ** |
| 71734 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71735 | */ |
| 71736 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71737 | ** Synopsis: key=r[P3@P4] |
| @@ -71318,10 +71743,14 @@ | |
| 71743 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71744 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
| 71745 | ** does contain an entry whose prefix matches the P3/P4 record then control |
| 71746 | ** falls through to the next instruction and P1 is left pointing at the |
| 71747 | ** matching entry. |
| 71748 | ** |
| 71749 | ** This operation leaves the cursor in a state where it cannot be |
| 71750 | ** advanced in either direction. In other words, the Next and Prev |
| 71751 | ** opcodes do not work after this operation. |
| 71752 | ** |
| 71753 | ** See also: Found, NotExists, NoConflict |
| 71754 | */ |
| 71755 | /* Opcode: NoConflict P1 P2 P3 P4 * |
| 71756 | ** Synopsis: key=r[P3@P4] |
| @@ -71337,10 +71766,14 @@ | |
| 71766 | ** immediately to P2. If there is a match, fall through and leave the P1 |
| 71767 | ** cursor pointing to the matching row. |
| 71768 | ** |
| 71769 | ** This opcode is similar to OP_NotFound with the exceptions that the |
| 71770 | ** branch is always taken if any part of the search key input is NULL. |
| 71771 | ** |
| 71772 | ** This operation leaves the cursor in a state where it cannot be |
| 71773 | ** advanced in either direction. In other words, the Next and Prev |
| 71774 | ** opcodes do not work after this operation. |
| 71775 | ** |
| 71776 | ** See also: NotFound, Found, NotExists |
| 71777 | */ |
| 71778 | case OP_NoConflict: /* jump, in3 */ |
| 71779 | case OP_NotFound: /* jump, in3 */ |
| @@ -71360,10 +71793,13 @@ | |
| 71793 | |
| 71794 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71795 | assert( pOp->p4type==P4_INT32 ); |
| 71796 | pC = p->apCsr[pOp->p1]; |
| 71797 | assert( pC!=0 ); |
| 71798 | #ifdef SQLITE_DEBUG |
| 71799 | pC->seekOp = 0; |
| 71800 | #endif |
| 71801 | pIn3 = &aMem[pOp->p3]; |
| 71802 | assert( pC->pCursor!=0 ); |
| 71803 | assert( pC->isTable==0 ); |
| 71804 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 71805 | if( pOp->p4.i>0 ){ |
| @@ -71430,10 +71866,14 @@ | |
| 71866 | ** with rowid P3 then leave the cursor pointing at that record and fall |
| 71867 | ** through to the next instruction. |
| 71868 | ** |
| 71869 | ** The OP_NotFound opcode performs the same operation on index btrees |
| 71870 | ** (with arbitrary multi-value keys). |
| 71871 | ** |
| 71872 | ** This opcode leaves the cursor in a state where it cannot be advanced |
| 71873 | ** in either direction. In other words, the Next and Prev opcodes will |
| 71874 | ** not work following this opcode. |
| 71875 | ** |
| 71876 | ** See also: Found, NotFound, NoConflict |
| 71877 | */ |
| 71878 | case OP_NotExists: { /* jump, in3 */ |
| 71879 | VdbeCursor *pC; |
| @@ -71444,10 +71884,13 @@ | |
| 71884 | pIn3 = &aMem[pOp->p3]; |
| 71885 | assert( pIn3->flags & MEM_Int ); |
| 71886 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71887 | pC = p->apCsr[pOp->p1]; |
| 71888 | assert( pC!=0 ); |
| 71889 | #ifdef SQLITE_DEBUG |
| 71890 | pC->seekOp = 0; |
| 71891 | #endif |
| 71892 | assert( pC->isTable ); |
| 71893 | assert( pC->pseudoTableReg==0 ); |
| 71894 | pCrsr = pC->pCursor; |
| 71895 | assert( pCrsr!=0 ); |
| 71896 | res = 0; |
| @@ -71806,16 +72249,16 @@ | |
| 72249 | p->nChange = 0; |
| 72250 | break; |
| 72251 | } |
| 72252 | |
| 72253 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 72254 | ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 |
| 72255 | ** |
| 72256 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 72257 | ** the record blob in register P3 against a prefix of the entry that |
| 72258 | ** the sorter cursor currently points to. Only the first P4 fields |
| 72259 | ** of r[P3] and the sorter record are compared. |
| 72260 | ** |
| 72261 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 72262 | ** fields (not counting the P4 fields at the end which are ignored) then |
| 72263 | ** the comparison is assumed to be equal. |
| 72264 | ** |
| @@ -71823,18 +72266,18 @@ | |
| 72266 | ** each other. Jump to P2 if they are different. |
| 72267 | */ |
| 72268 | case OP_SorterCompare: { |
| 72269 | VdbeCursor *pC; |
| 72270 | int res; |
| 72271 | int nKeyCol; |
| 72272 | |
| 72273 | pC = p->apCsr[pOp->p1]; |
| 72274 | assert( isSorter(pC) ); |
| 72275 | assert( pOp->p4type==P4_INT32 ); |
| 72276 | pIn3 = &aMem[pOp->p3]; |
| 72277 | nKeyCol = pOp->p4.i; |
| 72278 | rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); |
| 72279 | VdbeBranchTaken(res!=0,2); |
| 72280 | if( res ){ |
| 72281 | pc = pOp->p2-1; |
| 72282 | } |
| 72283 | break; |
| @@ -72010,15 +72453,19 @@ | |
| 72453 | break; |
| 72454 | } |
| 72455 | |
| 72456 | /* Opcode: Last P1 P2 * * * |
| 72457 | ** |
| 72458 | ** The next use of the Rowid or Column or Prev instruction for P1 |
| 72459 | ** will refer to the last entry in the database table or index. |
| 72460 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72461 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72462 | ** to the following instruction. |
| 72463 | ** |
| 72464 | ** This opcode leaves the cursor configured to move in reverse order, |
| 72465 | ** from the end toward the beginning. In other words, the cursor is |
| 72466 | ** configured to use Prev, not Next. |
| 72467 | */ |
| 72468 | case OP_Last: { /* jump */ |
| 72469 | VdbeCursor *pC; |
| 72470 | BtCursor *pCrsr; |
| 72471 | int res; |
| @@ -72032,10 +72479,13 @@ | |
| 72479 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 72480 | pC->nullRow = (u8)res; |
| 72481 | pC->deferredMoveto = 0; |
| 72482 | pC->rowidIsValid = 0; |
| 72483 | pC->cacheStatus = CACHE_STALE; |
| 72484 | #ifdef SQLITE_DEBUG |
| 72485 | pC->seekOp = OP_Last; |
| 72486 | #endif |
| 72487 | if( pOp->p2>0 ){ |
| 72488 | VdbeBranchTaken(res!=0,2); |
| 72489 | if( res ) pc = pOp->p2 - 1; |
| 72490 | } |
| 72491 | break; |
| @@ -72068,10 +72518,14 @@ | |
| 72518 | ** The next use of the Rowid or Column or Next instruction for P1 |
| 72519 | ** will refer to the first entry in the database table or index. |
| 72520 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 72521 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 72522 | ** to the following instruction. |
| 72523 | ** |
| 72524 | ** This opcode leaves the cursor configured to move in forward order, |
| 72525 | ** from the begining toward the end. In other words, the cursor is |
| 72526 | ** configured to use Next, not Prev. |
| 72527 | */ |
| 72528 | case OP_Rewind: { /* jump */ |
| 72529 | VdbeCursor *pC; |
| 72530 | BtCursor *pCrsr; |
| 72531 | int res; |
| @@ -72079,10 +72533,13 @@ | |
| 72533 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72534 | pC = p->apCsr[pOp->p1]; |
| 72535 | assert( pC!=0 ); |
| 72536 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 72537 | res = 1; |
| 72538 | #ifdef SQLITE_DEBUG |
| 72539 | pC->seekOp = OP_Rewind; |
| 72540 | #endif |
| 72541 | if( isSorter(pC) ){ |
| 72542 | rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 72543 | }else{ |
| 72544 | pCrsr = pC->pCursor; |
| 72545 | assert( pCrsr ); |
| @@ -72104,10 +72561,14 @@ | |
| 72561 | ** |
| 72562 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 72563 | ** table or index. If there are no more key/value pairs then fall through |
| 72564 | ** to the following instruction. But if the cursor advance was successful, |
| 72565 | ** jump immediately to P2. |
| 72566 | ** |
| 72567 | ** The Next opcode is only valid following an SeekGT, SeekGE, or |
| 72568 | ** OP_Rewind opcode used to position the cursor. Next is not allowed |
| 72569 | ** to follow SeekLT, SeekLE, or OP_Last. |
| 72570 | ** |
| 72571 | ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 72572 | ** been opened prior to this opcode or the program will segfault. |
| 72573 | ** |
| 72574 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| @@ -72123,20 +72584,25 @@ | |
| 72584 | ** |
| 72585 | ** See also: Prev, NextIfOpen |
| 72586 | */ |
| 72587 | /* Opcode: NextIfOpen P1 P2 P3 P4 P5 |
| 72588 | ** |
| 72589 | ** This opcode works just like Next except that if cursor P1 is not |
| 72590 | ** open it behaves a no-op. |
| 72591 | */ |
| 72592 | /* Opcode: Prev P1 P2 P3 P4 P5 |
| 72593 | ** |
| 72594 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 72595 | ** table or index. If there is no previous key/value pairs then fall through |
| 72596 | ** to the following instruction. But if the cursor backup was successful, |
| 72597 | ** jump immediately to P2. |
| 72598 | ** |
| 72599 | ** |
| 72600 | ** The Prev opcode is only valid following an SeekLT, SeekLE, or |
| 72601 | ** OP_Last opcode used to position the cursor. Prev is not allowed |
| 72602 | ** to follow SeekGT, SeekGE, or OP_Rewind. |
| 72603 | ** |
| 72604 | ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 72605 | ** not open then the behavior is undefined. |
| 72606 | ** |
| 72607 | ** The P3 value is a hint to the btree implementation. If P3==1, that |
| 72608 | ** means P1 is an SQL index and that this instruction could have been |
| @@ -72149,11 +72615,11 @@ | |
| 72615 | ** If P5 is positive and the jump is taken, then event counter |
| 72616 | ** number P5-1 in the prepared statement is incremented. |
| 72617 | */ |
| 72618 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 72619 | ** |
| 72620 | ** This opcode works just like Prev except that if cursor P1 is not |
| 72621 | ** open it behaves a no-op. |
| 72622 | */ |
| 72623 | case OP_SorterNext: { /* jump */ |
| 72624 | VdbeCursor *pC; |
| 72625 | int res; |
| @@ -72180,10 +72646,20 @@ | |
| 72646 | testcase( res==1 ); |
| 72647 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72648 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 72649 | assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 72650 | assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 72651 | |
| 72652 | /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. |
| 72653 | ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ |
| 72654 | assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen |
| 72655 | || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE |
| 72656 | || pC->seekOp==OP_Rewind ); |
| 72657 | assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen |
| 72658 | || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE |
| 72659 | || pC->seekOp==OP_Last ); |
| 72660 | |
| 72661 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 72662 | next_tail: |
| 72663 | pC->cacheStatus = CACHE_STALE; |
| 72664 | VdbeBranchTaken(res==0,2); |
| 72665 | if( res==0 ){ |
| @@ -72462,11 +72938,11 @@ | |
| 72938 | rc = SQLITE_LOCKED; |
| 72939 | p->errorAction = OE_Abort; |
| 72940 | }else{ |
| 72941 | iDb = pOp->p3; |
| 72942 | assert( iCnt==1 ); |
| 72943 | assert( DbMaskTest(p->btreeMask, iDb) ); |
| 72944 | iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 72945 | rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 72946 | pOut->flags = MEM_Int; |
| 72947 | pOut->u.i = iMoved; |
| 72948 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -72502,11 +72978,11 @@ | |
| 72978 | case OP_Clear: { |
| 72979 | int nChange; |
| 72980 | |
| 72981 | nChange = 0; |
| 72982 | assert( p->readOnly==0 ); |
| 72983 | assert( DbMaskTest(p->btreeMask, pOp->p2) ); |
| 72984 | rc = sqlite3BtreeClearTable( |
| 72985 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 72986 | ); |
| 72987 | if( pOp->p3 ){ |
| 72988 | p->nChange += nChange; |
| @@ -72572,11 +73048,11 @@ | |
| 73048 | int flags; |
| 73049 | Db *pDb; |
| 73050 | |
| 73051 | pgno = 0; |
| 73052 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73053 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 73054 | assert( p->readOnly==0 ); |
| 73055 | pDb = &db->aDb[pOp->p1]; |
| 73056 | assert( pDb->pBt!=0 ); |
| 73057 | if( pOp->opcode==OP_CreateTable ){ |
| 73058 | /* flags = BTREE_INTKEY; */ |
| @@ -72660,11 +73136,12 @@ | |
| 73136 | |
| 73137 | /* Opcode: DropTable P1 * * P4 * |
| 73138 | ** |
| 73139 | ** Remove the internal (in-memory) data structures that describe |
| 73140 | ** the table named P4 in database P1. This is called after a table |
| 73141 | ** is dropped from disk (using the Destroy opcode) in order to keep |
| 73142 | ** the internal representation of the |
| 73143 | ** schema consistent with what is on disk. |
| 73144 | */ |
| 73145 | case OP_DropTable: { |
| 73146 | sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); |
| 73147 | break; |
| @@ -72672,11 +73149,12 @@ | |
| 73149 | |
| 73150 | /* Opcode: DropIndex P1 * * P4 * |
| 73151 | ** |
| 73152 | ** Remove the internal (in-memory) data structures that describe |
| 73153 | ** the index named P4 in database P1. This is called after an index |
| 73154 | ** is dropped from disk (using the Destroy opcode) |
| 73155 | ** in order to keep the internal representation of the |
| 73156 | ** schema consistent with what is on disk. |
| 73157 | */ |
| 73158 | case OP_DropIndex: { |
| 73159 | sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); |
| 73160 | break; |
| @@ -72684,11 +73162,12 @@ | |
| 73162 | |
| 73163 | /* Opcode: DropTrigger P1 * * P4 * |
| 73164 | ** |
| 73165 | ** Remove the internal (in-memory) data structures that describe |
| 73166 | ** the trigger named P4 in database P1. This is called after a trigger |
| 73167 | ** is dropped from disk (using the Destroy opcode) in order to keep |
| 73168 | ** the internal representation of the |
| 73169 | ** schema consistent with what is on disk. |
| 73170 | */ |
| 73171 | case OP_DropTrigger: { |
| 73172 | sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); |
| 73173 | break; |
| @@ -72737,11 +73216,11 @@ | |
| 73216 | for(j=0; j<nRoot; j++){ |
| 73217 | aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 73218 | } |
| 73219 | aRoot[j] = 0; |
| 73220 | assert( pOp->p5<db->nDb ); |
| 73221 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); |
| 73222 | z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 73223 | (int)pnErr->u.i, &nErr); |
| 73224 | sqlite3DbFree(db, aRoot); |
| 73225 | pnErr->u.i -= nErr; |
| 73226 | sqlite3VdbeMemSetNull(pIn1); |
| @@ -73397,11 +73876,11 @@ | |
| 73876 | */ |
| 73877 | case OP_IncrVacuum: { /* jump */ |
| 73878 | Btree *pBt; |
| 73879 | |
| 73880 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 73881 | assert( DbMaskTest(p->btreeMask, pOp->p1) ); |
| 73882 | assert( p->readOnly==0 ); |
| 73883 | pBt = db->aDb[pOp->p1].pBt; |
| 73884 | rc = sqlite3BtreeIncrVacuum(pBt); |
| 73885 | VdbeBranchTaken(rc==SQLITE_DONE,2); |
| 73886 | if( rc==SQLITE_DONE ){ |
| @@ -73412,16 +73891,17 @@ | |
| 73891 | } |
| 73892 | #endif |
| 73893 | |
| 73894 | /* Opcode: Expire P1 * * * * |
| 73895 | ** |
| 73896 | ** Cause precompiled statements to expire. When an expired statement |
| 73897 | ** is executed using sqlite3_step() it will either automatically |
| 73898 | ** reprepare itself (if it was originally created using sqlite3_prepare_v2()) |
| 73899 | ** or it will fail with SQLITE_SCHEMA. |
| 73900 | ** |
| 73901 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
| 73902 | ** then only the currently executing statement is expired. |
| 73903 | */ |
| 73904 | case OP_Expire: { |
| 73905 | if( !pOp->p1 ){ |
| 73906 | sqlite3ExpirePreparedStatements(db); |
| 73907 | }else{ |
| @@ -73449,11 +73929,11 @@ | |
| 73929 | case OP_TableLock: { |
| 73930 | u8 isWriteLock = (u8)pOp->p3; |
| 73931 | if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ |
| 73932 | int p1 = pOp->p1; |
| 73933 | assert( p1>=0 && p1<db->nDb ); |
| 73934 | assert( DbMaskTest(p->btreeMask, p1) ); |
| 73935 | assert( isWriteLock==0 || isWriteLock==1 ); |
| 73936 | rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); |
| 73937 | if( (rc&0xFF)==SQLITE_LOCKED ){ |
| 73938 | const char *z = pOp->p4.z; |
| 73939 | sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); |
| @@ -73899,11 +74379,11 @@ | |
| 74379 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 74380 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 74381 | if( zTrace ){ |
| 74382 | int i; |
| 74383 | for(i=0; i<db->nDb; i++){ |
| 74384 | if( DbMaskTest(p->btreeMask, i)==0 ) continue; |
| 74385 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 74386 | } |
| 74387 | } |
| 74388 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 74389 | #ifdef SQLITE_DEBUG |
| @@ -74889,11 +75369,11 @@ | |
| 75369 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 75370 | ** has been allocated and contains an unpacked record that is used as key2. |
| 75371 | */ |
| 75372 | static void vdbeSorterCompare( |
| 75373 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 75374 | int nKeyCol, /* Num of columns. 0 means "all" */ |
| 75375 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 75376 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 75377 | int *pRes /* OUT: Result of comparison */ |
| 75378 | ){ |
| 75379 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| @@ -74903,14 +75383,13 @@ | |
| 75383 | |
| 75384 | if( pKey2 ){ |
| 75385 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 75386 | } |
| 75387 | |
| 75388 | if( nKeyCol ){ |
| 75389 | r2->nField = nKeyCol; |
| 75390 | for(i=0; i<nKeyCol; i++){ |
| 75391 | if( r2->aMem[i].flags & MEM_Null ){ |
| 75392 | *pRes = -1; |
| 75393 | return; |
| 75394 | } |
| 75395 | } |
| @@ -75588,18 +76067,18 @@ | |
| 76067 | ** key. |
| 76068 | */ |
| 76069 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 76070 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 76071 | Mem *pVal, /* Value to compare to current sorter key */ |
| 76072 | int nKeyCol, /* Only compare this many fields */ |
| 76073 | int *pRes /* OUT: Result of comparison */ |
| 76074 | ){ |
| 76075 | VdbeSorter *pSorter = pCsr->pSorter; |
| 76076 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 76077 | |
| 76078 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 76079 | vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes); |
| 76080 | return SQLITE_OK; |
| 76081 | } |
| 76082 | |
| 76083 | /************** End of vdbesort.c ********************************************/ |
| 76084 | /************** Begin file journal.c *****************************************/ |
| @@ -79352,11 +79831,11 @@ | |
| 79831 | } |
| 79832 | } |
| 79833 | } |
| 79834 | |
| 79835 | if( eType==0 ){ |
| 79836 | /* Could not find an existing table or index to use as the RHS b-tree. |
| 79837 | ** We will have to generate an ephemeral table to do the job. |
| 79838 | */ |
| 79839 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79840 | int rMayHaveNull = 0; |
| 79841 | eType = IN_INDEX_EPH; |
| @@ -79482,24 +79961,27 @@ | |
| 79961 | /* Case 1: expr IN (SELECT ...) |
| 79962 | ** |
| 79963 | ** Generate code to write the results of the select into the temporary |
| 79964 | ** table allocated and opened above. |
| 79965 | */ |
| 79966 | Select *pSelect = pExpr->x.pSelect; |
| 79967 | SelectDest dest; |
| 79968 | ExprList *pEList; |
| 79969 | |
| 79970 | assert( !isRowid ); |
| 79971 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 79972 | dest.affSdst = (u8)affinity; |
| 79973 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 79974 | pSelect->iLimit = 0; |
| 79975 | testcase( pSelect->selFlags & SF_Distinct ); |
| 79976 | pSelect->selFlags &= ~SF_Distinct; |
| 79977 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 79978 | if( sqlite3Select(pParse, pSelect, &dest) ){ |
| 79979 | sqlite3KeyInfoUnref(pKeyInfo); |
| 79980 | return 0; |
| 79981 | } |
| 79982 | pEList = pSelect->pEList; |
| 79983 | assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
| 79984 | assert( pEList!=0 ); |
| 79985 | assert( pEList->nExpr>0 ); |
| 79986 | assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); |
| 79987 | pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, |
| @@ -79803,21 +80285,28 @@ | |
| 80285 | }else{ |
| 80286 | int c; |
| 80287 | i64 value; |
| 80288 | const char *z = pExpr->u.zToken; |
| 80289 | assert( z!=0 ); |
| 80290 | c = sqlite3DecOrHexToI64(z, &value); |
| 80291 | if( c==0 || (c==2 && negFlag) ){ |
| 80292 | char *zV; |
| 80293 | if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } |
| 80294 | zV = dup8bytes(v, (char*)&value); |
| 80295 | sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); |
| 80296 | }else{ |
| 80297 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 80298 | sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); |
| 80299 | #else |
| 80300 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 80301 | if( sqlite3_strnicmp(z,"0x",2)==0 ){ |
| 80302 | sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); |
| 80303 | }else |
| 80304 | #endif |
| 80305 | { |
| 80306 | codeReal(v, z, negFlag, iMem); |
| 80307 | } |
| 80308 | #endif |
| 80309 | } |
| 80310 | } |
| 80311 | } |
| 80312 | |
| @@ -83186,19 +83675,24 @@ | |
| 83675 | } |
| 83676 | |
| 83677 | /* |
| 83678 | ** Implementation of the stat_init(N,K,C) SQL function. The three parameters |
| 83679 | ** are: |
| 83680 | ** N: The number of columns in the index including the rowid/pk (note 1) |
| 83681 | ** K: The number of columns in the index excluding the rowid/pk. |
| 83682 | ** C: The number of rows in the index (note 2) |
| 83683 | ** |
| 83684 | ** Note 1: In the special case of the covering index that implements a |
| 83685 | ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the |
| 83686 | ** total number of columns in the table. |
| 83687 | ** |
| 83688 | ** Note 2: C is only used for STAT3 and STAT4. |
| 83689 | ** |
| 83690 | ** For indexes on ordinary rowid tables, N==K+1. But for indexes on |
| 83691 | ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the |
| 83692 | ** PRIMARY KEY of the table. The covering index that implements the |
| 83693 | ** original WITHOUT ROWID table as N==K as a special case. |
| 83694 | ** |
| 83695 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 83696 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 83697 | ** the size of the blob is sizeof(void*) bytes). |
| 83698 | */ |
| @@ -83504,11 +83998,14 @@ | |
| 83998 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 83999 | ** C Index of left-most column to differ from previous row |
| 84000 | ** R Rowid for the current row. Might be a key record for |
| 84001 | ** WITHOUT ROWID tables. |
| 84002 | ** |
| 84003 | ** This SQL function always returns NULL. It's purpose it to accumulate |
| 84004 | ** statistical data and/or samples in the Stat4Accum object about the |
| 84005 | ** index being analyzed. The stat_get() SQL function will later be used to |
| 84006 | ** extract relevant information for constructing the sqlite_statN tables. |
| 84007 | ** |
| 84008 | ** The R parameter is only used for STAT3 and STAT4 |
| 84009 | */ |
| 84010 | static void statPush( |
| 84011 | sqlite3_context *context, |
| @@ -83598,11 +84095,14 @@ | |
| 84095 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 84096 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 84097 | |
| 84098 | /* |
| 84099 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 84100 | ** used to query statistical information that has been gathered into |
| 84101 | ** the Stat4Accum object by prior calls to stat_push(). The P parameter |
| 84102 | ** is a BLOB which is decoded into a pointer to the Stat4Accum objects. |
| 84103 | ** The content to returned is determined by the parameter J |
| 84104 | ** which is one of the STAT_GET_xxxx values defined above. |
| 84105 | ** |
| 84106 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 84107 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 84108 | ** a one-parameter function, stat_get(P), that always returns the |
| @@ -83817,28 +84317,27 @@ | |
| 84317 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 84318 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 84319 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 84320 | |
| 84321 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 84322 | int nCol; /* Number of columns in pIdx. "N" */ |
| 84323 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 84324 | int addrNextRow; /* Address of "next_row:" */ |
| 84325 | const char *zIdxName; /* Name of the index */ |
| 84326 | int nColTest; /* Number of columns to test for changes */ |
| 84327 | |
| 84328 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 84329 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 84330 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 84331 | nCol = pIdx->nKeyCol; |
| 84332 | zIdxName = pTab->zName; |
| 84333 | nColTest = nCol - 1; |
| 84334 | }else{ |
| 84335 | nCol = pIdx->nColumn; |
| 84336 | zIdxName = pIdx->zName; |
| 84337 | nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; |
| 84338 | } |
| 84339 | |
| 84340 | /* Populate the register containing the index name. */ |
| 84341 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| 84342 | VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 84343 | |
| @@ -83863,11 +84362,11 @@ | |
| 84362 | ** regPrev(0) = idx(0) |
| 84363 | ** chng_addr_1: |
| 84364 | ** regPrev(1) = idx(1) |
| 84365 | ** ... |
| 84366 | ** |
| 84367 | ** endDistinctTest: |
| 84368 | ** regRowid = idx(rowid) |
| 84369 | ** stat_push(P, regChng, regRowid) |
| 84370 | ** Next csr |
| 84371 | ** if !eof(csr) goto next_row; |
| 84372 | ** |
| @@ -83876,24 +84375,27 @@ | |
| 84375 | |
| 84376 | /* Make sure there are enough memory cells allocated to accommodate |
| 84377 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 84378 | ** when building a record to insert into the sample column of |
| 84379 | ** the sqlite_stat4 table. */ |
| 84380 | pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); |
| 84381 | |
| 84382 | /* Open a read-only cursor on the index being analyzed. */ |
| 84383 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 84384 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 84385 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 84386 | VdbeComment((v, "%s", pIdx->zName)); |
| 84387 | |
| 84388 | /* Invoke the stat_init() function. The arguments are: |
| 84389 | ** |
| 84390 | ** (1) the number of columns in the index including the rowid |
| 84391 | ** (or for a WITHOUT ROWID table, the number of PK columns), |
| 84392 | ** (2) the number of columns in the key without the rowid/pk |
| 84393 | ** (3) the number of rows in the index, |
| 84394 | ** |
| 84395 | ** |
| 84396 | ** The third argument is only used for STAT3 and STAT4 |
| 84397 | */ |
| 84398 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84399 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
| 84400 | #endif |
| 84401 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
| @@ -83911,56 +84413,73 @@ | |
| 84413 | ** |
| 84414 | */ |
| 84415 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 84416 | VdbeCoverage(v); |
| 84417 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 84418 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84419 | |
| 84420 | if( nColTest>0 ){ |
| 84421 | int endDistinctTest = sqlite3VdbeMakeLabel(v); |
| 84422 | int *aGotoChng; /* Array of jump instruction addresses */ |
| 84423 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); |
| 84424 | if( aGotoChng==0 ) continue; |
| 84425 | |
| 84426 | /* |
| 84427 | ** next_row: |
| 84428 | ** regChng = 0 |
| 84429 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 84430 | ** regChng = 1 |
| 84431 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 84432 | ** ... |
| 84433 | ** regChng = N |
| 84434 | ** goto endDistinctTest |
| 84435 | */ |
| 84436 | sqlite3VdbeAddOp0(v, OP_Goto); |
| 84437 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84438 | if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ |
| 84439 | /* For a single-column UNIQUE index, once we have found a non-NULL |
| 84440 | ** row, we know that all the rest will be distinct, so skip |
| 84441 | ** subsequent distinctness tests. */ |
| 84442 | sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); |
| 84443 | VdbeCoverage(v); |
| 84444 | } |
| 84445 | for(i=0; i<nColTest; i++){ |
| 84446 | char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 84447 | sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 84448 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 84449 | aGotoChng[i] = |
| 84450 | sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 84451 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 84452 | VdbeCoverage(v); |
| 84453 | } |
| 84454 | sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); |
| 84455 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); |
| 84456 | |
| 84457 | |
| 84458 | /* |
| 84459 | ** chng_addr_0: |
| 84460 | ** regPrev(0) = idx(0) |
| 84461 | ** chng_addr_1: |
| 84462 | ** regPrev(1) = idx(1) |
| 84463 | ** ... |
| 84464 | */ |
| 84465 | sqlite3VdbeJumpHere(v, addrNextRow-1); |
| 84466 | for(i=0; i<nColTest; i++){ |
| 84467 | sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 84468 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 84469 | } |
| 84470 | sqlite3VdbeResolveLabel(v, endDistinctTest); |
| 84471 | sqlite3DbFree(db, aGotoChng); |
| 84472 | } |
| 84473 | |
| 84474 | /* |
| 84475 | ** chng_addr_N: |
| 84476 | ** regRowid = idx(rowid) // STAT34 only |
| 84477 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 84478 | ** Next csr |
| 84479 | ** if !eof(csr) goto next_row; |
| 84480 | */ |
| 84481 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84482 | assert( regRowid==(regStat4+2) ); |
| 84483 | if( HasRowid(pTab) ){ |
| 84484 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 84485 | }else{ |
| @@ -84034,11 +84553,10 @@ | |
| 84553 | } |
| 84554 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 84555 | |
| 84556 | /* End of analysis */ |
| 84557 | sqlite3VdbeJumpHere(v, addrRewind); |
| 84558 | } |
| 84559 | |
| 84560 | |
| 84561 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 84562 | ** name and the row count as the content. |
| @@ -84135,10 +84653,11 @@ | |
| 84653 | int i; |
| 84654 | char *z, *zDb; |
| 84655 | Table *pTab; |
| 84656 | Index *pIdx; |
| 84657 | Token *pTableName; |
| 84658 | Vdbe *v; |
| 84659 | |
| 84660 | /* Read the database schema. If an error occurs, leave an error message |
| 84661 | ** and code in pParse and return NULL. */ |
| 84662 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 84663 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| @@ -84182,10 +84701,12 @@ | |
| 84701 | } |
| 84702 | sqlite3DbFree(db, z); |
| 84703 | } |
| 84704 | } |
| 84705 | } |
| 84706 | v = sqlite3GetVdbe(pParse); |
| 84707 | if( v ) sqlite3VdbeAddOp0(v, OP_Expire); |
| 84708 | } |
| 84709 | |
| 84710 | /* |
| 84711 | ** Used to pass information from the analyzer reader through to the |
| 84712 | ** callback routine. |
| @@ -84240,18 +84761,23 @@ | |
| 84761 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84762 | assert( pIndex!=0 ); |
| 84763 | #else |
| 84764 | if( pIndex ) |
| 84765 | #endif |
| 84766 | while( z[0] ){ |
| 84767 | if( sqlite3_strglob("unordered*", z)==0 ){ |
| 84768 | pIndex->bUnordered = 1; |
| 84769 | }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 84770 | pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); |
| 84771 | } |
| 84772 | #ifdef SQLITE_ENABLE_COSTMULT |
| 84773 | else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ |
| 84774 | pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); |
| 84775 | } |
| 84776 | #endif |
| 84777 | while( z[0]!=0 && z[0]!=' ' ) z++; |
| 84778 | while( z[0]==' ' ) z++; |
| 84779 | } |
| 84780 | } |
| 84781 | |
| 84782 | /* |
| 84783 | ** This callback is invoked once for each index when reading the |
| @@ -84288,15 +84814,19 @@ | |
| 84814 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84815 | } |
| 84816 | z = argv[2]; |
| 84817 | |
| 84818 | if( pIndex ){ |
| 84819 | pIndex->bUnordered = 0; |
| 84820 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84821 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84822 | }else{ |
| 84823 | Index fakeIdx; |
| 84824 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84825 | #ifdef SQLITE_ENABLE_COSTMULT |
| 84826 | fakeIdx.pTable = pTable; |
| 84827 | #endif |
| 84828 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84829 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84830 | } |
| 84831 | |
| 84832 | return 0; |
| @@ -85568,10 +86098,23 @@ | |
| 86098 | } |
| 86099 | #else |
| 86100 | #define codeTableLocks(x) |
| 86101 | #endif |
| 86102 | |
| 86103 | /* |
| 86104 | ** Return TRUE if the given yDbMask object is empty - if it contains no |
| 86105 | ** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() |
| 86106 | ** macros when SQLITE_MAX_ATTACHED is greater than 30. |
| 86107 | */ |
| 86108 | #if SQLITE_MAX_ATTACHED>30 |
| 86109 | SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ |
| 86110 | int i; |
| 86111 | for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0; |
| 86112 | return 1; |
| 86113 | } |
| 86114 | #endif |
| 86115 | |
| 86116 | /* |
| 86117 | ** This routine is called after a single SQL statement has been |
| 86118 | ** parsed and a VDBE program to execute that statement has been |
| 86119 | ** prepared. This routine puts the finishing touches on the |
| 86120 | ** VDBE program and resets the pParse structure for the next |
| @@ -85604,22 +86147,23 @@ | |
| 86147 | ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are |
| 86148 | ** set for each database that is used. Generate code to start a |
| 86149 | ** transaction on each used database and to verify the schema cookie |
| 86150 | ** on each used database. |
| 86151 | */ |
| 86152 | if( db->mallocFailed==0 |
| 86153 | && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) |
| 86154 | ){ |
| 86155 | int iDb, i; |
| 86156 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 86157 | sqlite3VdbeJumpHere(v, 0); |
| 86158 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 86159 | if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; |
| 86160 | sqlite3VdbeUsesBtree(v, iDb); |
| 86161 | sqlite3VdbeAddOp4Int(v, |
| 86162 | OP_Transaction, /* Opcode */ |
| 86163 | iDb, /* P1 */ |
| 86164 | DbMaskTest(pParse->writeMask,iDb), /* P2 */ |
| 86165 | pParse->cookieValue[iDb], /* P3 */ |
| 86166 | db->aDb[iDb].pSchema->iGeneration /* P4 */ |
| 86167 | ); |
| 86168 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 86169 | } |
| @@ -85671,11 +86215,11 @@ | |
| 86215 | } |
| 86216 | pParse->nTab = 0; |
| 86217 | pParse->nMem = 0; |
| 86218 | pParse->nSet = 0; |
| 86219 | pParse->nVar = 0; |
| 86220 | DbMaskZero(pParse->cookieMask); |
| 86221 | } |
| 86222 | |
| 86223 | /* |
| 86224 | ** Run the parser and code generator recursively in order to generate |
| 86225 | ** code for the SQL statement given onto the end of the pParse context |
| @@ -88153,11 +88697,11 @@ | |
| 88697 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88698 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88699 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88700 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88701 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88702 | pIndex->nKeyCol); VdbeCoverage(v); |
| 88703 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 88704 | }else{ |
| 88705 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88706 | } |
| 88707 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| @@ -89298,19 +89842,17 @@ | |
| 89842 | ** later, by sqlite3FinishCoding(). |
| 89843 | */ |
| 89844 | SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ |
| 89845 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89846 | sqlite3 *db = pToplevel->db; |
| 89847 | |
| 89848 | assert( iDb>=0 && iDb<db->nDb ); |
| 89849 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 89850 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 89851 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 89852 | if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ |
| 89853 | DbMaskSet(pToplevel->cookieMask, iDb); |
| 89854 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 89855 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 89856 | sqlite3OpenTempDatabase(pToplevel); |
| 89857 | } |
| 89858 | } |
| @@ -89345,11 +89887,11 @@ | |
| 89887 | ** necessary to undo a write and the checkpoint should not be set. |
| 89888 | */ |
| 89889 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 89890 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 89891 | sqlite3CodeVerifySchema(pParse, iDb); |
| 89892 | DbMaskSet(pToplevel->writeMask, iDb); |
| 89893 | pToplevel->isMultiWrite |= setStatement; |
| 89894 | } |
| 89895 | |
| 89896 | /* |
| 89897 | ** Indicate that the statement currently under construction might write |
| @@ -98033,11 +98575,11 @@ | |
| 98575 | ** Note that the values returned are one less that the values that |
| 98576 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
| 98577 | ** to support legacy SQL code. The safety level used to be boolean |
| 98578 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. |
| 98579 | */ |
| 98580 | static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ |
| 98581 | /* 123456789 123456789 */ |
| 98582 | static const char zText[] = "onoffalseyestruefull"; |
| 98583 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; |
| 98584 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; |
| 98585 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; |
| @@ -98055,11 +98597,11 @@ | |
| 98597 | } |
| 98598 | |
| 98599 | /* |
| 98600 | ** Interpret the given string as a boolean value. |
| 98601 | */ |
| 98602 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){ |
| 98603 | return getSafetyLevel(z,1,dflt)!=0; |
| 98604 | } |
| 98605 | |
| 98606 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 98607 | ** remainder of this file is specific to PRAGMA processing. So omit |
| @@ -98601,11 +99143,11 @@ | |
| 99143 | */ |
| 99144 | case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 99145 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 99146 | i64 iLimit = -2; |
| 99147 | if( zRight ){ |
| 99148 | sqlite3DecOrHexToI64(zRight, &iLimit); |
| 99149 | if( iLimit<-1 ) iLimit = -1; |
| 99150 | } |
| 99151 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 99152 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 99153 | break; |
| @@ -98729,11 +99271,11 @@ | |
| 99271 | sqlite3_int64 sz; |
| 99272 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 99273 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 99274 | if( zRight ){ |
| 99275 | int ii; |
| 99276 | sqlite3DecOrHexToI64(zRight, &sz); |
| 99277 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 99278 | if( pId2->n==0 ) db->szMmap = sz; |
| 99279 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 99280 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 99281 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -99772,11 +100314,11 @@ | |
| 100314 | ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 100315 | ** use -1. |
| 100316 | */ |
| 100317 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 100318 | sqlite3_int64 N; |
| 100319 | if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ |
| 100320 | sqlite3_soft_heap_limit64(N); |
| 100321 | } |
| 100322 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 100323 | break; |
| 100324 | } |
| @@ -112245,11 +112787,12 @@ | |
| 112787 | int nEq = pLoop->u.btree.nEq; |
| 112788 | sqlite3 *db = pParse->db; |
| 112789 | int nLower = -1; |
| 112790 | int nUpper = p->nSample+1; |
| 112791 | int rc = SQLITE_OK; |
| 112792 | int iCol = p->aiColumn[nEq]; |
| 112793 | u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; |
| 112794 | CollSeq *pColl; |
| 112795 | |
| 112796 | sqlite3_value *p1 = 0; /* Value extracted from pLower */ |
| 112797 | sqlite3_value *p2 = 0; /* Value extracted from pUpper */ |
| 112798 | sqlite3_value *pVal = 0; /* Value extracted from record */ |
| @@ -113620,10 +114163,11 @@ | |
| 114163 | int regRowid = 0; /* Register holding rowid */ |
| 114164 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 114165 | int iRetInit; /* Address of regReturn init */ |
| 114166 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 114167 | int ii; /* Loop counter */ |
| 114168 | u16 wctrlFlags; /* Flags for sub-WHERE clause */ |
| 114169 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 114170 | Table *pTab = pTabItem->pTab; |
| 114171 | |
| 114172 | pTerm = pLoop->aLTerm[0]; |
| 114173 | assert( pTerm!=0 ); |
| @@ -113715,10 +114259,12 @@ | |
| 114259 | |
| 114260 | /* Run a separate WHERE clause for each term of the OR clause. After |
| 114261 | ** eliminating duplicates from other WHERE clauses, the action for each |
| 114262 | ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 114263 | */ |
| 114264 | wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | |
| 114265 | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY; |
| 114266 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 114267 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 114268 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 114269 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 114270 | Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| @@ -113727,12 +114273,11 @@ | |
| 114273 | pAndExpr->pLeft = pOrExpr; |
| 114274 | pOrExpr = pAndExpr; |
| 114275 | } |
| 114276 | /* Loop through table entries that match term pOrTerm. */ |
| 114277 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| 114278 | wctrlFlags, iCovCur); |
| 114279 | assert( pSubWInfo || pParse->nErr || db->mallocFailed ); |
| 114280 | if( pSubWInfo ){ |
| 114281 | WhereLoop *pSubLoop; |
| 114282 | explainOneScan( |
| 114283 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| @@ -113819,10 +114364,11 @@ | |
| 114364 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 114365 | && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 114366 | ){ |
| 114367 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 114368 | pCov = pSubLoop->u.btree.pIndex; |
| 114369 | wctrlFlags |= WHERE_REOPEN_IDX; |
| 114370 | }else{ |
| 114371 | pCov = 0; |
| 114372 | } |
| 114373 | |
| 114374 | /* Finish the loop through table entries that match term pOrTerm. */ |
| @@ -114425,10 +114971,20 @@ | |
| 114971 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114972 | } |
| 114973 | } |
| 114974 | } |
| 114975 | |
| 114976 | /* |
| 114977 | ** Adjust the cost C by the costMult facter T. This only occurs if |
| 114978 | ** compiled with -DSQLITE_ENABLE_COSTMULT |
| 114979 | */ |
| 114980 | #ifdef SQLITE_ENABLE_COSTMULT |
| 114981 | # define ApplyCostMultiplier(C,T) C += T |
| 114982 | #else |
| 114983 | # define ApplyCostMultiplier(C,T) |
| 114984 | #endif |
| 114985 | |
| 114986 | /* |
| 114987 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114988 | ** index pIndex. Try to match one more. |
| 114989 | ** |
| 114990 | ** When this function is called, pBuilder->pNew->nOut contains the |
| @@ -114621,11 +115177,10 @@ | |
| 115177 | testcase( eOp & WO_ISNULL ); |
| 115178 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 115179 | }else{ |
| 115180 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 115181 | } |
| 115182 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 115183 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 115184 | if( nOut ){ |
| 115185 | pNew->nOut = sqlite3LogEst(nOut); |
| 115186 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| @@ -114653,10 +115208,11 @@ | |
| 115208 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 115209 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 115210 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 115211 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 115212 | } |
| 115213 | ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); |
| 115214 | |
| 115215 | nOutUnadjusted = pNew->nOut; |
| 115216 | pNew->rRun += nInMul + nIn; |
| 115217 | pNew->nOut += nInMul + nIn; |
| 115218 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| @@ -114772,10 +115328,18 @@ | |
| 115328 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 115329 | ** |
| 115330 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 115331 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 115332 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 115333 | ** |
| 115334 | ** The estimated values (nRow, nVisit, nSeek) often contain a large amount |
| 115335 | ** of uncertainty. For this reason, scoring is designed to pick plans that |
| 115336 | ** "do the least harm" if the estimates are inaccurate. For example, a |
| 115337 | ** log(nRow) factor is omitted from a non-covering index scan in order to |
| 115338 | ** bias the scoring in favor of using an index, since the worst-case |
| 115339 | ** performance of using an index is far better than the worst-case performance |
| 115340 | ** of a full table scan. |
| 115341 | */ |
| 115342 | static int whereLoopAddBtree( |
| 115343 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 115344 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 115345 | ){ |
| @@ -114859,10 +115423,11 @@ | |
| 115423 | pNew->aLTerm[0] = pTerm; |
| 115424 | /* TUNING: One-time cost for computing the automatic index is |
| 115425 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 115426 | ** the table being indexed. */ |
| 115427 | pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 115428 | ApplyCostMultiplier(pNew->rSetup, pTab->costMult); |
| 115429 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 115430 | ** is more than the usual guess of 10 rows, since we have no way |
| 115431 | ** of knowning how selective the index will ultimately be. It would |
| 115432 | ** not be unreasonable to make this value much larger. */ |
| 115433 | pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| @@ -114900,10 +115465,11 @@ | |
| 115465 | |
| 115466 | /* Full table scan */ |
| 115467 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 115468 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 115469 | pNew->rRun = rSize + 16; |
| 115470 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 115471 | whereLoopOutputAdjust(pWC, pNew); |
| 115472 | rc = whereLoopInsert(pBuilder, pNew); |
| 115473 | pNew->nOut = rSize; |
| 115474 | if( rc ) break; |
| 115475 | }else{ |
| @@ -114935,11 +115501,11 @@ | |
| 115501 | ** also add the cost of visiting table rows (N*3.0). */ |
| 115502 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 115503 | if( m!=0 ){ |
| 115504 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 115505 | } |
| 115506 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 115507 | whereLoopOutputAdjust(pWC, pNew); |
| 115508 | rc = whereLoopInsert(pBuilder, pNew); |
| 115509 | pNew->nOut = rSize; |
| 115510 | if( rc ) break; |
| 115511 | } |
| @@ -116410,10 +116976,11 @@ | |
| 116976 | } |
| 116977 | op = OP_OpenWrite; |
| 116978 | pWInfo->aiCurOnePass[1] = iIndexCur; |
| 116979 | }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ |
| 116980 | iIndexCur = iIdxCur; |
| 116981 | if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; |
| 116982 | }else{ |
| 116983 | iIndexCur = pParse->nTab++; |
| 116984 | } |
| 116985 | pLevel->iIdxCur = iIndexCur; |
| 116986 | assert( pIx->pSchema==pTab->pSchema ); |
| @@ -120734,10 +121301,16 @@ | |
| 121301 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 121302 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 121303 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 121304 | testcase( z[0]=='9' ); |
| 121305 | *tokenType = TK_INTEGER; |
| 121306 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 121307 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ |
| 121308 | for(i=3; sqlite3Isxdigit(z[i]); i++){} |
| 121309 | return i; |
| 121310 | } |
| 121311 | #endif |
| 121312 | for(i=0; sqlite3Isdigit(z[i]); i++){} |
| 121313 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 121314 | if( z[i]=='.' ){ |
| 121315 | i++; |
| 121316 | while( sqlite3Isdigit(z[i]) ){ i++; } |
| @@ -122410,11 +122983,11 @@ | |
| 122983 | |
| 122984 | /* |
| 122985 | ** Return a static string containing the name corresponding to the error code |
| 122986 | ** specified in the argument. |
| 122987 | */ |
| 122988 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 122989 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 122990 | const char *zName = 0; |
| 122991 | int i, origRc = rc; |
| 122992 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 122993 | switch( rc ){ |
| @@ -123455,12 +124028,12 @@ | |
| 124028 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 124029 | #endif |
| 124030 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 124031 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 124032 | #endif |
| 124033 | #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 |
| 124034 | # error SQLITE_MAX_ATTACHED must be between 0 and 125 |
| 124035 | #endif |
| 124036 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 124037 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 124038 | #endif |
| 124039 | #if SQLITE_MAX_COLUMN>32767 |
| @@ -124715,10 +125288,20 @@ | |
| 125288 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 125289 | #endif |
| 125290 | break; |
| 125291 | } |
| 125292 | |
| 125293 | /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); |
| 125294 | ** |
| 125295 | ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if |
| 125296 | ** not. |
| 125297 | */ |
| 125298 | case SQLITE_TESTCTRL_ISINIT: { |
| 125299 | if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; |
| 125300 | break; |
| 125301 | } |
| 125302 | |
| 125303 | } |
| 125304 | va_end(ap); |
| 125305 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 125306 | return rc; |
| 125307 | } |
| @@ -124763,11 +125346,11 @@ | |
| 125346 | const char *zParam, /* URI parameter sought */ |
| 125347 | sqlite3_int64 bDflt /* return if parameter is missing */ |
| 125348 | ){ |
| 125349 | const char *z = sqlite3_uri_parameter(zFilename, zParam); |
| 125350 | sqlite3_int64 v; |
| 125351 | if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ |
| 125352 | bDflt = v; |
| 125353 | } |
| 125354 | return bDflt; |
| 125355 | } |
| 125356 | |
| @@ -126294,11 +126877,11 @@ | |
| 126877 | |
| 126878 | /* fts3_tokenize_vtab.c */ |
| 126879 | SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); |
| 126880 | |
| 126881 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 126882 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 126883 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 126884 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 126885 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 126886 | #endif |
| 126887 | |
| @@ -129764,11 +130347,11 @@ | |
| 130347 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 130348 | ** And so on. |
| 130349 | */ |
| 130350 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130351 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130352 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130353 | SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 130354 | #endif |
| 130355 | #ifdef SQLITE_ENABLE_ICU |
| 130356 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 130357 | #endif |
| @@ -129782,20 +130365,20 @@ | |
| 130365 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 130366 | int rc = SQLITE_OK; |
| 130367 | Fts3Hash *pHash = 0; |
| 130368 | const sqlite3_tokenizer_module *pSimple = 0; |
| 130369 | const sqlite3_tokenizer_module *pPorter = 0; |
| 130370 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130371 | const sqlite3_tokenizer_module *pUnicode = 0; |
| 130372 | #endif |
| 130373 | |
| 130374 | #ifdef SQLITE_ENABLE_ICU |
| 130375 | const sqlite3_tokenizer_module *pIcu = 0; |
| 130376 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 130377 | #endif |
| 130378 | |
| 130379 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130380 | sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 130381 | #endif |
| 130382 | |
| 130383 | #ifdef SQLITE_TEST |
| 130384 | rc = sqlite3Fts3InitTerm(db); |
| @@ -129819,11 +130402,11 @@ | |
| 130402 | /* Load the built-in tokenizers into the hash table */ |
| 130403 | if( rc==SQLITE_OK ){ |
| 130404 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 130405 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 130406 | |
| 130407 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 130408 | || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 130409 | #endif |
| 130410 | #ifdef SQLITE_ENABLE_ICU |
| 130411 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 130412 | #endif |
| @@ -143079,11 +143662,11 @@ | |
| 143662 | ****************************************************************************** |
| 143663 | ** |
| 143664 | ** Implementation of the "unicode" full-text-search tokenizer. |
| 143665 | */ |
| 143666 | |
| 143667 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 143668 | |
| 143669 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 143670 | |
| 143671 | /* #include <assert.h> */ |
| 143672 | /* #include <stdlib.h> */ |
| @@ -143295,11 +143878,11 @@ | |
| 143878 | memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 143879 | pNew->bRemoveDiacritic = 1; |
| 143880 | |
| 143881 | for(i=0; rc==SQLITE_OK && i<nArg; i++){ |
| 143882 | const char *z = azArg[i]; |
| 143883 | int n = (int)strlen(z); |
| 143884 | |
| 143885 | if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 143886 | pNew->bRemoveDiacritic = 1; |
| 143887 | } |
| 143888 | else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| @@ -143427,15 +144010,15 @@ | |
| 144010 | }while( unicodeIsAlnum(p, iCode) |
| 144011 | || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 144012 | ); |
| 144013 | |
| 144014 | /* Set the output variables and return. */ |
| 144015 | pCsr->iOff = (int)(z - pCsr->aInput); |
| 144016 | *paToken = pCsr->zToken; |
| 144017 | *pnToken = (int)(zOut - pCsr->zToken); |
| 144018 | *piStart = (int)(zStart - pCsr->aInput); |
| 144019 | *piEnd = (int)(zEnd - pCsr->aInput); |
| 144020 | *piPos = pCsr->iToken++; |
| 144021 | return SQLITE_OK; |
| 144022 | } |
| 144023 | |
| 144024 | /* |
| @@ -143454,11 +144037,11 @@ | |
| 144037 | }; |
| 144038 | *ppModule = &module; |
| 144039 | } |
| 144040 | |
| 144041 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 144042 | #endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ |
| 144043 | |
| 144044 | /************** End of fts3_unicode.c ****************************************/ |
| 144045 | /************** Begin file fts3_unicode2.c ***********************************/ |
| 144046 | /* |
| 144047 | ** 2012 May 25 |
| @@ -143475,11 +144058,11 @@ | |
| 144058 | |
| 144059 | /* |
| 144060 | ** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 144061 | */ |
| 144062 | |
| 144063 | #ifndef SQLITE_DISABLE_FTS3_UNICODE |
| 144064 | #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 144065 | |
| 144066 | /* #include <assert.h> */ |
| 144067 | |
| 144068 | /* |
| @@ -143822,11 +144405,11 @@ | |
| 144405 | } |
| 144406 | |
| 144407 | return ret; |
| 144408 | } |
| 144409 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 144410 | #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ |
| 144411 | |
| 144412 | /************** End of fts3_unicode2.c ***************************************/ |
| 144413 | /************** Begin file rtree.c *******************************************/ |
| 144414 | /* |
| 144415 | ** 2001 September 15 |
| @@ -145359,13 +145942,17 @@ | |
| 145942 | int rc = SQLITE_OK; |
| 145943 | int iCell = 0; |
| 145944 | |
| 145945 | rtreeReference(pRtree); |
| 145946 | |
| 145947 | /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ |
| 145948 | freeCursorConstraints(pCsr); |
| 145949 | sqlite3_free(pCsr->aPoint); |
| 145950 | memset(pCsr, 0, sizeof(RtreeCursor)); |
| 145951 | pCsr->base.pVtab = (sqlite3_vtab*)pRtree; |
| 145952 | |
| 145953 | pCsr->iStrategy = idxNum; |
| 145954 | if( idxNum==1 ){ |
| 145955 | /* Special case - lookup by rowid. */ |
| 145956 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 145957 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 145958 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 145959 |
+54
-16
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | -#define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -2035,31 +2035,37 @@ | ||
| 2035 | 2035 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2036 | 2036 | |
| 2037 | 2037 | /* |
| 2038 | 2038 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2039 | 2039 | ** |
| 2040 | -** ^This routine sets a callback function that might be invoked whenever | |
| 2041 | -** an attempt is made to open a database table that another thread | |
| 2042 | -** or process has locked. | |
| 2040 | +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X | |
| 2041 | +** that might be invoked with argument P whenever | |
| 2042 | +** an attempt is made to access a database table associated with | |
| 2043 | +** [database connection] D when another thread | |
| 2044 | +** or process has the table locked. | |
| 2045 | +** The sqlite3_busy_handler() interface is used to implement | |
| 2046 | +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. | |
| 2043 | 2047 | ** |
| 2044 | 2048 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2045 | 2049 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2046 | 2050 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2047 | 2051 | ** |
| 2048 | 2052 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2049 | 2053 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2050 | 2054 | ** the busy handler callback is the number of times that the busy handler has |
| 2051 | -** been invoked for this locking event. ^If the | |
| 2055 | +** been invoked for the same locking event. ^If the | |
| 2052 | 2056 | ** busy callback returns 0, then no additional attempts are made to |
| 2053 | -** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. | |
| 2057 | +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned | |
| 2058 | +** to the application. | |
| 2054 | 2059 | ** ^If the callback returns non-zero, then another attempt |
| 2055 | -** is made to open the database for reading and the cycle repeats. | |
| 2060 | +** is made to access the database and the cycle repeats. | |
| 2056 | 2061 | ** |
| 2057 | 2062 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2058 | 2063 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2059 | 2064 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2060 | -** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. | |
| 2065 | +** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the | |
| 2066 | +** busy handler. | |
| 2061 | 2067 | ** Consider a scenario where one process is holding a read lock that |
| 2062 | 2068 | ** it is trying to promote to a reserved lock and |
| 2063 | 2069 | ** a second process is holding a reserved lock that it is trying |
| 2064 | 2070 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2065 | 2071 | ** because it is blocked by the second and the second process cannot |
| @@ -2087,14 +2093,16 @@ | ||
| 2087 | 2093 | ** this is important. |
| 2088 | 2094 | ** |
| 2089 | 2095 | ** ^(There can only be a single busy handler defined for each |
| 2090 | 2096 | ** [database connection]. Setting a new busy handler clears any |
| 2091 | 2097 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2092 | -** will also set or clear the busy handler. | |
| 2098 | +** or evaluating [PRAGMA busy_timeout=N] will change the | |
| 2099 | +** busy handler and thus clear any previously set busy handler. | |
| 2093 | 2100 | ** |
| 2094 | 2101 | ** The busy callback should not take any actions which modify the |
| 2095 | -** database connection that invoked the busy handler. Any such actions | |
| 2102 | +** database connection that invoked the busy handler. In other words, | |
| 2103 | +** the busy handler is not reentrant. Any such actions | |
| 2096 | 2104 | ** result in undefined behavior. |
| 2097 | 2105 | ** |
| 2098 | 2106 | ** A busy handler must not close the database connection |
| 2099 | 2107 | ** or [prepared statement] that invoked the busy handler. |
| 2100 | 2108 | */ |
| @@ -2115,10 +2123,12 @@ | ||
| 2115 | 2123 | ** |
| 2116 | 2124 | ** ^(There can only be a single busy handler for a particular |
| 2117 | 2125 | ** [database connection] any any given moment. If another busy handler |
| 2118 | 2126 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2119 | 2127 | ** this routine, that other busy handler is cleared.)^ |
| 2128 | +** | |
| 2129 | +** See also: [PRAGMA busy_timeout] | |
| 2120 | 2130 | */ |
| 2121 | 2131 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2122 | 2132 | |
| 2123 | 2133 | /* |
| 2124 | 2134 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4703,10 +4713,17 @@ | ||
| 4703 | 4713 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4704 | 4714 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4705 | 4715 | ** will be placed in that directory.)^ ^If this variable |
| 4706 | 4716 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4707 | 4717 | ** temporary file directory. |
| 4718 | +** | |
| 4719 | +** Applications are strongly discouraged from using this global variable. | |
| 4720 | +** It is required to set a temporary folder on Windows Runtime (WinRT). | |
| 4721 | +** But for all other platforms, it is highly recommended that applications | |
| 4722 | +** neither read nor write this variable. This global variable is a relic | |
| 4723 | +** that exists for backwards compatibility of legacy applications and should | |
| 4724 | +** be avoided in new projects. | |
| 4708 | 4725 | ** |
| 4709 | 4726 | ** It is not safe to read or modify this variable in more than one |
| 4710 | 4727 | ** thread at a time. It is not safe to read or modify this variable |
| 4711 | 4728 | ** if a [database connection] is being used at the same time in a separate |
| 4712 | 4729 | ** thread. |
| @@ -4722,10 +4739,15 @@ | ||
| 4722 | 4739 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4723 | 4740 | ** using [sqlite3_free]. |
| 4724 | 4741 | ** Hence, if this variable is modified directly, either it should be |
| 4725 | 4742 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4726 | 4743 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4744 | +** Except when requested by the [temp_store_directory pragma], SQLite | |
| 4745 | +** does not free the memory that sqlite3_temp_directory points to. If | |
| 4746 | +** the application wants that memory to be freed, it must do | |
| 4747 | +** so itself, taking care to only do so after all [database connection] | |
| 4748 | +** objects have been destroyed. | |
| 4727 | 4749 | ** |
| 4728 | 4750 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4729 | 4751 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4730 | 4752 | ** features that require the use of temporary files may fail. Here is an |
| 4731 | 4753 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5856,14 +5878,16 @@ | ||
| 5856 | 5878 | ** <ul> |
| 5857 | 5879 | ** <li> SQLITE_MUTEX_FAST |
| 5858 | 5880 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5859 | 5881 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5860 | 5882 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5861 | -** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 5883 | +** <li> SQLITE_MUTEX_STATIC_OPEN | |
| 5862 | 5884 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5863 | 5885 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5864 | -** <li> SQLITE_MUTEX_STATIC_LRU2 | |
| 5886 | +** <li> SQLITE_MUTEX_STATIC_PMEM | |
| 5887 | +** <li> SQLITE_MUTEX_STATIC_APP1 | |
| 5888 | +** <li> SQLITE_MUTEX_STATIC_APP2 | |
| 5865 | 5889 | ** </ul>)^ |
| 5866 | 5890 | ** |
| 5867 | 5891 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5868 | 5892 | ** cause sqlite3_mutex_alloc() to create |
| 5869 | 5893 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6063,10 +6087,13 @@ | ||
| 6063 | 6087 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6064 | 6088 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6065 | 6089 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6066 | 6090 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6067 | 6091 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6092 | +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ | |
| 6093 | +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ | |
| 6094 | +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ | |
| 6068 | 6095 | |
| 6069 | 6096 | /* |
| 6070 | 6097 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6071 | 6098 | ** |
| 6072 | 6099 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6158,11 +6185,12 @@ | ||
| 6158 | 6185 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6159 | 6186 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6160 | 6187 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6161 | 6188 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6162 | 6189 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6163 | -#define SQLITE_TESTCTRL_LAST 22 | |
| 6190 | +#define SQLITE_TESTCTRL_ISINIT 23 | |
| 6191 | +#define SQLITE_TESTCTRL_LAST 23 | |
| 6164 | 6192 | |
| 6165 | 6193 | /* |
| 6166 | 6194 | ** CAPI3REF: SQLite Runtime Status |
| 6167 | 6195 | ** |
| 6168 | 6196 | ** ^This interface is used to retrieve runtime status information |
| @@ -7141,10 +7169,13 @@ | ||
| 7141 | 7169 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7142 | 7170 | ** configured by this function. |
| 7143 | 7171 | ** |
| 7144 | 7172 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7145 | 7173 | ** from SQL. |
| 7174 | +** | |
| 7175 | +** ^Checkpoints initiated by this mechanism are | |
| 7176 | +** [sqlite3_wal_checkpoint_v2|PASSIVE]. | |
| 7146 | 7177 | ** |
| 7147 | 7178 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7148 | 7179 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7149 | 7180 | ** pages. The use of this interface |
| 7150 | 7181 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7158,10 +7189,14 @@ | ||
| 7158 | 7189 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7159 | 7190 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7160 | 7191 | ** empty string, then a checkpoint is run on all databases of |
| 7161 | 7192 | ** connection D. ^If the database connection D is not in |
| 7162 | 7193 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7194 | +** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a | |
| 7195 | +** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. | |
| 7196 | +** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL | |
| 7197 | +** or RESET checkpoint. | |
| 7163 | 7198 | ** |
| 7164 | 7199 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7165 | 7200 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7166 | 7201 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7167 | 7202 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7180,22 +7215,25 @@ | ||
| 7180 | 7215 | ** <dl> |
| 7181 | 7216 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7182 | 7217 | ** Checkpoint as many frames as possible without waiting for any database |
| 7183 | 7218 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7184 | 7219 | ** are checkpointed. This mode is the same as calling |
| 7185 | -** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. | |
| 7220 | +** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] | |
| 7221 | +** is never invoked. | |
| 7186 | 7222 | ** |
| 7187 | 7223 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7188 | -** This mode blocks (calls the busy-handler callback) until there is no | |
| 7224 | +** This mode blocks (it invokes the | |
| 7225 | +** [sqlite3_busy_handler|busy-handler callback]) until there is no | |
| 7189 | 7226 | ** database writer and all readers are reading from the most recent database |
| 7190 | 7227 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7191 | 7228 | ** database file. This call blocks database writers while it is running, |
| 7192 | 7229 | ** but not database readers. |
| 7193 | 7230 | ** |
| 7194 | 7231 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7195 | 7232 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7196 | -** checkpointing the log file it blocks (calls the busy-handler callback) | |
| 7233 | +** checkpointing the log file it blocks (calls the | |
| 7234 | +** [sqlite3_busy_handler|busy-handler callback]) | |
| 7197 | 7235 | ** until all readers are reading from the database file only. This ensures |
| 7198 | 7236 | ** that the next client to write to the database file restarts the log file |
| 7199 | 7237 | ** from the beginning. This call blocks database writers while it is running, |
| 7200 | 7238 | ** but not database readers. |
| 7201 | 7239 | ** </dl> |
| 7202 | 7240 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | #define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -2035,31 +2035,37 @@ | |
| 2035 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2036 | |
| 2037 | /* |
| 2038 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2039 | ** |
| 2040 | ** ^This routine sets a callback function that might be invoked whenever |
| 2041 | ** an attempt is made to open a database table that another thread |
| 2042 | ** or process has locked. |
| 2043 | ** |
| 2044 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2045 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2046 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2047 | ** |
| 2048 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2049 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2050 | ** the busy handler callback is the number of times that the busy handler has |
| 2051 | ** been invoked for this locking event. ^If the |
| 2052 | ** busy callback returns 0, then no additional attempts are made to |
| 2053 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. |
| 2054 | ** ^If the callback returns non-zero, then another attempt |
| 2055 | ** is made to open the database for reading and the cycle repeats. |
| 2056 | ** |
| 2057 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2058 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2059 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2060 | ** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. |
| 2061 | ** Consider a scenario where one process is holding a read lock that |
| 2062 | ** it is trying to promote to a reserved lock and |
| 2063 | ** a second process is holding a reserved lock that it is trying |
| 2064 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2065 | ** because it is blocked by the second and the second process cannot |
| @@ -2087,14 +2093,16 @@ | |
| 2087 | ** this is important. |
| 2088 | ** |
| 2089 | ** ^(There can only be a single busy handler defined for each |
| 2090 | ** [database connection]. Setting a new busy handler clears any |
| 2091 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2092 | ** will also set or clear the busy handler. |
| 2093 | ** |
| 2094 | ** The busy callback should not take any actions which modify the |
| 2095 | ** database connection that invoked the busy handler. Any such actions |
| 2096 | ** result in undefined behavior. |
| 2097 | ** |
| 2098 | ** A busy handler must not close the database connection |
| 2099 | ** or [prepared statement] that invoked the busy handler. |
| 2100 | */ |
| @@ -2115,10 +2123,12 @@ | |
| 2115 | ** |
| 2116 | ** ^(There can only be a single busy handler for a particular |
| 2117 | ** [database connection] any any given moment. If another busy handler |
| 2118 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2119 | ** this routine, that other busy handler is cleared.)^ |
| 2120 | */ |
| 2121 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2122 | |
| 2123 | /* |
| 2124 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4703,10 +4713,17 @@ | |
| 4703 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4704 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4705 | ** will be placed in that directory.)^ ^If this variable |
| 4706 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4707 | ** temporary file directory. |
| 4708 | ** |
| 4709 | ** It is not safe to read or modify this variable in more than one |
| 4710 | ** thread at a time. It is not safe to read or modify this variable |
| 4711 | ** if a [database connection] is being used at the same time in a separate |
| 4712 | ** thread. |
| @@ -4722,10 +4739,15 @@ | |
| 4722 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4723 | ** using [sqlite3_free]. |
| 4724 | ** Hence, if this variable is modified directly, either it should be |
| 4725 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4726 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4727 | ** |
| 4728 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4729 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4730 | ** features that require the use of temporary files may fail. Here is an |
| 4731 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5856,14 +5878,16 @@ | |
| 5856 | ** <ul> |
| 5857 | ** <li> SQLITE_MUTEX_FAST |
| 5858 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5859 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5860 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5861 | ** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 5862 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5863 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5864 | ** <li> SQLITE_MUTEX_STATIC_LRU2 |
| 5865 | ** </ul>)^ |
| 5866 | ** |
| 5867 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5868 | ** cause sqlite3_mutex_alloc() to create |
| 5869 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6063,10 +6087,13 @@ | |
| 6063 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6064 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6065 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6066 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6067 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6068 | |
| 6069 | /* |
| 6070 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6071 | ** |
| 6072 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6158,11 +6185,12 @@ | |
| 6158 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6159 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6160 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6161 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6162 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6163 | #define SQLITE_TESTCTRL_LAST 22 |
| 6164 | |
| 6165 | /* |
| 6166 | ** CAPI3REF: SQLite Runtime Status |
| 6167 | ** |
| 6168 | ** ^This interface is used to retrieve runtime status information |
| @@ -7141,10 +7169,13 @@ | |
| 7141 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7142 | ** configured by this function. |
| 7143 | ** |
| 7144 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7145 | ** from SQL. |
| 7146 | ** |
| 7147 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7148 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7149 | ** pages. The use of this interface |
| 7150 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7158,10 +7189,14 @@ | |
| 7158 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7159 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7160 | ** empty string, then a checkpoint is run on all databases of |
| 7161 | ** connection D. ^If the database connection D is not in |
| 7162 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7163 | ** |
| 7164 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7165 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7166 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7167 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7180,22 +7215,25 @@ | |
| 7180 | ** <dl> |
| 7181 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7182 | ** Checkpoint as many frames as possible without waiting for any database |
| 7183 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7184 | ** are checkpointed. This mode is the same as calling |
| 7185 | ** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. |
| 7186 | ** |
| 7187 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7188 | ** This mode blocks (calls the busy-handler callback) until there is no |
| 7189 | ** database writer and all readers are reading from the most recent database |
| 7190 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7191 | ** database file. This call blocks database writers while it is running, |
| 7192 | ** but not database readers. |
| 7193 | ** |
| 7194 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7195 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7196 | ** checkpointing the log file it blocks (calls the busy-handler callback) |
| 7197 | ** until all readers are reading from the database file only. This ensures |
| 7198 | ** that the next client to write to the database file restarts the log file |
| 7199 | ** from the beginning. This call blocks database writers while it is running, |
| 7200 | ** but not database readers. |
| 7201 | ** </dl> |
| 7202 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | #define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -2035,31 +2035,37 @@ | |
| 2035 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2036 | |
| 2037 | /* |
| 2038 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2039 | ** |
| 2040 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2041 | ** that might be invoked with argument P whenever |
| 2042 | ** an attempt is made to access a database table associated with |
| 2043 | ** [database connection] D when another thread |
| 2044 | ** or process has the table locked. |
| 2045 | ** The sqlite3_busy_handler() interface is used to implement |
| 2046 | ** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. |
| 2047 | ** |
| 2048 | ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] |
| 2049 | ** is returned immediately upon encountering the lock. ^If the busy callback |
| 2050 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2051 | ** |
| 2052 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2053 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2054 | ** the busy handler callback is the number of times that the busy handler has |
| 2055 | ** been invoked for the same locking event. ^If the |
| 2056 | ** busy callback returns 0, then no additional attempts are made to |
| 2057 | ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned |
| 2058 | ** to the application. |
| 2059 | ** ^If the callback returns non-zero, then another attempt |
| 2060 | ** is made to access the database and the cycle repeats. |
| 2061 | ** |
| 2062 | ** The presence of a busy handler does not guarantee that it will be invoked |
| 2063 | ** when there is lock contention. ^If SQLite determines that invoking the busy |
| 2064 | ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] |
| 2065 | ** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the |
| 2066 | ** busy handler. |
| 2067 | ** Consider a scenario where one process is holding a read lock that |
| 2068 | ** it is trying to promote to a reserved lock and |
| 2069 | ** a second process is holding a reserved lock that it is trying |
| 2070 | ** to promote to an exclusive lock. The first process cannot proceed |
| 2071 | ** because it is blocked by the second and the second process cannot |
| @@ -2087,14 +2093,16 @@ | |
| 2093 | ** this is important. |
| 2094 | ** |
| 2095 | ** ^(There can only be a single busy handler defined for each |
| 2096 | ** [database connection]. Setting a new busy handler clears any |
| 2097 | ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] |
| 2098 | ** or evaluating [PRAGMA busy_timeout=N] will change the |
| 2099 | ** busy handler and thus clear any previously set busy handler. |
| 2100 | ** |
| 2101 | ** The busy callback should not take any actions which modify the |
| 2102 | ** database connection that invoked the busy handler. In other words, |
| 2103 | ** the busy handler is not reentrant. Any such actions |
| 2104 | ** result in undefined behavior. |
| 2105 | ** |
| 2106 | ** A busy handler must not close the database connection |
| 2107 | ** or [prepared statement] that invoked the busy handler. |
| 2108 | */ |
| @@ -2115,10 +2123,12 @@ | |
| 2123 | ** |
| 2124 | ** ^(There can only be a single busy handler for a particular |
| 2125 | ** [database connection] any any given moment. If another busy handler |
| 2126 | ** was defined (using [sqlite3_busy_handler()]) prior to calling |
| 2127 | ** this routine, that other busy handler is cleared.)^ |
| 2128 | ** |
| 2129 | ** See also: [PRAGMA busy_timeout] |
| 2130 | */ |
| 2131 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); |
| 2132 | |
| 2133 | /* |
| 2134 | ** CAPI3REF: Convenience Routines For Running Queries |
| @@ -4703,10 +4713,17 @@ | |
| 4713 | ** the name of a folder (a.k.a. directory), then all temporary files |
| 4714 | ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| 4715 | ** will be placed in that directory.)^ ^If this variable |
| 4716 | ** is a NULL pointer, then SQLite performs a search for an appropriate |
| 4717 | ** temporary file directory. |
| 4718 | ** |
| 4719 | ** Applications are strongly discouraged from using this global variable. |
| 4720 | ** It is required to set a temporary folder on Windows Runtime (WinRT). |
| 4721 | ** But for all other platforms, it is highly recommended that applications |
| 4722 | ** neither read nor write this variable. This global variable is a relic |
| 4723 | ** that exists for backwards compatibility of legacy applications and should |
| 4724 | ** be avoided in new projects. |
| 4725 | ** |
| 4726 | ** It is not safe to read or modify this variable in more than one |
| 4727 | ** thread at a time. It is not safe to read or modify this variable |
| 4728 | ** if a [database connection] is being used at the same time in a separate |
| 4729 | ** thread. |
| @@ -4722,10 +4739,15 @@ | |
| 4739 | ** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 4740 | ** using [sqlite3_free]. |
| 4741 | ** Hence, if this variable is modified directly, either it should be |
| 4742 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4743 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4744 | ** Except when requested by the [temp_store_directory pragma], SQLite |
| 4745 | ** does not free the memory that sqlite3_temp_directory points to. If |
| 4746 | ** the application wants that memory to be freed, it must do |
| 4747 | ** so itself, taking care to only do so after all [database connection] |
| 4748 | ** objects have been destroyed. |
| 4749 | ** |
| 4750 | ** <b>Note to Windows Runtime users:</b> The temporary directory must be set |
| 4751 | ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various |
| 4752 | ** features that require the use of temporary files may fail. Here is an |
| 4753 | ** example of how to do this using C++ with the Windows Runtime: |
| @@ -5856,14 +5878,16 @@ | |
| 5878 | ** <ul> |
| 5879 | ** <li> SQLITE_MUTEX_FAST |
| 5880 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 5881 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 5882 | ** <li> SQLITE_MUTEX_STATIC_MEM |
| 5883 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
| 5884 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 5885 | ** <li> SQLITE_MUTEX_STATIC_LRU |
| 5886 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
| 5887 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 5888 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 5889 | ** </ul>)^ |
| 5890 | ** |
| 5891 | ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) |
| 5892 | ** cause sqlite3_mutex_alloc() to create |
| 5893 | ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| @@ -6063,10 +6087,13 @@ | |
| 6087 | #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ |
| 6088 | #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ |
| 6089 | #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ |
| 6090 | #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ |
| 6091 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ |
| 6092 | #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ |
| 6093 | #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ |
| 6094 | #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ |
| 6095 | |
| 6096 | /* |
| 6097 | ** CAPI3REF: Retrieve the mutex for a database connection |
| 6098 | ** |
| 6099 | ** ^This interface returns a pointer the [sqlite3_mutex] object that |
| @@ -6158,11 +6185,12 @@ | |
| 6185 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6186 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6187 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6188 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6189 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6190 | #define SQLITE_TESTCTRL_ISINIT 23 |
| 6191 | #define SQLITE_TESTCTRL_LAST 23 |
| 6192 | |
| 6193 | /* |
| 6194 | ** CAPI3REF: SQLite Runtime Status |
| 6195 | ** |
| 6196 | ** ^This interface is used to retrieve runtime status information |
| @@ -7141,10 +7169,13 @@ | |
| 7169 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| 7170 | ** configured by this function. |
| 7171 | ** |
| 7172 | ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface |
| 7173 | ** from SQL. |
| 7174 | ** |
| 7175 | ** ^Checkpoints initiated by this mechanism are |
| 7176 | ** [sqlite3_wal_checkpoint_v2|PASSIVE]. |
| 7177 | ** |
| 7178 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 7179 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 7180 | ** pages. The use of this interface |
| 7181 | ** is only necessary if the default setting is found to be suboptimal |
| @@ -7158,10 +7189,14 @@ | |
| 7189 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7190 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7191 | ** empty string, then a checkpoint is run on all databases of |
| 7192 | ** connection D. ^If the database connection D is not in |
| 7193 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7194 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a |
| 7195 | ** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. |
| 7196 | ** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL |
| 7197 | ** or RESET checkpoint. |
| 7198 | ** |
| 7199 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7200 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7201 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7202 | ** run whenever the WAL reaches a certain size threshold. |
| @@ -7180,22 +7215,25 @@ | |
| 7215 | ** <dl> |
| 7216 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7217 | ** Checkpoint as many frames as possible without waiting for any database |
| 7218 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7219 | ** are checkpointed. This mode is the same as calling |
| 7220 | ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] |
| 7221 | ** is never invoked. |
| 7222 | ** |
| 7223 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7224 | ** This mode blocks (it invokes the |
| 7225 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7226 | ** database writer and all readers are reading from the most recent database |
| 7227 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7228 | ** database file. This call blocks database writers while it is running, |
| 7229 | ** but not database readers. |
| 7230 | ** |
| 7231 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7232 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7233 | ** checkpointing the log file it blocks (calls the |
| 7234 | ** [sqlite3_busy_handler|busy-handler callback]) |
| 7235 | ** until all readers are reading from the database file only. This ensures |
| 7236 | ** that the next client to write to the database file restarts the log file |
| 7237 | ** from the beginning. This call blocks database writers while it is running, |
| 7238 | ** but not database readers. |
| 7239 | ** </dl> |
| 7240 |
+1
-1
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -552,11 +552,11 @@ | ||
| 552 | 552 | db_column_text(&q, 3) |
| 553 | 553 | ); |
| 554 | 554 | zCom = db_column_text(&q, 2); |
| 555 | 555 | if( zCom && zCom[0] ){ |
| 556 | 556 | fossil_print(" "); |
| 557 | - comment_print(zCom, 7, width); | |
| 557 | + comment_print(zCom, 0, 7, width, g.comFmtFlags); | |
| 558 | 558 | } |
| 559 | 559 | if( verboseFlag ){ |
| 560 | 560 | db_bind_int(&q2, "$id", stashid); |
| 561 | 561 | while( db_step(&q2)==SQLITE_ROW ){ |
| 562 | 562 | int isAdded = db_column_int(&q2, 0); |
| 563 | 563 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -552,11 +552,11 @@ | |
| 552 | db_column_text(&q, 3) |
| 553 | ); |
| 554 | zCom = db_column_text(&q, 2); |
| 555 | if( zCom && zCom[0] ){ |
| 556 | fossil_print(" "); |
| 557 | comment_print(zCom, 7, width); |
| 558 | } |
| 559 | if( verboseFlag ){ |
| 560 | db_bind_int(&q2, "$id", stashid); |
| 561 | while( db_step(&q2)==SQLITE_ROW ){ |
| 562 | int isAdded = db_column_int(&q2, 0); |
| 563 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -552,11 +552,11 @@ | |
| 552 | db_column_text(&q, 3) |
| 553 | ); |
| 554 | zCom = db_column_text(&q, 2); |
| 555 | if( zCom && zCom[0] ){ |
| 556 | fossil_print(" "); |
| 557 | comment_print(zCom, 0, 7, width, g.comFmtFlags); |
| 558 | } |
| 559 | if( verboseFlag ){ |
| 560 | db_bind_int(&q2, "$id", stashid); |
| 561 | while( db_step(&q2)==SQLITE_ROW ){ |
| 562 | int isAdded = db_column_int(&q2, 0); |
| 563 |
+4
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -172,10 +172,14 @@ | ||
| 172 | 172 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 173 | 173 | const char *p; |
| 174 | 174 | |
| 175 | 175 | brief = find_option("brief", "b",0)!=0; |
| 176 | 176 | db_find_and_open_repository(0,0); |
| 177 | + | |
| 178 | + /* We should be done with options.. */ | |
| 179 | + verify_all_options(); | |
| 180 | + | |
| 177 | 181 | fsize = file_size(g.zRepositoryName); |
| 178 | 182 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 179 | 183 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 180 | 184 | if( !brief ){ |
| 181 | 185 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 182 | 186 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -172,10 +172,14 @@ | |
| 172 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 173 | const char *p; |
| 174 | |
| 175 | brief = find_option("brief", "b",0)!=0; |
| 176 | db_find_and_open_repository(0,0); |
| 177 | fsize = file_size(g.zRepositoryName); |
| 178 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 179 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 180 | if( !brief ){ |
| 181 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 182 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -172,10 +172,14 @@ | |
| 172 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 173 | const char *p; |
| 174 | |
| 175 | brief = find_option("brief", "b",0)!=0; |
| 176 | db_find_and_open_repository(0,0); |
| 177 | |
| 178 | /* We should be done with options.. */ |
| 179 | verify_all_options(); |
| 180 | |
| 181 | fsize = file_size(g.zRepositoryName); |
| 182 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 183 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 184 | if( !brief ){ |
| 185 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 186 |
+16
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -186,10 +186,14 @@ | ||
| 186 | 186 | */ |
| 187 | 187 | void pull_cmd(void){ |
| 188 | 188 | unsigned configFlags = 0; |
| 189 | 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | + | |
| 192 | + /* We should be done with options.. */ | |
| 193 | + verify_all_options(); | |
| 194 | + | |
| 191 | 195 | client_sync(syncFlags, configFlags, 0); |
| 192 | 196 | } |
| 193 | 197 | |
| 194 | 198 | /* |
| 195 | 199 | ** COMMAND: push |
| @@ -217,10 +221,14 @@ | ||
| 217 | 221 | */ |
| 218 | 222 | void push_cmd(void){ |
| 219 | 223 | unsigned configFlags = 0; |
| 220 | 224 | unsigned syncFlags = SYNC_PUSH; |
| 221 | 225 | process_sync_args(&configFlags, &syncFlags); |
| 226 | + | |
| 227 | + /* We should be done with options.. */ | |
| 228 | + verify_all_options(); | |
| 229 | + | |
| 222 | 230 | if( db_get_boolean("dont-push",0) ){ |
| 223 | 231 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 224 | 232 | } |
| 225 | 233 | client_sync(syncFlags, 0, 0); |
| 226 | 234 | } |
| @@ -253,10 +261,14 @@ | ||
| 253 | 261 | */ |
| 254 | 262 | void sync_cmd(void){ |
| 255 | 263 | unsigned configFlags = 0; |
| 256 | 264 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 257 | 265 | process_sync_args(&configFlags, &syncFlags); |
| 266 | + | |
| 267 | + /* We should be done with options.. */ | |
| 268 | + verify_all_options(); | |
| 269 | + | |
| 258 | 270 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 259 | 271 | client_sync(syncFlags, configFlags, 0); |
| 260 | 272 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 261 | 273 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 262 | 274 | } |
| @@ -280,10 +292,14 @@ | ||
| 280 | 292 | ** See also: clone, push, pull, sync |
| 281 | 293 | */ |
| 282 | 294 | void remote_url_cmd(void){ |
| 283 | 295 | char *zUrl; |
| 284 | 296 | db_find_and_open_repository(0, 0); |
| 297 | + | |
| 298 | + /* We should be done with options.. */ | |
| 299 | + verify_all_options(); | |
| 300 | + | |
| 285 | 301 | if( g.argc!=2 && g.argc!=3 ){ |
| 286 | 302 | usage("remote-url ?URL|off?"); |
| 287 | 303 | } |
| 288 | 304 | if( g.argc==3 ){ |
| 289 | 305 | db_unset("last-sync-url", 0); |
| 290 | 306 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -186,10 +186,14 @@ | |
| 186 | */ |
| 187 | void pull_cmd(void){ |
| 188 | unsigned configFlags = 0; |
| 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | client_sync(syncFlags, configFlags, 0); |
| 192 | } |
| 193 | |
| 194 | /* |
| 195 | ** COMMAND: push |
| @@ -217,10 +221,14 @@ | |
| 217 | */ |
| 218 | void push_cmd(void){ |
| 219 | unsigned configFlags = 0; |
| 220 | unsigned syncFlags = SYNC_PUSH; |
| 221 | process_sync_args(&configFlags, &syncFlags); |
| 222 | if( db_get_boolean("dont-push",0) ){ |
| 223 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 224 | } |
| 225 | client_sync(syncFlags, 0, 0); |
| 226 | } |
| @@ -253,10 +261,14 @@ | |
| 253 | */ |
| 254 | void sync_cmd(void){ |
| 255 | unsigned configFlags = 0; |
| 256 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 257 | process_sync_args(&configFlags, &syncFlags); |
| 258 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 259 | client_sync(syncFlags, configFlags, 0); |
| 260 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 261 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 262 | } |
| @@ -280,10 +292,14 @@ | |
| 280 | ** See also: clone, push, pull, sync |
| 281 | */ |
| 282 | void remote_url_cmd(void){ |
| 283 | char *zUrl; |
| 284 | db_find_and_open_repository(0, 0); |
| 285 | if( g.argc!=2 && g.argc!=3 ){ |
| 286 | usage("remote-url ?URL|off?"); |
| 287 | } |
| 288 | if( g.argc==3 ){ |
| 289 | db_unset("last-sync-url", 0); |
| 290 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -186,10 +186,14 @@ | |
| 186 | */ |
| 187 | void pull_cmd(void){ |
| 188 | unsigned configFlags = 0; |
| 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | |
| 192 | /* We should be done with options.. */ |
| 193 | verify_all_options(); |
| 194 | |
| 195 | client_sync(syncFlags, configFlags, 0); |
| 196 | } |
| 197 | |
| 198 | /* |
| 199 | ** COMMAND: push |
| @@ -217,10 +221,14 @@ | |
| 221 | */ |
| 222 | void push_cmd(void){ |
| 223 | unsigned configFlags = 0; |
| 224 | unsigned syncFlags = SYNC_PUSH; |
| 225 | process_sync_args(&configFlags, &syncFlags); |
| 226 | |
| 227 | /* We should be done with options.. */ |
| 228 | verify_all_options(); |
| 229 | |
| 230 | if( db_get_boolean("dont-push",0) ){ |
| 231 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 232 | } |
| 233 | client_sync(syncFlags, 0, 0); |
| 234 | } |
| @@ -253,10 +261,14 @@ | |
| 261 | */ |
| 262 | void sync_cmd(void){ |
| 263 | unsigned configFlags = 0; |
| 264 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 265 | process_sync_args(&configFlags, &syncFlags); |
| 266 | |
| 267 | /* We should be done with options.. */ |
| 268 | verify_all_options(); |
| 269 | |
| 270 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 271 | client_sync(syncFlags, configFlags, 0); |
| 272 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 273 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 274 | } |
| @@ -280,10 +292,14 @@ | |
| 292 | ** See also: clone, push, pull, sync |
| 293 | */ |
| 294 | void remote_url_cmd(void){ |
| 295 | char *zUrl; |
| 296 | db_find_and_open_repository(0, 0); |
| 297 | |
| 298 | /* We should be done with options.. */ |
| 299 | verify_all_options(); |
| 300 | |
| 301 | if( g.argc!=2 && g.argc!=3 ){ |
| 302 | usage("remote-url ?URL|off?"); |
| 303 | } |
| 304 | if( g.argc==3 ){ |
| 305 | db_unset("last-sync-url", 0); |
| 306 |
+9
-3
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -540,10 +540,14 @@ | ||
| 540 | 540 | int rid; |
| 541 | 541 | Blob tarball; |
| 542 | 542 | const char *zName; |
| 543 | 543 | zName = find_option("name", 0, 1); |
| 544 | 544 | db_find_and_open_repository(0, 0); |
| 545 | + | |
| 546 | + /* We should be done with options.. */ | |
| 547 | + verify_all_options(); | |
| 548 | + | |
| 545 | 549 | if( g.argc!=4 ){ |
| 546 | 550 | usage("VERSION OUTPUTFILE"); |
| 547 | 551 | } |
| 548 | 552 | rid = name_to_typed_rid(g.argv[2], "ci"); |
| 549 | 553 | if( rid==0 ){ |
| @@ -574,15 +578,17 @@ | ||
| 574 | 578 | ** Generate a compressed tarball for a checkin. |
| 575 | 579 | ** Return that tarball as the HTTP reply content. |
| 576 | 580 | ** |
| 577 | 581 | ** Optional URL Parameters: |
| 578 | 582 | ** |
| 579 | -** - name=base name of the output file. Defaults to | |
| 580 | -** something project/version-specific. | |
| 583 | +** - name=NAME[.tar.gz] is base name of the output file. Defaults to | |
| 584 | +** something project/version-specific. The prefix of the name, up to | |
| 585 | +** the last '.', are used as the top-most directory name in the tar | |
| 586 | +** output. | |
| 581 | 587 | ** |
| 582 | 588 | ** - uuid=the version to tar (may be a tag/branch name). |
| 583 | -** Defaults to trunk. | |
| 589 | +** Defaults to "trunk". | |
| 584 | 590 | ** |
| 585 | 591 | */ |
| 586 | 592 | void tarball_page(void){ |
| 587 | 593 | int rid; |
| 588 | 594 | char *zName, *zRid, *zKey; |
| 589 | 595 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -540,10 +540,14 @@ | |
| 540 | int rid; |
| 541 | Blob tarball; |
| 542 | const char *zName; |
| 543 | zName = find_option("name", 0, 1); |
| 544 | db_find_and_open_repository(0, 0); |
| 545 | if( g.argc!=4 ){ |
| 546 | usage("VERSION OUTPUTFILE"); |
| 547 | } |
| 548 | rid = name_to_typed_rid(g.argv[2], "ci"); |
| 549 | if( rid==0 ){ |
| @@ -574,15 +578,17 @@ | |
| 574 | ** Generate a compressed tarball for a checkin. |
| 575 | ** Return that tarball as the HTTP reply content. |
| 576 | ** |
| 577 | ** Optional URL Parameters: |
| 578 | ** |
| 579 | ** - name=base name of the output file. Defaults to |
| 580 | ** something project/version-specific. |
| 581 | ** |
| 582 | ** - uuid=the version to tar (may be a tag/branch name). |
| 583 | ** Defaults to trunk. |
| 584 | ** |
| 585 | */ |
| 586 | void tarball_page(void){ |
| 587 | int rid; |
| 588 | char *zName, *zRid, *zKey; |
| 589 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -540,10 +540,14 @@ | |
| 540 | int rid; |
| 541 | Blob tarball; |
| 542 | const char *zName; |
| 543 | zName = find_option("name", 0, 1); |
| 544 | db_find_and_open_repository(0, 0); |
| 545 | |
| 546 | /* We should be done with options.. */ |
| 547 | verify_all_options(); |
| 548 | |
| 549 | if( g.argc!=4 ){ |
| 550 | usage("VERSION OUTPUTFILE"); |
| 551 | } |
| 552 | rid = name_to_typed_rid(g.argv[2], "ci"); |
| 553 | if( rid==0 ){ |
| @@ -574,15 +578,17 @@ | |
| 578 | ** Generate a compressed tarball for a checkin. |
| 579 | ** Return that tarball as the HTTP reply content. |
| 580 | ** |
| 581 | ** Optional URL Parameters: |
| 582 | ** |
| 583 | ** - name=NAME[.tar.gz] is base name of the output file. Defaults to |
| 584 | ** something project/version-specific. The prefix of the name, up to |
| 585 | ** the last '.', are used as the top-most directory name in the tar |
| 586 | ** output. |
| 587 | ** |
| 588 | ** - uuid=the version to tar (may be a tag/branch name). |
| 589 | ** Defaults to "trunk". |
| 590 | ** |
| 591 | */ |
| 592 | void tarball_page(void){ |
| 593 | int rid; |
| 594 | char *zName, *zRid, *zKey; |
| 595 |
M
src/th.c
+2
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -511,16 +511,18 @@ | ||
| 511 | 511 | } |
| 512 | 512 | iEnd++; |
| 513 | 513 | } |
| 514 | 514 | if( nBrace>0 || nSq>0 ){ |
| 515 | 515 | /* Parse error */ |
| 516 | + Th_SetResult(interp, "parse error", -1); | |
| 516 | 517 | return TH_ERROR; |
| 517 | 518 | } |
| 518 | 519 | } |
| 519 | 520 | |
| 520 | 521 | if( iEnd>nInput ){ |
| 521 | 522 | /* Parse error */ |
| 523 | + Th_SetResult(interp, "parse error", -1); | |
| 522 | 524 | return TH_ERROR; |
| 523 | 525 | } |
| 524 | 526 | *pnWord = iEnd; |
| 525 | 527 | return TH_OK; |
| 526 | 528 | } |
| 527 | 529 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -511,16 +511,18 @@ | |
| 511 | } |
| 512 | iEnd++; |
| 513 | } |
| 514 | if( nBrace>0 || nSq>0 ){ |
| 515 | /* Parse error */ |
| 516 | return TH_ERROR; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | if( iEnd>nInput ){ |
| 521 | /* Parse error */ |
| 522 | return TH_ERROR; |
| 523 | } |
| 524 | *pnWord = iEnd; |
| 525 | return TH_OK; |
| 526 | } |
| 527 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -511,16 +511,18 @@ | |
| 511 | } |
| 512 | iEnd++; |
| 513 | } |
| 514 | if( nBrace>0 || nSq>0 ){ |
| 515 | /* Parse error */ |
| 516 | Th_SetResult(interp, "parse error", -1); |
| 517 | return TH_ERROR; |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | if( iEnd>nInput ){ |
| 522 | /* Parse error */ |
| 523 | Th_SetResult(interp, "parse error", -1); |
| 524 | return TH_ERROR; |
| 525 | } |
| 526 | *pnWord = iEnd; |
| 527 | return TH_OK; |
| 528 | } |
| 529 |
+63
-63
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -145,14 +145,14 @@ | ||
| 145 | 145 | ** |
| 146 | 146 | ** Escape all characters of STRING which have special meaning in URI |
| 147 | 147 | ** components. Return a new string result. |
| 148 | 148 | */ |
| 149 | 149 | static int httpizeCmd( |
| 150 | - Th_Interp *interp, | |
| 151 | - void *p, | |
| 152 | - int argc, | |
| 153 | - const char **argv, | |
| 150 | + Th_Interp *interp, | |
| 151 | + void *p, | |
| 152 | + int argc, | |
| 153 | + const char **argv, | |
| 154 | 154 | int *argl |
| 155 | 155 | ){ |
| 156 | 156 | char *zOut; |
| 157 | 157 | if( argc!=2 ){ |
| 158 | 158 | return Th_WrongNumArgs(interp, "httpize STRING"); |
| @@ -172,14 +172,14 @@ | ||
| 172 | 172 | ** TH1 command: enable_output BOOLEAN |
| 173 | 173 | ** |
| 174 | 174 | ** Enable or disable the puts and hputs commands. |
| 175 | 175 | */ |
| 176 | 176 | static int enableOutputCmd( |
| 177 | - Th_Interp *interp, | |
| 178 | - void *p, | |
| 179 | - int argc, | |
| 180 | - const char **argv, | |
| 177 | + Th_Interp *interp, | |
| 178 | + void *p, | |
| 179 | + int argc, | |
| 180 | + const char **argv, | |
| 181 | 181 | int *argl |
| 182 | 182 | ){ |
| 183 | 183 | int rc; |
| 184 | 184 | if( argc<2 || argc>3 ){ |
| 185 | 185 | return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN"); |
| @@ -245,17 +245,17 @@ | ||
| 245 | 245 | |
| 246 | 246 | /* |
| 247 | 247 | ** TH1 command: puts STRING |
| 248 | 248 | ** TH1 command: html STRING |
| 249 | 249 | ** |
| 250 | -** Output STRING escaped for HTML (html) or unchanged (puts). | |
| 250 | +** Output STRING escaped for HTML (html) or unchanged (puts). | |
| 251 | 251 | */ |
| 252 | 252 | static int putsCmd( |
| 253 | - Th_Interp *interp, | |
| 254 | - void *pConvert, | |
| 255 | - int argc, | |
| 256 | - const char **argv, | |
| 253 | + Th_Interp *interp, | |
| 254 | + void *pConvert, | |
| 255 | + int argc, | |
| 256 | + const char **argv, | |
| 257 | 257 | int *argl |
| 258 | 258 | ){ |
| 259 | 259 | if( argc!=2 ){ |
| 260 | 260 | return Th_WrongNumArgs(interp, "puts STRING"); |
| 261 | 261 | } |
| @@ -267,14 +267,14 @@ | ||
| 267 | 267 | ** TH1 command: wiki STRING |
| 268 | 268 | ** |
| 269 | 269 | ** Render the input string as wiki. |
| 270 | 270 | */ |
| 271 | 271 | static int wikiCmd( |
| 272 | - Th_Interp *interp, | |
| 273 | - void *p, | |
| 274 | - int argc, | |
| 275 | - const char **argv, | |
| 272 | + Th_Interp *interp, | |
| 273 | + void *p, | |
| 274 | + int argc, | |
| 275 | + const char **argv, | |
| 276 | 276 | int *argl |
| 277 | 277 | ){ |
| 278 | 278 | int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p; |
| 279 | 279 | if( argc!=2 ){ |
| 280 | 280 | return Th_WrongNumArgs(interp, "wiki STRING"); |
| @@ -293,14 +293,14 @@ | ||
| 293 | 293 | ** |
| 294 | 294 | ** Escape all characters of STRING which have special meaning in HTML. |
| 295 | 295 | ** Return a new string result. |
| 296 | 296 | */ |
| 297 | 297 | static int htmlizeCmd( |
| 298 | - Th_Interp *interp, | |
| 299 | - void *p, | |
| 300 | - int argc, | |
| 301 | - const char **argv, | |
| 298 | + Th_Interp *interp, | |
| 299 | + void *p, | |
| 300 | + int argc, | |
| 301 | + const char **argv, | |
| 302 | 302 | int *argl |
| 303 | 303 | ){ |
| 304 | 304 | char *zOut; |
| 305 | 305 | if( argc!=2 ){ |
| 306 | 306 | return Th_WrongNumArgs(interp, "htmlize STRING"); |
| @@ -317,14 +317,14 @@ | ||
| 317 | 317 | ** Return a string which is the current time and date. If the |
| 318 | 318 | ** -local option is used, the date appears using localtime instead |
| 319 | 319 | ** of UTC. |
| 320 | 320 | */ |
| 321 | 321 | static int dateCmd( |
| 322 | - Th_Interp *interp, | |
| 323 | - void *p, | |
| 324 | - int argc, | |
| 325 | - const char **argv, | |
| 322 | + Th_Interp *interp, | |
| 323 | + void *p, | |
| 324 | + int argc, | |
| 325 | + const char **argv, | |
| 326 | 326 | int *argl |
| 327 | 327 | ){ |
| 328 | 328 | char *zOut; |
| 329 | 329 | if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){ |
| 330 | 330 | zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc()); |
| @@ -340,14 +340,14 @@ | ||
| 340 | 340 | ** TH1 command: hascap STRING... |
| 341 | 341 | ** |
| 342 | 342 | ** Return true if the user has all of the capabilities listed in STRING. |
| 343 | 343 | */ |
| 344 | 344 | static int hascapCmd( |
| 345 | - Th_Interp *interp, | |
| 346 | - void *p, | |
| 347 | - int argc, | |
| 348 | - const char **argv, | |
| 345 | + Th_Interp *interp, | |
| 346 | + void *p, | |
| 347 | + int argc, | |
| 348 | + const char **argv, | |
| 349 | 349 | int *argl |
| 350 | 350 | ){ |
| 351 | 351 | int rc = 0, i; |
| 352 | 352 | if( argc<2 ){ |
| 353 | 353 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| @@ -377,14 +377,14 @@ | ||
| 377 | 377 | ** "json" = FOSSIL_ENABLE_JSON |
| 378 | 378 | ** "markdown" = FOSSIL_ENABLE_MARKDOWN |
| 379 | 379 | ** |
| 380 | 380 | */ |
| 381 | 381 | static int hasfeatureCmd( |
| 382 | - Th_Interp *interp, | |
| 383 | - void *p, | |
| 384 | - int argc, | |
| 385 | - const char **argv, | |
| 382 | + Th_Interp *interp, | |
| 383 | + void *p, | |
| 384 | + int argc, | |
| 385 | + const char **argv, | |
| 386 | 386 | int *argl |
| 387 | 387 | ){ |
| 388 | 388 | int rc = 0; |
| 389 | 389 | char const * zArg; |
| 390 | 390 | if( argc!=2 ){ |
| @@ -475,14 +475,14 @@ | ||
| 475 | 475 | ** TH1 command: anycap STRING |
| 476 | 476 | ** |
| 477 | 477 | ** Return true if the user has any one of the capabilities listed in STRING. |
| 478 | 478 | */ |
| 479 | 479 | static int anycapCmd( |
| 480 | - Th_Interp *interp, | |
| 481 | - void *p, | |
| 482 | - int argc, | |
| 483 | - const char **argv, | |
| 480 | + Th_Interp *interp, | |
| 481 | + void *p, | |
| 482 | + int argc, | |
| 483 | + const char **argv, | |
| 484 | 484 | int *argl |
| 485 | 485 | ){ |
| 486 | 486 | int rc = 0; |
| 487 | 487 | int i; |
| 488 | 488 | if( argc!=2 ){ |
| @@ -508,13 +508,13 @@ | ||
| 508 | 508 | ** If NUMLINES is greater than one then the display is a listbox |
| 509 | 509 | ** with the number of lines given. |
| 510 | 510 | */ |
| 511 | 511 | static int comboboxCmd( |
| 512 | 512 | Th_Interp *interp, |
| 513 | - void *p, | |
| 514 | - int argc, | |
| 515 | - const char **argv, | |
| 513 | + void *p, | |
| 514 | + int argc, | |
| 515 | + const char **argv, | |
| 516 | 516 | int *argl |
| 517 | 517 | ){ |
| 518 | 518 | if( argc!=4 ){ |
| 519 | 519 | return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES"); |
| 520 | 520 | } |
| @@ -539,11 +539,11 @@ | ||
| 539 | 539 | sendText(z, -1, 0); |
| 540 | 540 | free(z); |
| 541 | 541 | blob_reset(&name); |
| 542 | 542 | for(i=0; i<nElem; i++){ |
| 543 | 543 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 544 | - if( zValue && aszElem[i]==nValue | |
| 544 | + if( zValue && aszElem[i]==nValue | |
| 545 | 545 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 546 | 546 | z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", |
| 547 | 547 | zH, zH); |
| 548 | 548 | }else{ |
| 549 | 549 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| @@ -564,13 +564,13 @@ | ||
| 564 | 564 | ** Return one more than the number of \n characters in STRING. But |
| 565 | 565 | ** never return less than MIN or more than MAX. |
| 566 | 566 | */ |
| 567 | 567 | static int linecntCmd( |
| 568 | 568 | Th_Interp *interp, |
| 569 | - void *p, | |
| 570 | - int argc, | |
| 571 | - const char **argv, | |
| 569 | + void *p, | |
| 570 | + int argc, | |
| 571 | + const char **argv, | |
| 572 | 572 | int *argl |
| 573 | 573 | ){ |
| 574 | 574 | const char *z; |
| 575 | 575 | int size, n, i; |
| 576 | 576 | int iMin, iMax; |
| @@ -600,13 +600,13 @@ | ||
| 600 | 600 | ** string if one is not currently open. Optionally, it will attempt to open |
| 601 | 601 | ** the repository if the boolean argument is non-zero. |
| 602 | 602 | */ |
| 603 | 603 | static int repositoryCmd( |
| 604 | 604 | Th_Interp *interp, |
| 605 | - void *p, | |
| 606 | - int argc, | |
| 607 | - const char **argv, | |
| 605 | + void *p, | |
| 606 | + int argc, | |
| 607 | + const char **argv, | |
| 608 | 608 | int *argl |
| 609 | 609 | ){ |
| 610 | 610 | if( argc!=1 && argc!=2 ){ |
| 611 | 611 | return Th_WrongNumArgs(interp, "repository ?BOOLEAN?"); |
| 612 | 612 | } |
| @@ -855,11 +855,11 @@ | ||
| 855 | 855 | getrusage(RUSAGE_SELF, &s); |
| 856 | 856 | if( piUser ){ |
| 857 | 857 | *piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec; |
| 858 | 858 | } |
| 859 | 859 | if( piKernel ){ |
| 860 | - *piKernel = | |
| 860 | + *piKernel = | |
| 861 | 861 | ((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec; |
| 862 | 862 | } |
| 863 | 863 | #endif |
| 864 | 864 | } |
| 865 | 865 | |
| @@ -869,13 +869,13 @@ | ||
| 869 | 869 | ** Return the number of microseconds of CPU time consumed by the current |
| 870 | 870 | ** process in user space. |
| 871 | 871 | */ |
| 872 | 872 | static int utimeCmd( |
| 873 | 873 | Th_Interp *interp, |
| 874 | - void *p, | |
| 875 | - int argc, | |
| 876 | - const char **argv, | |
| 874 | + void *p, | |
| 875 | + int argc, | |
| 876 | + const char **argv, | |
| 877 | 877 | int *argl |
| 878 | 878 | ){ |
| 879 | 879 | sqlite3_uint64 x; |
| 880 | 880 | char zUTime[50]; |
| 881 | 881 | getCpuTimes(&x, 0); |
| @@ -890,13 +890,13 @@ | ||
| 890 | 890 | ** Return the number of microseconds of CPU time consumed by the current |
| 891 | 891 | ** process in system space. |
| 892 | 892 | */ |
| 893 | 893 | static int stimeCmd( |
| 894 | 894 | Th_Interp *interp, |
| 895 | - void *p, | |
| 896 | - int argc, | |
| 897 | - const char **argv, | |
| 895 | + void *p, | |
| 896 | + int argc, | |
| 897 | + const char **argv, | |
| 898 | 898 | int *argl |
| 899 | 899 | ){ |
| 900 | 900 | sqlite3_uint64 x; |
| 901 | 901 | char zUTime[50]; |
| 902 | 902 | getCpuTimes(0, &x); |
| @@ -907,18 +907,18 @@ | ||
| 907 | 907 | |
| 908 | 908 | |
| 909 | 909 | /* |
| 910 | 910 | ** TH1 command: randhex N |
| 911 | 911 | ** |
| 912 | -** Return N*2 random hexadecimal digits with N<50. If N is omitted, | |
| 912 | +** Return N*2 random hexadecimal digits with N<50. If N is omitted, | |
| 913 | 913 | ** use a value of 10. |
| 914 | 914 | */ |
| 915 | 915 | static int randhexCmd( |
| 916 | 916 | Th_Interp *interp, |
| 917 | - void *p, | |
| 918 | - int argc, | |
| 919 | - const char **argv, | |
| 917 | + void *p, | |
| 918 | + int argc, | |
| 919 | + const char **argv, | |
| 920 | 920 | int *argl |
| 921 | 921 | ){ |
| 922 | 922 | int n; |
| 923 | 923 | unsigned char aRand[50]; |
| 924 | 924 | unsigned char zOut[100]; |
| @@ -950,13 +950,13 @@ | ||
| 950 | 950 | ** "var". Result values are stored in variables with the column name prior |
| 951 | 951 | ** to each invocation of CODE. |
| 952 | 952 | */ |
| 953 | 953 | static int queryCmd( |
| 954 | 954 | Th_Interp *interp, |
| 955 | - void *p, | |
| 956 | - int argc, | |
| 957 | - const char **argv, | |
| 955 | + void *p, | |
| 956 | + int argc, | |
| 957 | + const char **argv, | |
| 958 | 958 | int *argl |
| 959 | 959 | ){ |
| 960 | 960 | sqlite3_stmt *pStmt; |
| 961 | 961 | int rc; |
| 962 | 962 | const char *zSql; |
| @@ -1016,11 +1016,11 @@ | ||
| 1016 | 1016 | rc = sqlite3_finalize(pStmt); |
| 1017 | 1017 | if( rc!=SQLITE_OK ){ |
| 1018 | 1018 | Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1); |
| 1019 | 1019 | return TH_ERROR; |
| 1020 | 1020 | } |
| 1021 | - } | |
| 1021 | + } | |
| 1022 | 1022 | return res; |
| 1023 | 1023 | } |
| 1024 | 1024 | |
| 1025 | 1025 | /* |
| 1026 | 1026 | ** TH1 command: setting name |
| @@ -1691,11 +1691,11 @@ | ||
| 1691 | 1691 | } |
| 1692 | 1692 | #endif |
| 1693 | 1693 | |
| 1694 | 1694 | /* |
| 1695 | 1695 | ** The z[] input contains text mixed with TH1 scripts. |
| 1696 | -** The TH1 scripts are contained within <th1>...</th1>. | |
| 1696 | +** The TH1 scripts are contained within <th1>...</th1>. | |
| 1697 | 1697 | ** TH1 variables are $aaa or $<aaa>. The first form of |
| 1698 | 1698 | ** variable is literal. The second is run through htmlize |
| 1699 | 1699 | ** before being inserted. |
| 1700 | 1700 | ** |
| 1701 | 1701 | ** This routine processes the template and writes the results |
| 1702 | 1702 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -145,14 +145,14 @@ | |
| 145 | ** |
| 146 | ** Escape all characters of STRING which have special meaning in URI |
| 147 | ** components. Return a new string result. |
| 148 | */ |
| 149 | static int httpizeCmd( |
| 150 | Th_Interp *interp, |
| 151 | void *p, |
| 152 | int argc, |
| 153 | const char **argv, |
| 154 | int *argl |
| 155 | ){ |
| 156 | char *zOut; |
| 157 | if( argc!=2 ){ |
| 158 | return Th_WrongNumArgs(interp, "httpize STRING"); |
| @@ -172,14 +172,14 @@ | |
| 172 | ** TH1 command: enable_output BOOLEAN |
| 173 | ** |
| 174 | ** Enable or disable the puts and hputs commands. |
| 175 | */ |
| 176 | static int enableOutputCmd( |
| 177 | Th_Interp *interp, |
| 178 | void *p, |
| 179 | int argc, |
| 180 | const char **argv, |
| 181 | int *argl |
| 182 | ){ |
| 183 | int rc; |
| 184 | if( argc<2 || argc>3 ){ |
| 185 | return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN"); |
| @@ -245,17 +245,17 @@ | |
| 245 | |
| 246 | /* |
| 247 | ** TH1 command: puts STRING |
| 248 | ** TH1 command: html STRING |
| 249 | ** |
| 250 | ** Output STRING escaped for HTML (html) or unchanged (puts). |
| 251 | */ |
| 252 | static int putsCmd( |
| 253 | Th_Interp *interp, |
| 254 | void *pConvert, |
| 255 | int argc, |
| 256 | const char **argv, |
| 257 | int *argl |
| 258 | ){ |
| 259 | if( argc!=2 ){ |
| 260 | return Th_WrongNumArgs(interp, "puts STRING"); |
| 261 | } |
| @@ -267,14 +267,14 @@ | |
| 267 | ** TH1 command: wiki STRING |
| 268 | ** |
| 269 | ** Render the input string as wiki. |
| 270 | */ |
| 271 | static int wikiCmd( |
| 272 | Th_Interp *interp, |
| 273 | void *p, |
| 274 | int argc, |
| 275 | const char **argv, |
| 276 | int *argl |
| 277 | ){ |
| 278 | int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p; |
| 279 | if( argc!=2 ){ |
| 280 | return Th_WrongNumArgs(interp, "wiki STRING"); |
| @@ -293,14 +293,14 @@ | |
| 293 | ** |
| 294 | ** Escape all characters of STRING which have special meaning in HTML. |
| 295 | ** Return a new string result. |
| 296 | */ |
| 297 | static int htmlizeCmd( |
| 298 | Th_Interp *interp, |
| 299 | void *p, |
| 300 | int argc, |
| 301 | const char **argv, |
| 302 | int *argl |
| 303 | ){ |
| 304 | char *zOut; |
| 305 | if( argc!=2 ){ |
| 306 | return Th_WrongNumArgs(interp, "htmlize STRING"); |
| @@ -317,14 +317,14 @@ | |
| 317 | ** Return a string which is the current time and date. If the |
| 318 | ** -local option is used, the date appears using localtime instead |
| 319 | ** of UTC. |
| 320 | */ |
| 321 | static int dateCmd( |
| 322 | Th_Interp *interp, |
| 323 | void *p, |
| 324 | int argc, |
| 325 | const char **argv, |
| 326 | int *argl |
| 327 | ){ |
| 328 | char *zOut; |
| 329 | if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){ |
| 330 | zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc()); |
| @@ -340,14 +340,14 @@ | |
| 340 | ** TH1 command: hascap STRING... |
| 341 | ** |
| 342 | ** Return true if the user has all of the capabilities listed in STRING. |
| 343 | */ |
| 344 | static int hascapCmd( |
| 345 | Th_Interp *interp, |
| 346 | void *p, |
| 347 | int argc, |
| 348 | const char **argv, |
| 349 | int *argl |
| 350 | ){ |
| 351 | int rc = 0, i; |
| 352 | if( argc<2 ){ |
| 353 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| @@ -377,14 +377,14 @@ | |
| 377 | ** "json" = FOSSIL_ENABLE_JSON |
| 378 | ** "markdown" = FOSSIL_ENABLE_MARKDOWN |
| 379 | ** |
| 380 | */ |
| 381 | static int hasfeatureCmd( |
| 382 | Th_Interp *interp, |
| 383 | void *p, |
| 384 | int argc, |
| 385 | const char **argv, |
| 386 | int *argl |
| 387 | ){ |
| 388 | int rc = 0; |
| 389 | char const * zArg; |
| 390 | if( argc!=2 ){ |
| @@ -475,14 +475,14 @@ | |
| 475 | ** TH1 command: anycap STRING |
| 476 | ** |
| 477 | ** Return true if the user has any one of the capabilities listed in STRING. |
| 478 | */ |
| 479 | static int anycapCmd( |
| 480 | Th_Interp *interp, |
| 481 | void *p, |
| 482 | int argc, |
| 483 | const char **argv, |
| 484 | int *argl |
| 485 | ){ |
| 486 | int rc = 0; |
| 487 | int i; |
| 488 | if( argc!=2 ){ |
| @@ -508,13 +508,13 @@ | |
| 508 | ** If NUMLINES is greater than one then the display is a listbox |
| 509 | ** with the number of lines given. |
| 510 | */ |
| 511 | static int comboboxCmd( |
| 512 | Th_Interp *interp, |
| 513 | void *p, |
| 514 | int argc, |
| 515 | const char **argv, |
| 516 | int *argl |
| 517 | ){ |
| 518 | if( argc!=4 ){ |
| 519 | return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES"); |
| 520 | } |
| @@ -539,11 +539,11 @@ | |
| 539 | sendText(z, -1, 0); |
| 540 | free(z); |
| 541 | blob_reset(&name); |
| 542 | for(i=0; i<nElem; i++){ |
| 543 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 544 | if( zValue && aszElem[i]==nValue |
| 545 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 546 | z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", |
| 547 | zH, zH); |
| 548 | }else{ |
| 549 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| @@ -564,13 +564,13 @@ | |
| 564 | ** Return one more than the number of \n characters in STRING. But |
| 565 | ** never return less than MIN or more than MAX. |
| 566 | */ |
| 567 | static int linecntCmd( |
| 568 | Th_Interp *interp, |
| 569 | void *p, |
| 570 | int argc, |
| 571 | const char **argv, |
| 572 | int *argl |
| 573 | ){ |
| 574 | const char *z; |
| 575 | int size, n, i; |
| 576 | int iMin, iMax; |
| @@ -600,13 +600,13 @@ | |
| 600 | ** string if one is not currently open. Optionally, it will attempt to open |
| 601 | ** the repository if the boolean argument is non-zero. |
| 602 | */ |
| 603 | static int repositoryCmd( |
| 604 | Th_Interp *interp, |
| 605 | void *p, |
| 606 | int argc, |
| 607 | const char **argv, |
| 608 | int *argl |
| 609 | ){ |
| 610 | if( argc!=1 && argc!=2 ){ |
| 611 | return Th_WrongNumArgs(interp, "repository ?BOOLEAN?"); |
| 612 | } |
| @@ -855,11 +855,11 @@ | |
| 855 | getrusage(RUSAGE_SELF, &s); |
| 856 | if( piUser ){ |
| 857 | *piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec; |
| 858 | } |
| 859 | if( piKernel ){ |
| 860 | *piKernel = |
| 861 | ((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec; |
| 862 | } |
| 863 | #endif |
| 864 | } |
| 865 | |
| @@ -869,13 +869,13 @@ | |
| 869 | ** Return the number of microseconds of CPU time consumed by the current |
| 870 | ** process in user space. |
| 871 | */ |
| 872 | static int utimeCmd( |
| 873 | Th_Interp *interp, |
| 874 | void *p, |
| 875 | int argc, |
| 876 | const char **argv, |
| 877 | int *argl |
| 878 | ){ |
| 879 | sqlite3_uint64 x; |
| 880 | char zUTime[50]; |
| 881 | getCpuTimes(&x, 0); |
| @@ -890,13 +890,13 @@ | |
| 890 | ** Return the number of microseconds of CPU time consumed by the current |
| 891 | ** process in system space. |
| 892 | */ |
| 893 | static int stimeCmd( |
| 894 | Th_Interp *interp, |
| 895 | void *p, |
| 896 | int argc, |
| 897 | const char **argv, |
| 898 | int *argl |
| 899 | ){ |
| 900 | sqlite3_uint64 x; |
| 901 | char zUTime[50]; |
| 902 | getCpuTimes(0, &x); |
| @@ -907,18 +907,18 @@ | |
| 907 | |
| 908 | |
| 909 | /* |
| 910 | ** TH1 command: randhex N |
| 911 | ** |
| 912 | ** Return N*2 random hexadecimal digits with N<50. If N is omitted, |
| 913 | ** use a value of 10. |
| 914 | */ |
| 915 | static int randhexCmd( |
| 916 | Th_Interp *interp, |
| 917 | void *p, |
| 918 | int argc, |
| 919 | const char **argv, |
| 920 | int *argl |
| 921 | ){ |
| 922 | int n; |
| 923 | unsigned char aRand[50]; |
| 924 | unsigned char zOut[100]; |
| @@ -950,13 +950,13 @@ | |
| 950 | ** "var". Result values are stored in variables with the column name prior |
| 951 | ** to each invocation of CODE. |
| 952 | */ |
| 953 | static int queryCmd( |
| 954 | Th_Interp *interp, |
| 955 | void *p, |
| 956 | int argc, |
| 957 | const char **argv, |
| 958 | int *argl |
| 959 | ){ |
| 960 | sqlite3_stmt *pStmt; |
| 961 | int rc; |
| 962 | const char *zSql; |
| @@ -1016,11 +1016,11 @@ | |
| 1016 | rc = sqlite3_finalize(pStmt); |
| 1017 | if( rc!=SQLITE_OK ){ |
| 1018 | Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1); |
| 1019 | return TH_ERROR; |
| 1020 | } |
| 1021 | } |
| 1022 | return res; |
| 1023 | } |
| 1024 | |
| 1025 | /* |
| 1026 | ** TH1 command: setting name |
| @@ -1691,11 +1691,11 @@ | |
| 1691 | } |
| 1692 | #endif |
| 1693 | |
| 1694 | /* |
| 1695 | ** The z[] input contains text mixed with TH1 scripts. |
| 1696 | ** The TH1 scripts are contained within <th1>...</th1>. |
| 1697 | ** TH1 variables are $aaa or $<aaa>. The first form of |
| 1698 | ** variable is literal. The second is run through htmlize |
| 1699 | ** before being inserted. |
| 1700 | ** |
| 1701 | ** This routine processes the template and writes the results |
| 1702 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -145,14 +145,14 @@ | |
| 145 | ** |
| 146 | ** Escape all characters of STRING which have special meaning in URI |
| 147 | ** components. Return a new string result. |
| 148 | */ |
| 149 | static int httpizeCmd( |
| 150 | Th_Interp *interp, |
| 151 | void *p, |
| 152 | int argc, |
| 153 | const char **argv, |
| 154 | int *argl |
| 155 | ){ |
| 156 | char *zOut; |
| 157 | if( argc!=2 ){ |
| 158 | return Th_WrongNumArgs(interp, "httpize STRING"); |
| @@ -172,14 +172,14 @@ | |
| 172 | ** TH1 command: enable_output BOOLEAN |
| 173 | ** |
| 174 | ** Enable or disable the puts and hputs commands. |
| 175 | */ |
| 176 | static int enableOutputCmd( |
| 177 | Th_Interp *interp, |
| 178 | void *p, |
| 179 | int argc, |
| 180 | const char **argv, |
| 181 | int *argl |
| 182 | ){ |
| 183 | int rc; |
| 184 | if( argc<2 || argc>3 ){ |
| 185 | return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN"); |
| @@ -245,17 +245,17 @@ | |
| 245 | |
| 246 | /* |
| 247 | ** TH1 command: puts STRING |
| 248 | ** TH1 command: html STRING |
| 249 | ** |
| 250 | ** Output STRING escaped for HTML (html) or unchanged (puts). |
| 251 | */ |
| 252 | static int putsCmd( |
| 253 | Th_Interp *interp, |
| 254 | void *pConvert, |
| 255 | int argc, |
| 256 | const char **argv, |
| 257 | int *argl |
| 258 | ){ |
| 259 | if( argc!=2 ){ |
| 260 | return Th_WrongNumArgs(interp, "puts STRING"); |
| 261 | } |
| @@ -267,14 +267,14 @@ | |
| 267 | ** TH1 command: wiki STRING |
| 268 | ** |
| 269 | ** Render the input string as wiki. |
| 270 | */ |
| 271 | static int wikiCmd( |
| 272 | Th_Interp *interp, |
| 273 | void *p, |
| 274 | int argc, |
| 275 | const char **argv, |
| 276 | int *argl |
| 277 | ){ |
| 278 | int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p; |
| 279 | if( argc!=2 ){ |
| 280 | return Th_WrongNumArgs(interp, "wiki STRING"); |
| @@ -293,14 +293,14 @@ | |
| 293 | ** |
| 294 | ** Escape all characters of STRING which have special meaning in HTML. |
| 295 | ** Return a new string result. |
| 296 | */ |
| 297 | static int htmlizeCmd( |
| 298 | Th_Interp *interp, |
| 299 | void *p, |
| 300 | int argc, |
| 301 | const char **argv, |
| 302 | int *argl |
| 303 | ){ |
| 304 | char *zOut; |
| 305 | if( argc!=2 ){ |
| 306 | return Th_WrongNumArgs(interp, "htmlize STRING"); |
| @@ -317,14 +317,14 @@ | |
| 317 | ** Return a string which is the current time and date. If the |
| 318 | ** -local option is used, the date appears using localtime instead |
| 319 | ** of UTC. |
| 320 | */ |
| 321 | static int dateCmd( |
| 322 | Th_Interp *interp, |
| 323 | void *p, |
| 324 | int argc, |
| 325 | const char **argv, |
| 326 | int *argl |
| 327 | ){ |
| 328 | char *zOut; |
| 329 | if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){ |
| 330 | zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc()); |
| @@ -340,14 +340,14 @@ | |
| 340 | ** TH1 command: hascap STRING... |
| 341 | ** |
| 342 | ** Return true if the user has all of the capabilities listed in STRING. |
| 343 | */ |
| 344 | static int hascapCmd( |
| 345 | Th_Interp *interp, |
| 346 | void *p, |
| 347 | int argc, |
| 348 | const char **argv, |
| 349 | int *argl |
| 350 | ){ |
| 351 | int rc = 0, i; |
| 352 | if( argc<2 ){ |
| 353 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| @@ -377,14 +377,14 @@ | |
| 377 | ** "json" = FOSSIL_ENABLE_JSON |
| 378 | ** "markdown" = FOSSIL_ENABLE_MARKDOWN |
| 379 | ** |
| 380 | */ |
| 381 | static int hasfeatureCmd( |
| 382 | Th_Interp *interp, |
| 383 | void *p, |
| 384 | int argc, |
| 385 | const char **argv, |
| 386 | int *argl |
| 387 | ){ |
| 388 | int rc = 0; |
| 389 | char const * zArg; |
| 390 | if( argc!=2 ){ |
| @@ -475,14 +475,14 @@ | |
| 475 | ** TH1 command: anycap STRING |
| 476 | ** |
| 477 | ** Return true if the user has any one of the capabilities listed in STRING. |
| 478 | */ |
| 479 | static int anycapCmd( |
| 480 | Th_Interp *interp, |
| 481 | void *p, |
| 482 | int argc, |
| 483 | const char **argv, |
| 484 | int *argl |
| 485 | ){ |
| 486 | int rc = 0; |
| 487 | int i; |
| 488 | if( argc!=2 ){ |
| @@ -508,13 +508,13 @@ | |
| 508 | ** If NUMLINES is greater than one then the display is a listbox |
| 509 | ** with the number of lines given. |
| 510 | */ |
| 511 | static int comboboxCmd( |
| 512 | Th_Interp *interp, |
| 513 | void *p, |
| 514 | int argc, |
| 515 | const char **argv, |
| 516 | int *argl |
| 517 | ){ |
| 518 | if( argc!=4 ){ |
| 519 | return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES"); |
| 520 | } |
| @@ -539,11 +539,11 @@ | |
| 539 | sendText(z, -1, 0); |
| 540 | free(z); |
| 541 | blob_reset(&name); |
| 542 | for(i=0; i<nElem; i++){ |
| 543 | zH = htmlize((char*)azElem[i], aszElem[i]); |
| 544 | if( zValue && aszElem[i]==nValue |
| 545 | && memcmp(zValue, azElem[i], nValue)==0 ){ |
| 546 | z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", |
| 547 | zH, zH); |
| 548 | }else{ |
| 549 | z = mprintf("<option value=\"%s\">%s</option>", zH, zH); |
| @@ -564,13 +564,13 @@ | |
| 564 | ** Return one more than the number of \n characters in STRING. But |
| 565 | ** never return less than MIN or more than MAX. |
| 566 | */ |
| 567 | static int linecntCmd( |
| 568 | Th_Interp *interp, |
| 569 | void *p, |
| 570 | int argc, |
| 571 | const char **argv, |
| 572 | int *argl |
| 573 | ){ |
| 574 | const char *z; |
| 575 | int size, n, i; |
| 576 | int iMin, iMax; |
| @@ -600,13 +600,13 @@ | |
| 600 | ** string if one is not currently open. Optionally, it will attempt to open |
| 601 | ** the repository if the boolean argument is non-zero. |
| 602 | */ |
| 603 | static int repositoryCmd( |
| 604 | Th_Interp *interp, |
| 605 | void *p, |
| 606 | int argc, |
| 607 | const char **argv, |
| 608 | int *argl |
| 609 | ){ |
| 610 | if( argc!=1 && argc!=2 ){ |
| 611 | return Th_WrongNumArgs(interp, "repository ?BOOLEAN?"); |
| 612 | } |
| @@ -855,11 +855,11 @@ | |
| 855 | getrusage(RUSAGE_SELF, &s); |
| 856 | if( piUser ){ |
| 857 | *piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec; |
| 858 | } |
| 859 | if( piKernel ){ |
| 860 | *piKernel = |
| 861 | ((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec; |
| 862 | } |
| 863 | #endif |
| 864 | } |
| 865 | |
| @@ -869,13 +869,13 @@ | |
| 869 | ** Return the number of microseconds of CPU time consumed by the current |
| 870 | ** process in user space. |
| 871 | */ |
| 872 | static int utimeCmd( |
| 873 | Th_Interp *interp, |
| 874 | void *p, |
| 875 | int argc, |
| 876 | const char **argv, |
| 877 | int *argl |
| 878 | ){ |
| 879 | sqlite3_uint64 x; |
| 880 | char zUTime[50]; |
| 881 | getCpuTimes(&x, 0); |
| @@ -890,13 +890,13 @@ | |
| 890 | ** Return the number of microseconds of CPU time consumed by the current |
| 891 | ** process in system space. |
| 892 | */ |
| 893 | static int stimeCmd( |
| 894 | Th_Interp *interp, |
| 895 | void *p, |
| 896 | int argc, |
| 897 | const char **argv, |
| 898 | int *argl |
| 899 | ){ |
| 900 | sqlite3_uint64 x; |
| 901 | char zUTime[50]; |
| 902 | getCpuTimes(0, &x); |
| @@ -907,18 +907,18 @@ | |
| 907 | |
| 908 | |
| 909 | /* |
| 910 | ** TH1 command: randhex N |
| 911 | ** |
| 912 | ** Return N*2 random hexadecimal digits with N<50. If N is omitted, |
| 913 | ** use a value of 10. |
| 914 | */ |
| 915 | static int randhexCmd( |
| 916 | Th_Interp *interp, |
| 917 | void *p, |
| 918 | int argc, |
| 919 | const char **argv, |
| 920 | int *argl |
| 921 | ){ |
| 922 | int n; |
| 923 | unsigned char aRand[50]; |
| 924 | unsigned char zOut[100]; |
| @@ -950,13 +950,13 @@ | |
| 950 | ** "var". Result values are stored in variables with the column name prior |
| 951 | ** to each invocation of CODE. |
| 952 | */ |
| 953 | static int queryCmd( |
| 954 | Th_Interp *interp, |
| 955 | void *p, |
| 956 | int argc, |
| 957 | const char **argv, |
| 958 | int *argl |
| 959 | ){ |
| 960 | sqlite3_stmt *pStmt; |
| 961 | int rc; |
| 962 | const char *zSql; |
| @@ -1016,11 +1016,11 @@ | |
| 1016 | rc = sqlite3_finalize(pStmt); |
| 1017 | if( rc!=SQLITE_OK ){ |
| 1018 | Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1); |
| 1019 | return TH_ERROR; |
| 1020 | } |
| 1021 | } |
| 1022 | return res; |
| 1023 | } |
| 1024 | |
| 1025 | /* |
| 1026 | ** TH1 command: setting name |
| @@ -1691,11 +1691,11 @@ | |
| 1691 | } |
| 1692 | #endif |
| 1693 | |
| 1694 | /* |
| 1695 | ** The z[] input contains text mixed with TH1 scripts. |
| 1696 | ** The TH1 scripts are contained within <th1>...</th1>. |
| 1697 | ** TH1 variables are $aaa or $<aaa>. The first form of |
| 1698 | ** variable is literal. The second is run through htmlize |
| 1699 | ** before being inserted. |
| 1700 | ** |
| 1701 | ** This routine processes the template and writes the results |
| 1702 |
+22
-33
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -20,41 +20,19 @@ | ||
| 20 | 20 | */ |
| 21 | 21 | #include "config.h" |
| 22 | 22 | #include <string.h> |
| 23 | 23 | #include <time.h> |
| 24 | 24 | #include "timeline.h" |
| 25 | - | |
| 26 | -/* | |
| 27 | -** Shorten a UUID so that is the minimum length needed to contain | |
| 28 | -** at least one digit in the range 'a'..'f'. The minimum length is 10. | |
| 29 | -*/ | |
| 30 | -static void shorten_uuid(char *zDest, const char *zSrc){ | |
| 31 | - int i; | |
| 32 | - for(i=0; i<10 && zSrc[i]<='9'; i++){} | |
| 33 | - memcpy(zDest, zSrc, 10); | |
| 34 | - if( i==10 && zSrc[i] ){ | |
| 35 | - do{ | |
| 36 | - zDest[i] = zSrc[i]; | |
| 37 | - i++; | |
| 38 | - }while( zSrc[i-1]<='9' ); | |
| 39 | - }else{ | |
| 40 | - i = 10; | |
| 41 | - } | |
| 42 | - zDest[i] = 0; | |
| 43 | -} | |
| 44 | - | |
| 45 | 25 | |
| 46 | 26 | /* |
| 47 | 27 | ** Generate a hyperlink to a version. |
| 48 | 28 | */ |
| 49 | 29 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | - char z[UUID_SIZE+1]; | |
| 51 | - shorten_uuid(z, zUuid); | |
| 52 | 30 | if( g.perm.Hyperlink ){ |
| 53 | - @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%s(z)]</a> | |
| 31 | + @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%S(zUuid)]</a> | |
| 54 | 32 | }else{ |
| 55 | - @ <span class="timelineHistDsp">[%s(z)]</span> | |
| 33 | + @ <span class="timelineHistDsp">[%S(zUuid)]</span> | |
| 56 | 34 | } |
| 57 | 35 | } |
| 58 | 36 | |
| 59 | 37 | /* |
| 60 | 38 | ** Generate a hyperlink to a date & time. |
| @@ -1018,19 +996,20 @@ | ||
| 1018 | 996 | ** d=UUID artifact and up to COUNT descendants |
| 1019 | 997 | ** dp=UUID The same as d=UUID&p=UUID |
| 1020 | 998 | ** t=TAGID show only check-ins with the given tagid |
| 1021 | 999 | ** r=TAGID show check-ins related to tagid |
| 1022 | 1000 | ** u=USER only if belonging to this user |
| 1023 | -** y=TYPE 'ci', 'w', 't', 'e' | |
| 1001 | +** y=TYPE 'ci', 'w', 't', 'e', or (default) 'all' | |
| 1024 | 1002 | ** s=TEXT string search (comment and brief) |
| 1025 | 1003 | ** ng Suppress the graph if present |
| 1026 | 1004 | ** nd Suppress "divider" lines |
| 1027 | 1005 | ** v Show details of files changed |
| 1028 | 1006 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1029 | 1007 | ** from=UUID Path from... |
| 1030 | 1008 | ** to=UUID ... to this |
| 1031 | 1009 | ** nomerge ... avoid merge links on the path |
| 1010 | +** shortest ... show only the shortest path | |
| 1032 | 1011 | ** uf=FUUID Show only checkins that use given file version |
| 1033 | 1012 | ** brbg Background color from branch name |
| 1034 | 1013 | ** ubg Background color from user |
| 1035 | 1014 | ** namechng Show only checkins that filename changes |
| 1036 | 1015 | ** ym=YYYY-MM Shown only events for the given year/month. |
| @@ -1220,11 +1199,11 @@ | ||
| 1220 | 1199 | blob_appendf(&desc, "%d ancestors", np); |
| 1221 | 1200 | db_multi_exec("%s", blob_str(&sql)); |
| 1222 | 1201 | } |
| 1223 | 1202 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1224 | 1203 | } |
| 1225 | - blob_appendf(&desc, " of %z[%.10s]</a>", | |
| 1204 | + blob_appendf(&desc, " of %z[%S]</a>", | |
| 1226 | 1205 | href("%R/info/%s", zUuid), zUuid); |
| 1227 | 1206 | if( p_rid ){ |
| 1228 | 1207 | url_add_parameter(&url, "p", zUuid); |
| 1229 | 1208 | } |
| 1230 | 1209 | if( d_rid ){ |
| @@ -1261,11 +1240,11 @@ | ||
| 1261 | 1240 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1262 | 1241 | db_multi_exec("%s", blob_str(&sql)); |
| 1263 | 1242 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1264 | 1243 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1265 | 1244 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1266 | - blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid); | |
| 1245 | + blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid); | |
| 1267 | 1246 | tmFlags |= TIMELINE_DISJOINT; |
| 1268 | 1247 | url_add_parameter(&url, "f", zUuid); |
| 1269 | 1248 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1270 | 1249 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1271 | 1250 | }else{ |
| @@ -1587,11 +1566,10 @@ | ||
| 1587 | 1566 | int nChild = db_column_int(q, 4); |
| 1588 | 1567 | int nParent = db_column_int(q, 5); |
| 1589 | 1568 | char *zFree = 0; |
| 1590 | 1569 | int n = 0; |
| 1591 | 1570 | char zPrefix[80]; |
| 1592 | - char zUuid[UUID_SIZE+1]; | |
| 1593 | 1571 | |
| 1594 | 1572 | if( nAbsLimit!=0 ){ |
| 1595 | 1573 | if( nLimit<0 && nLine>=nAbsLimit ){ |
| 1596 | 1574 | fossil_print("--- line limit (%d) reached ---\n", nAbsLimit); |
| 1597 | 1575 | break; /* line count limit hit, stop. */ |
| @@ -1598,11 +1576,10 @@ | ||
| 1598 | 1576 | }else if( nEntry>=nAbsLimit ){ |
| 1599 | 1577 | fossil_print("--- entry limit (%d) reached ---\n", nAbsLimit); |
| 1600 | 1578 | break; /* entry count limit hit, stop. */ |
| 1601 | 1579 | } |
| 1602 | 1580 | } |
| 1603 | - sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); | |
| 1604 | 1581 | if( fossil_strnicmp(zDate, zPrevDate, 10) ){ |
| 1605 | 1582 | fossil_print("=== %.10s ===\n", zDate); |
| 1606 | 1583 | memcpy(zPrevDate, zDate, 10); |
| 1607 | 1584 | nLine++; /* record another line */ |
| 1608 | 1585 | } |
| @@ -1625,13 +1602,14 @@ | ||
| 1625 | 1602 | } |
| 1626 | 1603 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1627 | 1604 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1628 | 1605 | n += strlen(zPrefix); |
| 1629 | 1606 | } |
| 1630 | - zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom); | |
| 1631 | - nLine += comment_print(zFree, 9, width); /* record another X lines */ | |
| 1632 | - sqlite3_free(zFree); | |
| 1607 | + zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom); | |
| 1608 | + /* record another X lines */ | |
| 1609 | + nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags); | |
| 1610 | + fossil_free(zFree); | |
| 1633 | 1611 | |
| 1634 | 1612 | if(verboseFlag){ |
| 1635 | 1613 | if( !fchngQueryInit ){ |
| 1636 | 1614 | db_prepare(&fchngQuery, |
| 1637 | 1615 | "SELECT (pid==0) AS isnew," |
| @@ -1801,10 +1779,14 @@ | ||
| 1801 | 1779 | }else{ |
| 1802 | 1780 | width = -1; |
| 1803 | 1781 | } |
| 1804 | 1782 | zOffset = find_option("offset",0,1); |
| 1805 | 1783 | iOffset = zOffset ? atoi(zOffset) : 0; |
| 1784 | + | |
| 1785 | + /* We should be done with options.. */ | |
| 1786 | + verify_all_options(); | |
| 1787 | + | |
| 1806 | 1788 | if( g.argc>=4 ){ |
| 1807 | 1789 | k = strlen(g.argv[2]); |
| 1808 | 1790 | if( strncmp(g.argv[2],"before",k)==0 ){ |
| 1809 | 1791 | mode = 1; |
| 1810 | 1792 | }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){ |
| @@ -2067,10 +2049,12 @@ | ||
| 2067 | 2049 | static const char * stats_report_label_for_type(){ |
| 2068 | 2050 | assert( statsReportType && "Must call stats_report_init_view() first." ); |
| 2069 | 2051 | switch( statsReportType ){ |
| 2070 | 2052 | case 'c': |
| 2071 | 2053 | return "checkins"; |
| 2054 | + case 'e': | |
| 2055 | + return "events"; | |
| 2072 | 2056 | case 'w': |
| 2073 | 2057 | return "wiki changes"; |
| 2074 | 2058 | case 't': |
| 2075 | 2059 | return "ticket changes"; |
| 2076 | 2060 | case 'g': |
| @@ -2096,11 +2080,11 @@ | ||
| 2096 | 2080 | zParam = NULL; |
| 2097 | 2081 | } |
| 2098 | 2082 | zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName, |
| 2099 | 2083 | zParam ? "&" : "", zParam); |
| 2100 | 2084 | cgi_printf("<div>"); |
| 2101 | - cgi_printf("<span>Event types:</span> "); | |
| 2085 | + cgi_printf("<span>Types:</span> "); | |
| 2102 | 2086 | if('*' == statsReportType){ |
| 2103 | 2087 | cgi_printf(" <strong>all</strong>", zTop); |
| 2104 | 2088 | }else{ |
| 2105 | 2089 | cgi_printf(" <a href='%s'>all</a>", zTop); |
| 2106 | 2090 | } |
| @@ -2107,10 +2091,15 @@ | ||
| 2107 | 2091 | if('c' == statsReportType){ |
| 2108 | 2092 | cgi_printf(" <strong>checkins</strong>", zTop); |
| 2109 | 2093 | }else{ |
| 2110 | 2094 | cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop); |
| 2111 | 2095 | } |
| 2096 | + if('e' == statsReportType){ | |
| 2097 | + cgi_printf(" <strong>events</strong>", zTop); | |
| 2098 | + }else{ | |
| 2099 | + cgi_printf(" <a href='%s&type=e'>events</a>", zTop); | |
| 2100 | + } | |
| 2112 | 2101 | if( 't' == statsReportType ){ |
| 2113 | 2102 | cgi_printf(" <strong>tickets</strong>", zTop); |
| 2114 | 2103 | }else{ |
| 2115 | 2104 | cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop); |
| 2116 | 2105 | } |
| 2117 | 2106 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,41 +20,19 @@ | |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #include <string.h> |
| 23 | #include <time.h> |
| 24 | #include "timeline.h" |
| 25 | |
| 26 | /* |
| 27 | ** Shorten a UUID so that is the minimum length needed to contain |
| 28 | ** at least one digit in the range 'a'..'f'. The minimum length is 10. |
| 29 | */ |
| 30 | static void shorten_uuid(char *zDest, const char *zSrc){ |
| 31 | int i; |
| 32 | for(i=0; i<10 && zSrc[i]<='9'; i++){} |
| 33 | memcpy(zDest, zSrc, 10); |
| 34 | if( i==10 && zSrc[i] ){ |
| 35 | do{ |
| 36 | zDest[i] = zSrc[i]; |
| 37 | i++; |
| 38 | }while( zSrc[i-1]<='9' ); |
| 39 | }else{ |
| 40 | i = 10; |
| 41 | } |
| 42 | zDest[i] = 0; |
| 43 | } |
| 44 | |
| 45 | |
| 46 | /* |
| 47 | ** Generate a hyperlink to a version. |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char z[UUID_SIZE+1]; |
| 51 | shorten_uuid(z, zUuid); |
| 52 | if( g.perm.Hyperlink ){ |
| 53 | @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%s(z)]</a> |
| 54 | }else{ |
| 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink to a date & time. |
| @@ -1018,19 +996,20 @@ | |
| 1018 | ** d=UUID artifact and up to COUNT descendants |
| 1019 | ** dp=UUID The same as d=UUID&p=UUID |
| 1020 | ** t=TAGID show only check-ins with the given tagid |
| 1021 | ** r=TAGID show check-ins related to tagid |
| 1022 | ** u=USER only if belonging to this user |
| 1023 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 1024 | ** s=TEXT string search (comment and brief) |
| 1025 | ** ng Suppress the graph if present |
| 1026 | ** nd Suppress "divider" lines |
| 1027 | ** v Show details of files changed |
| 1028 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1029 | ** from=UUID Path from... |
| 1030 | ** to=UUID ... to this |
| 1031 | ** nomerge ... avoid merge links on the path |
| 1032 | ** uf=FUUID Show only checkins that use given file version |
| 1033 | ** brbg Background color from branch name |
| 1034 | ** ubg Background color from user |
| 1035 | ** namechng Show only checkins that filename changes |
| 1036 | ** ym=YYYY-MM Shown only events for the given year/month. |
| @@ -1220,11 +1199,11 @@ | |
| 1220 | blob_appendf(&desc, "%d ancestors", np); |
| 1221 | db_multi_exec("%s", blob_str(&sql)); |
| 1222 | } |
| 1223 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1224 | } |
| 1225 | blob_appendf(&desc, " of %z[%.10s]</a>", |
| 1226 | href("%R/info/%s", zUuid), zUuid); |
| 1227 | if( p_rid ){ |
| 1228 | url_add_parameter(&url, "p", zUuid); |
| 1229 | } |
| 1230 | if( d_rid ){ |
| @@ -1261,11 +1240,11 @@ | |
| 1261 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1262 | db_multi_exec("%s", blob_str(&sql)); |
| 1263 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1264 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1265 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1266 | blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1267 | tmFlags |= TIMELINE_DISJOINT; |
| 1268 | url_add_parameter(&url, "f", zUuid); |
| 1269 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1270 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1271 | }else{ |
| @@ -1587,11 +1566,10 @@ | |
| 1587 | int nChild = db_column_int(q, 4); |
| 1588 | int nParent = db_column_int(q, 5); |
| 1589 | char *zFree = 0; |
| 1590 | int n = 0; |
| 1591 | char zPrefix[80]; |
| 1592 | char zUuid[UUID_SIZE+1]; |
| 1593 | |
| 1594 | if( nAbsLimit!=0 ){ |
| 1595 | if( nLimit<0 && nLine>=nAbsLimit ){ |
| 1596 | fossil_print("--- line limit (%d) reached ---\n", nAbsLimit); |
| 1597 | break; /* line count limit hit, stop. */ |
| @@ -1598,11 +1576,10 @@ | |
| 1598 | }else if( nEntry>=nAbsLimit ){ |
| 1599 | fossil_print("--- entry limit (%d) reached ---\n", nAbsLimit); |
| 1600 | break; /* entry count limit hit, stop. */ |
| 1601 | } |
| 1602 | } |
| 1603 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1604 | if( fossil_strnicmp(zDate, zPrevDate, 10) ){ |
| 1605 | fossil_print("=== %.10s ===\n", zDate); |
| 1606 | memcpy(zPrevDate, zDate, 10); |
| 1607 | nLine++; /* record another line */ |
| 1608 | } |
| @@ -1625,13 +1602,14 @@ | |
| 1625 | } |
| 1626 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1627 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1628 | n += strlen(zPrefix); |
| 1629 | } |
| 1630 | zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom); |
| 1631 | nLine += comment_print(zFree, 9, width); /* record another X lines */ |
| 1632 | sqlite3_free(zFree); |
| 1633 | |
| 1634 | if(verboseFlag){ |
| 1635 | if( !fchngQueryInit ){ |
| 1636 | db_prepare(&fchngQuery, |
| 1637 | "SELECT (pid==0) AS isnew," |
| @@ -1801,10 +1779,14 @@ | |
| 1801 | }else{ |
| 1802 | width = -1; |
| 1803 | } |
| 1804 | zOffset = find_option("offset",0,1); |
| 1805 | iOffset = zOffset ? atoi(zOffset) : 0; |
| 1806 | if( g.argc>=4 ){ |
| 1807 | k = strlen(g.argv[2]); |
| 1808 | if( strncmp(g.argv[2],"before",k)==0 ){ |
| 1809 | mode = 1; |
| 1810 | }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){ |
| @@ -2067,10 +2049,12 @@ | |
| 2067 | static const char * stats_report_label_for_type(){ |
| 2068 | assert( statsReportType && "Must call stats_report_init_view() first." ); |
| 2069 | switch( statsReportType ){ |
| 2070 | case 'c': |
| 2071 | return "checkins"; |
| 2072 | case 'w': |
| 2073 | return "wiki changes"; |
| 2074 | case 't': |
| 2075 | return "ticket changes"; |
| 2076 | case 'g': |
| @@ -2096,11 +2080,11 @@ | |
| 2096 | zParam = NULL; |
| 2097 | } |
| 2098 | zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName, |
| 2099 | zParam ? "&" : "", zParam); |
| 2100 | cgi_printf("<div>"); |
| 2101 | cgi_printf("<span>Event types:</span> "); |
| 2102 | if('*' == statsReportType){ |
| 2103 | cgi_printf(" <strong>all</strong>", zTop); |
| 2104 | }else{ |
| 2105 | cgi_printf(" <a href='%s'>all</a>", zTop); |
| 2106 | } |
| @@ -2107,10 +2091,15 @@ | |
| 2107 | if('c' == statsReportType){ |
| 2108 | cgi_printf(" <strong>checkins</strong>", zTop); |
| 2109 | }else{ |
| 2110 | cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop); |
| 2111 | } |
| 2112 | if( 't' == statsReportType ){ |
| 2113 | cgi_printf(" <strong>tickets</strong>", zTop); |
| 2114 | }else{ |
| 2115 | cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop); |
| 2116 | } |
| 2117 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,41 +20,19 @@ | |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #include <string.h> |
| 23 | #include <time.h> |
| 24 | #include "timeline.h" |
| 25 | |
| 26 | /* |
| 27 | ** Generate a hyperlink to a version. |
| 28 | */ |
| 29 | void hyperlink_to_uuid(const char *zUuid){ |
| 30 | if( g.perm.Hyperlink ){ |
| 31 | @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%S(zUuid)]</a> |
| 32 | }else{ |
| 33 | @ <span class="timelineHistDsp">[%S(zUuid)]</span> |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | /* |
| 38 | ** Generate a hyperlink to a date & time. |
| @@ -1018,19 +996,20 @@ | |
| 996 | ** d=UUID artifact and up to COUNT descendants |
| 997 | ** dp=UUID The same as d=UUID&p=UUID |
| 998 | ** t=TAGID show only check-ins with the given tagid |
| 999 | ** r=TAGID show check-ins related to tagid |
| 1000 | ** u=USER only if belonging to this user |
| 1001 | ** y=TYPE 'ci', 'w', 't', 'e', or (default) 'all' |
| 1002 | ** s=TEXT string search (comment and brief) |
| 1003 | ** ng Suppress the graph if present |
| 1004 | ** nd Suppress "divider" lines |
| 1005 | ** v Show details of files changed |
| 1006 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1007 | ** from=UUID Path from... |
| 1008 | ** to=UUID ... to this |
| 1009 | ** nomerge ... avoid merge links on the path |
| 1010 | ** shortest ... show only the shortest path |
| 1011 | ** uf=FUUID Show only checkins that use given file version |
| 1012 | ** brbg Background color from branch name |
| 1013 | ** ubg Background color from user |
| 1014 | ** namechng Show only checkins that filename changes |
| 1015 | ** ym=YYYY-MM Shown only events for the given year/month. |
| @@ -1220,11 +1199,11 @@ | |
| 1199 | blob_appendf(&desc, "%d ancestors", np); |
| 1200 | db_multi_exec("%s", blob_str(&sql)); |
| 1201 | } |
| 1202 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1203 | } |
| 1204 | blob_appendf(&desc, " of %z[%S]</a>", |
| 1205 | href("%R/info/%s", zUuid), zUuid); |
| 1206 | if( p_rid ){ |
| 1207 | url_add_parameter(&url, "p", zUuid); |
| 1208 | } |
| 1209 | if( d_rid ){ |
| @@ -1261,11 +1240,11 @@ | |
| 1240 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1241 | db_multi_exec("%s", blob_str(&sql)); |
| 1242 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1243 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1244 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1245 | blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1246 | tmFlags |= TIMELINE_DISJOINT; |
| 1247 | url_add_parameter(&url, "f", zUuid); |
| 1248 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1249 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1250 | }else{ |
| @@ -1587,11 +1566,10 @@ | |
| 1566 | int nChild = db_column_int(q, 4); |
| 1567 | int nParent = db_column_int(q, 5); |
| 1568 | char *zFree = 0; |
| 1569 | int n = 0; |
| 1570 | char zPrefix[80]; |
| 1571 | |
| 1572 | if( nAbsLimit!=0 ){ |
| 1573 | if( nLimit<0 && nLine>=nAbsLimit ){ |
| 1574 | fossil_print("--- line limit (%d) reached ---\n", nAbsLimit); |
| 1575 | break; /* line count limit hit, stop. */ |
| @@ -1598,11 +1576,10 @@ | |
| 1576 | }else if( nEntry>=nAbsLimit ){ |
| 1577 | fossil_print("--- entry limit (%d) reached ---\n", nAbsLimit); |
| 1578 | break; /* entry count limit hit, stop. */ |
| 1579 | } |
| 1580 | } |
| 1581 | if( fossil_strnicmp(zDate, zPrevDate, 10) ){ |
| 1582 | fossil_print("=== %.10s ===\n", zDate); |
| 1583 | memcpy(zPrevDate, zDate, 10); |
| 1584 | nLine++; /* record another line */ |
| 1585 | } |
| @@ -1625,13 +1602,14 @@ | |
| 1602 | } |
| 1603 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1604 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1605 | n += strlen(zPrefix); |
| 1606 | } |
| 1607 | zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom); |
| 1608 | /* record another X lines */ |
| 1609 | nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags); |
| 1610 | fossil_free(zFree); |
| 1611 | |
| 1612 | if(verboseFlag){ |
| 1613 | if( !fchngQueryInit ){ |
| 1614 | db_prepare(&fchngQuery, |
| 1615 | "SELECT (pid==0) AS isnew," |
| @@ -1801,10 +1779,14 @@ | |
| 1779 | }else{ |
| 1780 | width = -1; |
| 1781 | } |
| 1782 | zOffset = find_option("offset",0,1); |
| 1783 | iOffset = zOffset ? atoi(zOffset) : 0; |
| 1784 | |
| 1785 | /* We should be done with options.. */ |
| 1786 | verify_all_options(); |
| 1787 | |
| 1788 | if( g.argc>=4 ){ |
| 1789 | k = strlen(g.argv[2]); |
| 1790 | if( strncmp(g.argv[2],"before",k)==0 ){ |
| 1791 | mode = 1; |
| 1792 | }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){ |
| @@ -2067,10 +2049,12 @@ | |
| 2049 | static const char * stats_report_label_for_type(){ |
| 2050 | assert( statsReportType && "Must call stats_report_init_view() first." ); |
| 2051 | switch( statsReportType ){ |
| 2052 | case 'c': |
| 2053 | return "checkins"; |
| 2054 | case 'e': |
| 2055 | return "events"; |
| 2056 | case 'w': |
| 2057 | return "wiki changes"; |
| 2058 | case 't': |
| 2059 | return "ticket changes"; |
| 2060 | case 'g': |
| @@ -2096,11 +2080,11 @@ | |
| 2080 | zParam = NULL; |
| 2081 | } |
| 2082 | zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName, |
| 2083 | zParam ? "&" : "", zParam); |
| 2084 | cgi_printf("<div>"); |
| 2085 | cgi_printf("<span>Types:</span> "); |
| 2086 | if('*' == statsReportType){ |
| 2087 | cgi_printf(" <strong>all</strong>", zTop); |
| 2088 | }else{ |
| 2089 | cgi_printf(" <a href='%s'>all</a>", zTop); |
| 2090 | } |
| @@ -2107,10 +2091,15 @@ | |
| 2091 | if('c' == statsReportType){ |
| 2092 | cgi_printf(" <strong>checkins</strong>", zTop); |
| 2093 | }else{ |
| 2094 | cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop); |
| 2095 | } |
| 2096 | if('e' == statsReportType){ |
| 2097 | cgi_printf(" <strong>events</strong>", zTop); |
| 2098 | }else{ |
| 2099 | cgi_printf(" <a href='%s&type=e'>events</a>", zTop); |
| 2100 | } |
| 2101 | if( 't' == statsReportType ){ |
| 2102 | cgi_printf(" <strong>tickets</strong>", zTop); |
| 2103 | }else{ |
| 2104 | cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop); |
| 2105 | } |
| 2106 |
+3
-3
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -943,20 +943,20 @@ | ||
| 943 | 943 | }else{ |
| 944 | 944 | @ |
| 945 | 945 | @ <li><p>Add attachment |
| 946 | 946 | @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>" |
| 947 | 947 | } |
| 948 | - @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] | |
| 948 | + @ [%z(href("%R/artifact/%s",zChngUuid))%S(zChngUuid)</a>] | |
| 949 | 949 | @ (rid %d(rid)) by |
| 950 | 950 | hyperlink_to_user(zUser,zDate," on"); |
| 951 | 951 | hyperlink_to_date(zDate, ".</p>"); |
| 952 | 952 | }else{ |
| 953 | 953 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 954 | 954 | if( pTicket ){ |
| 955 | 955 | @ |
| 956 | 956 | @ <li><p>Ticket change |
| 957 | - @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] | |
| 957 | + @ [%z(href("%R/artifact/%s",zChngUuid))%S(zChngUuid)</a>] | |
| 958 | 958 | @ (rid %d(rid)) by |
| 959 | 959 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 960 | 960 | hyperlink_to_date(zDate, ":"); |
| 961 | 961 | @ </p> |
| 962 | 962 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1264,11 +1264,11 @@ | ||
| 1264 | 1264 | fossil_print(" Change "); |
| 1265 | 1265 | } |
| 1266 | 1266 | fossil_print("%h: ",z); |
| 1267 | 1267 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1268 | 1268 | fossil_print("\n ",blob_str(&val)); |
| 1269 | - comment_print(blob_str(&val),4,-1); | |
| 1269 | + comment_print(blob_str(&val),0,4,-1,g.comFmtFlags); | |
| 1270 | 1270 | }else{ |
| 1271 | 1271 | fossil_print("%s\n",blob_str(&val)); |
| 1272 | 1272 | } |
| 1273 | 1273 | blob_reset(&val); |
| 1274 | 1274 | } |
| 1275 | 1275 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -943,20 +943,20 @@ | |
| 943 | }else{ |
| 944 | @ |
| 945 | @ <li><p>Add attachment |
| 946 | @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>" |
| 947 | } |
| 948 | @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] |
| 949 | @ (rid %d(rid)) by |
| 950 | hyperlink_to_user(zUser,zDate," on"); |
| 951 | hyperlink_to_date(zDate, ".</p>"); |
| 952 | }else{ |
| 953 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 954 | if( pTicket ){ |
| 955 | @ |
| 956 | @ <li><p>Ticket change |
| 957 | @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] |
| 958 | @ (rid %d(rid)) by |
| 959 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 960 | hyperlink_to_date(zDate, ":"); |
| 961 | @ </p> |
| 962 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1264,11 +1264,11 @@ | |
| 1264 | fossil_print(" Change "); |
| 1265 | } |
| 1266 | fossil_print("%h: ",z); |
| 1267 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1268 | fossil_print("\n ",blob_str(&val)); |
| 1269 | comment_print(blob_str(&val),4,-1); |
| 1270 | }else{ |
| 1271 | fossil_print("%s\n",blob_str(&val)); |
| 1272 | } |
| 1273 | blob_reset(&val); |
| 1274 | } |
| 1275 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -943,20 +943,20 @@ | |
| 943 | }else{ |
| 944 | @ |
| 945 | @ <li><p>Add attachment |
| 946 | @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>" |
| 947 | } |
| 948 | @ [%z(href("%R/artifact/%s",zChngUuid))%S(zChngUuid)</a>] |
| 949 | @ (rid %d(rid)) by |
| 950 | hyperlink_to_user(zUser,zDate," on"); |
| 951 | hyperlink_to_date(zDate, ".</p>"); |
| 952 | }else{ |
| 953 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 954 | if( pTicket ){ |
| 955 | @ |
| 956 | @ <li><p>Ticket change |
| 957 | @ [%z(href("%R/artifact/%s",zChngUuid))%S(zChngUuid)</a>] |
| 958 | @ (rid %d(rid)) by |
| 959 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 960 | hyperlink_to_date(zDate, ":"); |
| 961 | @ </p> |
| 962 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1264,11 +1264,11 @@ | |
| 1264 | fossil_print(" Change "); |
| 1265 | } |
| 1266 | fossil_print("%h: ",z); |
| 1267 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1268 | fossil_print("\n ",blob_str(&val)); |
| 1269 | comment_print(blob_str(&val),0,4,-1,g.comFmtFlags); |
| 1270 | }else{ |
| 1271 | fossil_print("%s\n",blob_str(&val)); |
| 1272 | } |
| 1273 | blob_reset(&val); |
| 1274 | } |
| 1275 |
+166
-154
| --- src/unicode.c | ||
| +++ src/unicode.c | ||
| @@ -31,101 +31,107 @@ | ||
| 31 | 31 | int unicode_isalnum(int c){ |
| 32 | 32 | /* Each unsigned integer in the following array corresponds to a contiguous |
| 33 | 33 | ** range of unicode codepoints that are not either letters or numbers (i.e. |
| 34 | 34 | ** codepoints for which this function should return 0). |
| 35 | 35 | ** |
| 36 | - ** The most significant 22 bits in each 32-bit value contain the first | |
| 36 | + ** The most significant 22 bits in each 32-bit value contain the first | |
| 37 | 37 | ** codepoint in the range. The least significant 10 bits are used to store |
| 38 | - ** the size of the range (always at least 1). In other words, the value | |
| 39 | - ** ((C<<22) + N) represents a range of N codepoints starting with codepoint | |
| 40 | - ** C. It is not possible to represent a range larger than 1023 codepoints | |
| 38 | + ** the size of the range (always at least 1). In other words, the value | |
| 39 | + ** ((C<<22) + N) represents a range of N codepoints starting with codepoint | |
| 40 | + ** C. It is not possible to represent a range larger than 1023 codepoints | |
| 41 | 41 | ** using this format. |
| 42 | 42 | */ |
| 43 | 43 | static const unsigned int aEntry[] = { |
| 44 | 44 | 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, |
| 45 | 45 | 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, |
| 46 | 46 | 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, |
| 47 | 47 | 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, |
| 48 | - 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, | |
| 49 | - 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, | |
| 50 | - 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, | |
| 51 | - 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, | |
| 52 | - 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, | |
| 53 | - 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, | |
| 54 | - 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, | |
| 55 | - 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, | |
| 56 | - 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, | |
| 57 | - 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, | |
| 58 | - 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, | |
| 59 | - 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, | |
| 60 | - 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, | |
| 61 | - 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, | |
| 62 | - 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, | |
| 63 | - 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, | |
| 64 | - 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, | |
| 65 | - 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, | |
| 66 | - 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, | |
| 67 | - 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, | |
| 68 | - 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, | |
| 69 | - 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, | |
| 70 | - 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, | |
| 71 | - 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, | |
| 72 | - 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, | |
| 73 | - 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, | |
| 74 | - 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, | |
| 75 | - 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, | |
| 76 | - 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, | |
| 77 | - 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, | |
| 78 | - 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, | |
| 79 | - 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, | |
| 80 | - 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, | |
| 81 | - 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, | |
| 82 | - 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, | |
| 48 | + 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163403, | |
| 49 | + 0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15, | |
| 50 | + 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07, | |
| 51 | + 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B, | |
| 52 | + 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09, | |
| 53 | + 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801, | |
| 54 | + 0x00239020, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804, | |
| 55 | + 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02, | |
| 56 | + 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802, | |
| 57 | + 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03, | |
| 58 | + 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403, 0x002AF001, | |
| 59 | + 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002, | |
| 60 | + 0x002C0403, 0x002CF001, 0x002CF807, 0x002D1C02, 0x002D2C03, | |
| 61 | + 0x002D5802, 0x002D8802, 0x002DC001, 0x002E0801, 0x002EF805, | |
| 62 | + 0x002F1803, 0x002F2804, 0x002F5C01, 0x002FCC08, 0x00300004, | |
| 63 | + 0x0030F807, 0x00311803, 0x00312804, 0x00315402, 0x00318802, | |
| 64 | + 0x0031FC01, 0x00320403, 0x0032F001, 0x0032F807, 0x00331803, | |
| 65 | + 0x00332804, 0x00335402, 0x00338802, 0x00340403, 0x0034F807, | |
| 66 | + 0x00351803, 0x00352804, 0x00355C01, 0x00358802, 0x0035E401, | |
| 67 | + 0x00360802, 0x00372801, 0x00373C06, 0x00375801, 0x00376008, | |
| 68 | + 0x0037C803, 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09, | |
| 69 | + 0x00396802, 0x003AC401, 0x003AD006, 0x003AEC02, 0x003B2006, | |
| 70 | + 0x003C041F, 0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424, | |
| 71 | + 0x003EF80F, 0x003F380D, 0x0040AC14, 0x00412806, 0x00415804, | |
| 72 | + 0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C, | |
| 73 | + 0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A, | |
| 74 | + 0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03, | |
| 75 | + 0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023, | |
| 76 | + 0x005F6004, 0x005F7401, 0x0060000F, 0x0062A401, 0x0064800C, | |
| 77 | + 0x0064C00C, 0x00650001, 0x00651002, 0x0066C011, 0x00672002, | |
| 78 | + 0x00677822, 0x00685C05, 0x00687802, 0x0069540A, 0x0069801D, | |
| 79 | + 0x0069FC01, 0x006A8007, 0x006AA006, 0x006AC00F, 0x006C0005, | |
| 80 | + 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, 0x006F980E, | |
| 81 | + 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, 0x00730008, | |
| 82 | + 0x00734019, 0x0073B401, 0x0073C803, 0x0073E002, 0x00770036, | |
| 83 | 83 | 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, |
| 84 | - 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, | |
| 85 | - 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, | |
| 84 | + 0x007FB403, 0x007FF402, 0x00800065, 0x0081980A, 0x0081E805, | |
| 85 | + 0x00822805, 0x0082801E, 0x00834021, 0x00840002, 0x00840C04, | |
| 86 | 86 | 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, |
| 87 | 87 | 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, |
| 88 | - 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, | |
| 89 | - 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, | |
| 90 | - 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, | |
| 91 | - 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, | |
| 92 | - 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, | |
| 93 | - 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, | |
| 94 | - 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, | |
| 95 | - 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, | |
| 96 | - 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, | |
| 97 | - 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, | |
| 98 | - 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, | |
| 99 | - 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, | |
| 100 | - 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, | |
| 101 | - 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, | |
| 102 | - 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, | |
| 103 | - 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, | |
| 104 | - 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, | |
| 105 | - 0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, | |
| 106 | - 0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, | |
| 107 | - 0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, | |
| 108 | - 0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, | |
| 109 | - 0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, | |
| 110 | - 0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, | |
| 111 | - 0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, | |
| 112 | - 0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, | |
| 113 | - 0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, | |
| 114 | - 0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, | |
| 115 | - 0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, | |
| 116 | - 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, | |
| 117 | - 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, | |
| 118 | - 0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, | |
| 119 | - 0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, | |
| 120 | - 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, | |
| 121 | - 0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, | |
| 122 | - 0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, | |
| 123 | - 0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, | |
| 124 | - 0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, | |
| 125 | - 0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001, | |
| 126 | - 0x43FFF401, | |
| 88 | + 0x00852804, 0x00853C01, 0x0086426B, 0x00900027, 0x0091000B, | |
| 89 | + 0x0092704E, 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022, | |
| 90 | + 0x00AEF40C, 0x00AF2808, 0x00B39406, 0x00B3BC03, 0x00B3E404, | |
| 91 | + 0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C013, | |
| 92 | + 0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005, | |
| 93 | + 0x00C02019, 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404, | |
| 94 | + 0x00C28001, 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024, | |
| 95 | + 0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827, | |
| 96 | + 0x00CB003F, 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802, | |
| 97 | + 0x02983403, 0x0299BC10, 0x029A7C01, 0x029BC008, 0x029C0017, | |
| 98 | + 0x029C8002, 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01, | |
| 99 | + 0x02A08C09, 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D011, | |
| 100 | + 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A4980A, 0x02A51C0D, | |
| 101 | + 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401, | |
| 102 | + 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03, | |
| 103 | + 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802, | |
| 104 | + 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402, 0x02AD6C01, | |
| 105 | + 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, 0x037FFC01, | |
| 106 | + 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, 0x03F7F002, | |
| 107 | + 0x03F8001A, 0x03F8800E, 0x03F8C023, 0x03F95013, 0x03F9A004, | |
| 108 | + 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B, | |
| 109 | + 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09, | |
| 110 | + 0x0405E411, 0x04063001, 0x0406400C, 0x04068001, 0x0407402E, | |
| 111 | + 0x040B8001, 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01, | |
| 112 | + 0x04215C01, 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403, | |
| 113 | + 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, | |
| 114 | + 0x0429FC01, 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407, | |
| 115 | + 0x042E6404, 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012, | |
| 116 | + 0x04440003, 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003, | |
| 117 | + 0x0446CC0E, 0x04471404, 0x04473401, 0x0448B012, 0x044B7C0C, | |
| 118 | + 0x044C0403, 0x044CF001, 0x044CF807, 0x044D1C02, 0x044D2C03, | |
| 119 | + 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005, 0x0452C014, | |
| 120 | + 0x04531801, 0x0456BC07, 0x0456E012, 0x0458C014, 0x045AAC0D, | |
| 121 | + 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010, 0x05AD1002, | |
| 122 | + 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6, 0x07440027, | |
| 123 | + 0x0744A4B5, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, | |
| 124 | + 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, | |
| 125 | + 0x075E2401, 0x075EA401, 0x075F0C01, 0x07A34007, 0x07BBC002, | |
| 126 | + 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F, 0x07C3040F, | |
| 127 | + 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C02B, 0x07C7981D, | |
| 128 | + 0x07C8402B, 0x07C90009, 0x07C94002, 0x07CC002D, 0x07CCC04E, | |
| 129 | + 0x07CE004F, 0x07CF5024, 0x07D000FF, 0x07D4004B, 0x07D5402A, | |
| 130 | + 0x07D5EC29, 0x07D6949E, 0x07D9148B, 0x07DB800D, 0x07DBC004, | |
| 131 | + 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038, 0x07E1400A, | |
| 132 | + 0x07E18028, 0x07E2401E, 0x38000401, 0x38008060, 0x380400F0, | |
| 127 | 133 | }; |
| 128 | 134 | static const unsigned int aAscii[4] = { |
| 129 | 135 | 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, |
| 130 | 136 | }; |
| 131 | 137 | |
| @@ -160,35 +166,35 @@ | ||
| 160 | 166 | ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER |
| 161 | 167 | ** E"). The resuls of passing a codepoint that corresponds to an |
| 162 | 168 | ** uppercase letter are undefined. |
| 163 | 169 | */ |
| 164 | 170 | static int unicode_remove_diacritic(int c){ |
| 165 | - unsigned short aDia[] = { | |
| 166 | - 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, | |
| 167 | - 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, | |
| 168 | - 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, | |
| 169 | - 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, | |
| 170 | - 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, | |
| 171 | - 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, | |
| 172 | - 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, | |
| 173 | - 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, | |
| 174 | - 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, | |
| 175 | - 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, | |
| 176 | - 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, | |
| 177 | - 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, | |
| 178 | - 62924, 63050, 63082, 63274, 63390, | |
| 171 | + static const unsigned short aDia[] = { | |
| 172 | + 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, | |
| 173 | + 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, | |
| 174 | + 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, | |
| 175 | + 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, | |
| 176 | + 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, | |
| 177 | + 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, | |
| 178 | + 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, | |
| 179 | + 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, | |
| 180 | + 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, | |
| 181 | + 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, | |
| 182 | + 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, | |
| 183 | + 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, | |
| 184 | + 62924, 63050, 63082, 63274, 63390, | |
| 179 | 185 | }; |
| 180 | - char aChar[] = { | |
| 181 | - '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', | |
| 182 | - 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', | |
| 183 | - 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', | |
| 184 | - 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', | |
| 185 | - 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', | |
| 186 | - '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', | |
| 187 | - 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', | |
| 188 | - 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', | |
| 189 | - 'e', 'i', 'o', 'u', 'y', | |
| 186 | + static const char aChar[] = { | |
| 187 | + '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', | |
| 188 | + 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', | |
| 189 | + 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', | |
| 190 | + 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', | |
| 191 | + 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', | |
| 192 | + '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', | |
| 193 | + 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', | |
| 194 | + 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', | |
| 195 | + 'e', 'i', 'o', 'u', 'y', | |
| 190 | 196 | }; |
| 191 | 197 | |
| 192 | 198 | unsigned int key = (((unsigned int)c)<<3) | 0x00000007; |
| 193 | 199 | int iRes = 0; |
| 194 | 200 | int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; |
| @@ -253,12 +259,12 @@ | ||
| 253 | 259 | unsigned char flags; |
| 254 | 260 | unsigned char nRange; |
| 255 | 261 | } aEntry[] = { |
| 256 | 262 | {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, |
| 257 | 263 | {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, |
| 258 | - {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, | |
| 259 | - {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, | |
| 264 | + {313, 1, 16}, {330, 1, 46}, {376, 126, 1}, | |
| 265 | + {377, 1, 6}, {383, 114, 1}, {385, 50, 1}, | |
| 260 | 266 | {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, |
| 261 | 267 | {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, |
| 262 | 268 | {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, |
| 263 | 269 | {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, |
| 264 | 270 | {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, |
| @@ -267,61 +273,64 @@ | ||
| 267 | 273 | {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, |
| 268 | 274 | {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, |
| 269 | 275 | {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, |
| 270 | 276 | {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, |
| 271 | 277 | {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, |
| 272 | - {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, | |
| 273 | - {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, | |
| 278 | + {497, 2, 1}, {498, 1, 4}, {502, 132, 1}, | |
| 279 | + {503, 144, 1}, {504, 1, 40}, {544, 120, 1}, | |
| 274 | 280 | {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, |
| 275 | - {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, | |
| 276 | - {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, | |
| 281 | + {573, 118, 1}, {574, 68, 1}, {577, 0, 1}, | |
| 282 | + {579, 116, 1}, {580, 28, 1}, {581, 30, 1}, | |
| 277 | 283 | {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, |
| 278 | - {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, | |
| 279 | - {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, | |
| 280 | - {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, | |
| 281 | - {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, | |
| 282 | - {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, | |
| 283 | - {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, | |
| 284 | - {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, | |
| 285 | - {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, | |
| 286 | - {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, | |
| 287 | - {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, | |
| 288 | - {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, | |
| 289 | - {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, | |
| 290 | - {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, | |
| 291 | - {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, | |
| 292 | - {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, | |
| 293 | - {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, | |
| 294 | - {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, | |
| 295 | - {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, | |
| 296 | - {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, | |
| 297 | - {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, | |
| 298 | - {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, | |
| 299 | - {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, | |
| 300 | - {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, | |
| 301 | - {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, | |
| 302 | - {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, | |
| 303 | - {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, | |
| 304 | - {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, | |
| 305 | - {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, | |
| 306 | - {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, | |
| 307 | - {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, | |
| 308 | - {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, | |
| 309 | - {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, | |
| 310 | - {65313, 14, 26}, | |
| 284 | + {886, 0, 1}, {895, 36, 1}, {902, 18, 1}, | |
| 285 | + {904, 16, 3}, {908, 26, 1}, {910, 24, 2}, | |
| 286 | + {913, 14, 17}, {931, 14, 9}, {962, 0, 1}, | |
| 287 | + {975, 4, 1}, {976, 150, 1}, {977, 152, 1}, | |
| 288 | + {981, 156, 1}, {982, 154, 1}, {984, 1, 24}, | |
| 289 | + {1008, 146, 1}, {1009, 148, 1}, {1012, 140, 1}, | |
| 290 | + {1013, 138, 1}, {1015, 0, 1}, {1017, 162, 1}, | |
| 291 | + {1018, 0, 1}, {1021, 120, 3}, {1024, 34, 16}, | |
| 292 | + {1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54}, | |
| 293 | + {1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96}, | |
| 294 | + {1329, 22, 38}, {4256, 66, 38}, {4295, 66, 1}, | |
| 295 | + {4301, 66, 1}, {7680, 1, 150}, {7835, 142, 1}, | |
| 296 | + {7838, 106, 1}, {7840, 1, 96}, {7944, 160, 8}, | |
| 297 | + {7960, 160, 6}, {7976, 160, 8}, {7992, 160, 8}, | |
| 298 | + {8008, 160, 6}, {8025, 161, 8}, {8040, 160, 8}, | |
| 299 | + {8072, 160, 8}, {8088, 160, 8}, {8104, 160, 8}, | |
| 300 | + {8120, 160, 2}, {8122, 136, 2}, {8124, 158, 1}, | |
| 301 | + {8126, 110, 1}, {8136, 134, 4}, {8140, 158, 1}, | |
| 302 | + {8152, 160, 2}, {8154, 130, 2}, {8168, 160, 2}, | |
| 303 | + {8170, 128, 2}, {8172, 162, 1}, {8184, 122, 2}, | |
| 304 | + {8186, 124, 2}, {8188, 158, 1}, {8486, 108, 1}, | |
| 305 | + {8490, 102, 1}, {8491, 104, 1}, {8498, 12, 1}, | |
| 306 | + {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26}, | |
| 307 | + {11264, 22, 47}, {11360, 0, 1}, {11362, 98, 1}, | |
| 308 | + {11363, 112, 1}, {11364, 100, 1}, {11367, 1, 6}, | |
| 309 | + {11373, 94, 1}, {11374, 96, 1}, {11375, 90, 1}, | |
| 310 | + {11376, 92, 1}, {11378, 0, 1}, {11381, 0, 1}, | |
| 311 | + {11390, 88, 2}, {11392, 1, 100}, {11499, 1, 4}, | |
| 312 | + {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28}, | |
| 313 | + {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4}, | |
| 314 | + {42877, 86, 1}, {42878, 1, 10}, {42891, 0, 1}, | |
| 315 | + {42893, 82, 1}, {42896, 1, 4}, {42902, 1, 20}, | |
| 316 | + {42922, 76, 1}, {42923, 72, 1}, {42924, 74, 1}, | |
| 317 | + {42925, 78, 1}, {42928, 84, 1}, {42929, 80, 1}, | |
| 318 | + {65313, 14, 26}, | |
| 311 | 319 | }; |
| 312 | 320 | static const unsigned short aiOff[] = { |
| 313 | - 1, 2, 8, 15, 16, 26, 28, 32, | |
| 314 | - 37, 38, 40, 48, 63, 64, 69, 71, | |
| 315 | - 79, 80, 116, 202, 203, 205, 206, 207, | |
| 316 | - 209, 210, 211, 213, 214, 217, 218, 219, | |
| 317 | - 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, | |
| 318 | - 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, | |
| 319 | - 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, | |
| 320 | - 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, | |
| 321 | - 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, | |
| 322 | - 65514, 65521, 65527, 65528, 65529, | |
| 321 | + 1, 2, 8, 15, 16, 26, 28, 32, | |
| 322 | + 37, 38, 40, 48, 63, 64, 69, 71, | |
| 323 | + 79, 80, 116, 202, 203, 205, 206, 207, | |
| 324 | + 209, 210, 211, 213, 214, 217, 218, 219, | |
| 325 | + 775, 7264, 10792, 10795, 23217, 23221, 23228, 23231, | |
| 326 | + 23254, 23256, 23278, 30204, 54721, 54753, 54754, 54756, | |
| 327 | + 54787, 54793, 54809, 57153, 57274, 57921, 58019, 58363, | |
| 328 | + 61722, 65268, 65341, 65373, 65406, 65408, 65410, 65415, | |
| 329 | + 65424, 65436, 65439, 65450, 65462, 65472, 65476, 65478, | |
| 330 | + 65480, 65482, 65488, 65506, 65511, 65514, 65521, 65527, | |
| 331 | + 65528, 65529, | |
| 323 | 332 | }; |
| 324 | 333 | |
| 325 | 334 | int ret = c; |
| 326 | 335 | |
| 327 | 336 | assert( c>=0 ); |
| @@ -354,12 +363,15 @@ | ||
| 354 | 363 | } |
| 355 | 364 | } |
| 356 | 365 | |
| 357 | 366 | if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret); |
| 358 | 367 | } |
| 359 | - | |
| 368 | + | |
| 360 | 369 | else if( c>=66560 && c<66600 ){ |
| 361 | 370 | ret = c + 40; |
| 371 | + } | |
| 372 | + else if( c>=71840 && c<71872 ){ | |
| 373 | + ret = c + 32; | |
| 362 | 374 | } |
| 363 | 375 | |
| 364 | 376 | return ret; |
| 365 | 377 | } |
| 366 | 378 |
| --- src/unicode.c | |
| +++ src/unicode.c | |
| @@ -31,101 +31,107 @@ | |
| 31 | int unicode_isalnum(int c){ |
| 32 | /* Each unsigned integer in the following array corresponds to a contiguous |
| 33 | ** range of unicode codepoints that are not either letters or numbers (i.e. |
| 34 | ** codepoints for which this function should return 0). |
| 35 | ** |
| 36 | ** The most significant 22 bits in each 32-bit value contain the first |
| 37 | ** codepoint in the range. The least significant 10 bits are used to store |
| 38 | ** the size of the range (always at least 1). In other words, the value |
| 39 | ** ((C<<22) + N) represents a range of N codepoints starting with codepoint |
| 40 | ** C. It is not possible to represent a range larger than 1023 codepoints |
| 41 | ** using this format. |
| 42 | */ |
| 43 | static const unsigned int aEntry[] = { |
| 44 | 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, |
| 45 | 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, |
| 46 | 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, |
| 47 | 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, |
| 48 | 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, |
| 49 | 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, |
| 50 | 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, |
| 51 | 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, |
| 52 | 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, |
| 53 | 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, |
| 54 | 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, |
| 55 | 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, |
| 56 | 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, |
| 57 | 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, |
| 58 | 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, |
| 59 | 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, |
| 60 | 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, |
| 61 | 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, |
| 62 | 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, |
| 63 | 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, |
| 64 | 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, |
| 65 | 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, |
| 66 | 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, |
| 67 | 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, |
| 68 | 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, |
| 69 | 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, |
| 70 | 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, |
| 71 | 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, |
| 72 | 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, |
| 73 | 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, |
| 74 | 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, |
| 75 | 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, |
| 76 | 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, |
| 77 | 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, |
| 78 | 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, |
| 79 | 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, |
| 80 | 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, |
| 81 | 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, |
| 82 | 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, |
| 83 | 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, |
| 84 | 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, |
| 85 | 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, |
| 86 | 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, |
| 87 | 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, |
| 88 | 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, |
| 89 | 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, |
| 90 | 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, |
| 91 | 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, |
| 92 | 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, |
| 93 | 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, |
| 94 | 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, |
| 95 | 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, |
| 96 | 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, |
| 97 | 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, |
| 98 | 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, |
| 99 | 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, |
| 100 | 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, |
| 101 | 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, |
| 102 | 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, |
| 103 | 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, |
| 104 | 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, |
| 105 | 0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, |
| 106 | 0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, |
| 107 | 0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, |
| 108 | 0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, |
| 109 | 0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, |
| 110 | 0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, |
| 111 | 0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, |
| 112 | 0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, |
| 113 | 0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, |
| 114 | 0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, |
| 115 | 0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, |
| 116 | 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, |
| 117 | 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, |
| 118 | 0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, |
| 119 | 0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, |
| 120 | 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, |
| 121 | 0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, |
| 122 | 0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, |
| 123 | 0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, |
| 124 | 0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, |
| 125 | 0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001, |
| 126 | 0x43FFF401, |
| 127 | }; |
| 128 | static const unsigned int aAscii[4] = { |
| 129 | 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, |
| 130 | }; |
| 131 | |
| @@ -160,35 +166,35 @@ | |
| 160 | ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER |
| 161 | ** E"). The resuls of passing a codepoint that corresponds to an |
| 162 | ** uppercase letter are undefined. |
| 163 | */ |
| 164 | static int unicode_remove_diacritic(int c){ |
| 165 | unsigned short aDia[] = { |
| 166 | 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, |
| 167 | 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, |
| 168 | 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, |
| 169 | 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, |
| 170 | 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, |
| 171 | 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, |
| 172 | 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, |
| 173 | 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, |
| 174 | 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, |
| 175 | 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, |
| 176 | 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, |
| 177 | 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, |
| 178 | 62924, 63050, 63082, 63274, 63390, |
| 179 | }; |
| 180 | char aChar[] = { |
| 181 | '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', |
| 182 | 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', |
| 183 | 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', |
| 184 | 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', |
| 185 | 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', |
| 186 | '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', |
| 187 | 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', |
| 188 | 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', |
| 189 | 'e', 'i', 'o', 'u', 'y', |
| 190 | }; |
| 191 | |
| 192 | unsigned int key = (((unsigned int)c)<<3) | 0x00000007; |
| 193 | int iRes = 0; |
| 194 | int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; |
| @@ -253,12 +259,12 @@ | |
| 253 | unsigned char flags; |
| 254 | unsigned char nRange; |
| 255 | } aEntry[] = { |
| 256 | {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, |
| 257 | {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, |
| 258 | {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, |
| 259 | {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, |
| 260 | {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, |
| 261 | {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, |
| 262 | {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, |
| 263 | {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, |
| 264 | {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, |
| @@ -267,61 +273,64 @@ | |
| 267 | {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, |
| 268 | {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, |
| 269 | {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, |
| 270 | {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, |
| 271 | {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, |
| 272 | {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, |
| 273 | {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, |
| 274 | {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, |
| 275 | {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, |
| 276 | {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, |
| 277 | {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, |
| 278 | {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, |
| 279 | {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, |
| 280 | {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, |
| 281 | {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, |
| 282 | {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, |
| 283 | {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, |
| 284 | {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, |
| 285 | {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, |
| 286 | {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, |
| 287 | {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, |
| 288 | {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, |
| 289 | {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, |
| 290 | {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, |
| 291 | {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, |
| 292 | {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, |
| 293 | {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, |
| 294 | {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, |
| 295 | {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, |
| 296 | {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, |
| 297 | {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, |
| 298 | {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, |
| 299 | {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, |
| 300 | {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, |
| 301 | {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, |
| 302 | {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, |
| 303 | {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, |
| 304 | {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, |
| 305 | {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, |
| 306 | {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, |
| 307 | {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, |
| 308 | {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, |
| 309 | {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, |
| 310 | {65313, 14, 26}, |
| 311 | }; |
| 312 | static const unsigned short aiOff[] = { |
| 313 | 1, 2, 8, 15, 16, 26, 28, 32, |
| 314 | 37, 38, 40, 48, 63, 64, 69, 71, |
| 315 | 79, 80, 116, 202, 203, 205, 206, 207, |
| 316 | 209, 210, 211, 213, 214, 217, 218, 219, |
| 317 | 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, |
| 318 | 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, |
| 319 | 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, |
| 320 | 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, |
| 321 | 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, |
| 322 | 65514, 65521, 65527, 65528, 65529, |
| 323 | }; |
| 324 | |
| 325 | int ret = c; |
| 326 | |
| 327 | assert( c>=0 ); |
| @@ -354,12 +363,15 @@ | |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret); |
| 358 | } |
| 359 | |
| 360 | else if( c>=66560 && c<66600 ){ |
| 361 | ret = c + 40; |
| 362 | } |
| 363 | |
| 364 | return ret; |
| 365 | } |
| 366 |
| --- src/unicode.c | |
| +++ src/unicode.c | |
| @@ -31,101 +31,107 @@ | |
| 31 | int unicode_isalnum(int c){ |
| 32 | /* Each unsigned integer in the following array corresponds to a contiguous |
| 33 | ** range of unicode codepoints that are not either letters or numbers (i.e. |
| 34 | ** codepoints for which this function should return 0). |
| 35 | ** |
| 36 | ** The most significant 22 bits in each 32-bit value contain the first |
| 37 | ** codepoint in the range. The least significant 10 bits are used to store |
| 38 | ** the size of the range (always at least 1). In other words, the value |
| 39 | ** ((C<<22) + N) represents a range of N codepoints starting with codepoint |
| 40 | ** C. It is not possible to represent a range larger than 1023 codepoints |
| 41 | ** using this format. |
| 42 | */ |
| 43 | static const unsigned int aEntry[] = { |
| 44 | 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, |
| 45 | 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, |
| 46 | 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, |
| 47 | 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, |
| 48 | 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163403, |
| 49 | 0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15, |
| 50 | 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07, |
| 51 | 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B, |
| 52 | 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09, |
| 53 | 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801, |
| 54 | 0x00239020, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804, |
| 55 | 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02, |
| 56 | 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802, |
| 57 | 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03, |
| 58 | 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403, 0x002AF001, |
| 59 | 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002, |
| 60 | 0x002C0403, 0x002CF001, 0x002CF807, 0x002D1C02, 0x002D2C03, |
| 61 | 0x002D5802, 0x002D8802, 0x002DC001, 0x002E0801, 0x002EF805, |
| 62 | 0x002F1803, 0x002F2804, 0x002F5C01, 0x002FCC08, 0x00300004, |
| 63 | 0x0030F807, 0x00311803, 0x00312804, 0x00315402, 0x00318802, |
| 64 | 0x0031FC01, 0x00320403, 0x0032F001, 0x0032F807, 0x00331803, |
| 65 | 0x00332804, 0x00335402, 0x00338802, 0x00340403, 0x0034F807, |
| 66 | 0x00351803, 0x00352804, 0x00355C01, 0x00358802, 0x0035E401, |
| 67 | 0x00360802, 0x00372801, 0x00373C06, 0x00375801, 0x00376008, |
| 68 | 0x0037C803, 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09, |
| 69 | 0x00396802, 0x003AC401, 0x003AD006, 0x003AEC02, 0x003B2006, |
| 70 | 0x003C041F, 0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424, |
| 71 | 0x003EF80F, 0x003F380D, 0x0040AC14, 0x00412806, 0x00415804, |
| 72 | 0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C, |
| 73 | 0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A, |
| 74 | 0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03, |
| 75 | 0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023, |
| 76 | 0x005F6004, 0x005F7401, 0x0060000F, 0x0062A401, 0x0064800C, |
| 77 | 0x0064C00C, 0x00650001, 0x00651002, 0x0066C011, 0x00672002, |
| 78 | 0x00677822, 0x00685C05, 0x00687802, 0x0069540A, 0x0069801D, |
| 79 | 0x0069FC01, 0x006A8007, 0x006AA006, 0x006AC00F, 0x006C0005, |
| 80 | 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, 0x006F980E, |
| 81 | 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, 0x00730008, |
| 82 | 0x00734019, 0x0073B401, 0x0073C803, 0x0073E002, 0x00770036, |
| 83 | 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, |
| 84 | 0x007FB403, 0x007FF402, 0x00800065, 0x0081980A, 0x0081E805, |
| 85 | 0x00822805, 0x0082801E, 0x00834021, 0x00840002, 0x00840C04, |
| 86 | 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, |
| 87 | 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, |
| 88 | 0x00852804, 0x00853C01, 0x0086426B, 0x00900027, 0x0091000B, |
| 89 | 0x0092704E, 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022, |
| 90 | 0x00AEF40C, 0x00AF2808, 0x00B39406, 0x00B3BC03, 0x00B3E404, |
| 91 | 0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C013, |
| 92 | 0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005, |
| 93 | 0x00C02019, 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404, |
| 94 | 0x00C28001, 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024, |
| 95 | 0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827, |
| 96 | 0x00CB003F, 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802, |
| 97 | 0x02983403, 0x0299BC10, 0x029A7C01, 0x029BC008, 0x029C0017, |
| 98 | 0x029C8002, 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01, |
| 99 | 0x02A08C09, 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D011, |
| 100 | 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A4980A, 0x02A51C0D, |
| 101 | 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401, |
| 102 | 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03, |
| 103 | 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802, |
| 104 | 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402, 0x02AD6C01, |
| 105 | 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, 0x037FFC01, |
| 106 | 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, 0x03F7F002, |
| 107 | 0x03F8001A, 0x03F8800E, 0x03F8C023, 0x03F95013, 0x03F9A004, |
| 108 | 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B, |
| 109 | 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09, |
| 110 | 0x0405E411, 0x04063001, 0x0406400C, 0x04068001, 0x0407402E, |
| 111 | 0x040B8001, 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01, |
| 112 | 0x04215C01, 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403, |
| 113 | 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, |
| 114 | 0x0429FC01, 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407, |
| 115 | 0x042E6404, 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012, |
| 116 | 0x04440003, 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003, |
| 117 | 0x0446CC0E, 0x04471404, 0x04473401, 0x0448B012, 0x044B7C0C, |
| 118 | 0x044C0403, 0x044CF001, 0x044CF807, 0x044D1C02, 0x044D2C03, |
| 119 | 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005, 0x0452C014, |
| 120 | 0x04531801, 0x0456BC07, 0x0456E012, 0x0458C014, 0x045AAC0D, |
| 121 | 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010, 0x05AD1002, |
| 122 | 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6, 0x07440027, |
| 123 | 0x0744A4B5, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, |
| 124 | 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, |
| 125 | 0x075E2401, 0x075EA401, 0x075F0C01, 0x07A34007, 0x07BBC002, |
| 126 | 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F, 0x07C3040F, |
| 127 | 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C02B, 0x07C7981D, |
| 128 | 0x07C8402B, 0x07C90009, 0x07C94002, 0x07CC002D, 0x07CCC04E, |
| 129 | 0x07CE004F, 0x07CF5024, 0x07D000FF, 0x07D4004B, 0x07D5402A, |
| 130 | 0x07D5EC29, 0x07D6949E, 0x07D9148B, 0x07DB800D, 0x07DBC004, |
| 131 | 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038, 0x07E1400A, |
| 132 | 0x07E18028, 0x07E2401E, 0x38000401, 0x38008060, 0x380400F0, |
| 133 | }; |
| 134 | static const unsigned int aAscii[4] = { |
| 135 | 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, |
| 136 | }; |
| 137 | |
| @@ -160,35 +166,35 @@ | |
| 166 | ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER |
| 167 | ** E"). The resuls of passing a codepoint that corresponds to an |
| 168 | ** uppercase letter are undefined. |
| 169 | */ |
| 170 | static int unicode_remove_diacritic(int c){ |
| 171 | static const unsigned short aDia[] = { |
| 172 | 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, |
| 173 | 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, |
| 174 | 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, |
| 175 | 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, |
| 176 | 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, |
| 177 | 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, |
| 178 | 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, |
| 179 | 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, |
| 180 | 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, |
| 181 | 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, |
| 182 | 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, |
| 183 | 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, |
| 184 | 62924, 63050, 63082, 63274, 63390, |
| 185 | }; |
| 186 | static const char aChar[] = { |
| 187 | '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', |
| 188 | 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', |
| 189 | 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', |
| 190 | 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', |
| 191 | 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', |
| 192 | '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', |
| 193 | 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', |
| 194 | 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', |
| 195 | 'e', 'i', 'o', 'u', 'y', |
| 196 | }; |
| 197 | |
| 198 | unsigned int key = (((unsigned int)c)<<3) | 0x00000007; |
| 199 | int iRes = 0; |
| 200 | int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; |
| @@ -253,12 +259,12 @@ | |
| 259 | unsigned char flags; |
| 260 | unsigned char nRange; |
| 261 | } aEntry[] = { |
| 262 | {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, |
| 263 | {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, |
| 264 | {313, 1, 16}, {330, 1, 46}, {376, 126, 1}, |
| 265 | {377, 1, 6}, {383, 114, 1}, {385, 50, 1}, |
| 266 | {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, |
| 267 | {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, |
| 268 | {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, |
| 269 | {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, |
| 270 | {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, |
| @@ -267,61 +273,64 @@ | |
| 273 | {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, |
| 274 | {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, |
| 275 | {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, |
| 276 | {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, |
| 277 | {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, |
| 278 | {497, 2, 1}, {498, 1, 4}, {502, 132, 1}, |
| 279 | {503, 144, 1}, {504, 1, 40}, {544, 120, 1}, |
| 280 | {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, |
| 281 | {573, 118, 1}, {574, 68, 1}, {577, 0, 1}, |
| 282 | {579, 116, 1}, {580, 28, 1}, {581, 30, 1}, |
| 283 | {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, |
| 284 | {886, 0, 1}, {895, 36, 1}, {902, 18, 1}, |
| 285 | {904, 16, 3}, {908, 26, 1}, {910, 24, 2}, |
| 286 | {913, 14, 17}, {931, 14, 9}, {962, 0, 1}, |
| 287 | {975, 4, 1}, {976, 150, 1}, {977, 152, 1}, |
| 288 | {981, 156, 1}, {982, 154, 1}, {984, 1, 24}, |
| 289 | {1008, 146, 1}, {1009, 148, 1}, {1012, 140, 1}, |
| 290 | {1013, 138, 1}, {1015, 0, 1}, {1017, 162, 1}, |
| 291 | {1018, 0, 1}, {1021, 120, 3}, {1024, 34, 16}, |
| 292 | {1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54}, |
| 293 | {1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96}, |
| 294 | {1329, 22, 38}, {4256, 66, 38}, {4295, 66, 1}, |
| 295 | {4301, 66, 1}, {7680, 1, 150}, {7835, 142, 1}, |
| 296 | {7838, 106, 1}, {7840, 1, 96}, {7944, 160, 8}, |
| 297 | {7960, 160, 6}, {7976, 160, 8}, {7992, 160, 8}, |
| 298 | {8008, 160, 6}, {8025, 161, 8}, {8040, 160, 8}, |
| 299 | {8072, 160, 8}, {8088, 160, 8}, {8104, 160, 8}, |
| 300 | {8120, 160, 2}, {8122, 136, 2}, {8124, 158, 1}, |
| 301 | {8126, 110, 1}, {8136, 134, 4}, {8140, 158, 1}, |
| 302 | {8152, 160, 2}, {8154, 130, 2}, {8168, 160, 2}, |
| 303 | {8170, 128, 2}, {8172, 162, 1}, {8184, 122, 2}, |
| 304 | {8186, 124, 2}, {8188, 158, 1}, {8486, 108, 1}, |
| 305 | {8490, 102, 1}, {8491, 104, 1}, {8498, 12, 1}, |
| 306 | {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26}, |
| 307 | {11264, 22, 47}, {11360, 0, 1}, {11362, 98, 1}, |
| 308 | {11363, 112, 1}, {11364, 100, 1}, {11367, 1, 6}, |
| 309 | {11373, 94, 1}, {11374, 96, 1}, {11375, 90, 1}, |
| 310 | {11376, 92, 1}, {11378, 0, 1}, {11381, 0, 1}, |
| 311 | {11390, 88, 2}, {11392, 1, 100}, {11499, 1, 4}, |
| 312 | {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28}, |
| 313 | {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4}, |
| 314 | {42877, 86, 1}, {42878, 1, 10}, {42891, 0, 1}, |
| 315 | {42893, 82, 1}, {42896, 1, 4}, {42902, 1, 20}, |
| 316 | {42922, 76, 1}, {42923, 72, 1}, {42924, 74, 1}, |
| 317 | {42925, 78, 1}, {42928, 84, 1}, {42929, 80, 1}, |
| 318 | {65313, 14, 26}, |
| 319 | }; |
| 320 | static const unsigned short aiOff[] = { |
| 321 | 1, 2, 8, 15, 16, 26, 28, 32, |
| 322 | 37, 38, 40, 48, 63, 64, 69, 71, |
| 323 | 79, 80, 116, 202, 203, 205, 206, 207, |
| 324 | 209, 210, 211, 213, 214, 217, 218, 219, |
| 325 | 775, 7264, 10792, 10795, 23217, 23221, 23228, 23231, |
| 326 | 23254, 23256, 23278, 30204, 54721, 54753, 54754, 54756, |
| 327 | 54787, 54793, 54809, 57153, 57274, 57921, 58019, 58363, |
| 328 | 61722, 65268, 65341, 65373, 65406, 65408, 65410, 65415, |
| 329 | 65424, 65436, 65439, 65450, 65462, 65472, 65476, 65478, |
| 330 | 65480, 65482, 65488, 65506, 65511, 65514, 65521, 65527, |
| 331 | 65528, 65529, |
| 332 | }; |
| 333 | |
| 334 | int ret = c; |
| 335 | |
| 336 | assert( c>=0 ); |
| @@ -354,12 +363,15 @@ | |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret); |
| 367 | } |
| 368 | |
| 369 | else if( c>=66560 && c<66600 ){ |
| 370 | ret = c + 40; |
| 371 | } |
| 372 | else if( c>=71840 && c<71872 ){ |
| 373 | ret = c + 32; |
| 374 | } |
| 375 | |
| 376 | return ret; |
| 377 | } |
| 378 |
+41
-29
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -62,31 +62,37 @@ | ||
| 62 | 62 | /* |
| 63 | 63 | ** COMMAND: update |
| 64 | 64 | ** |
| 65 | 65 | ** Usage: %fossil update ?OPTIONS? ?VERSION? ?FILES...? |
| 66 | 66 | ** |
| 67 | -** Change the version of the current checkout to VERSION. Any uncommitted | |
| 68 | -** changes are retained and applied to the new checkout. | |
| 67 | +** Change the version of the current checkout to VERSION. Any | |
| 68 | +** uncommitted changes are retained and applied to the new checkout. | |
| 69 | 69 | ** |
| 70 | -** The VERSION argument can be a specific version or tag or branch name. | |
| 71 | -** If the VERSION argument is omitted, then the leaf of the subtree | |
| 72 | -** that begins at the current version is used, if there is only a single | |
| 73 | -** leaf. VERSION can also be "current" to select the leaf of the current | |
| 74 | -** version or "latest" to select the most recent check-in. | |
| 70 | +** The VERSION argument can be a specific version or tag or branch | |
| 71 | +** name. If the VERSION argument is omitted, then the leaf of the | |
| 72 | +** subtree that begins at the current version is used, if there is | |
| 73 | +** only a single leaf. VERSION can also be "current" to select the | |
| 74 | +** leaf of the current version or "latest" to select the most recent | |
| 75 | +** check-in. | |
| 75 | 76 | ** |
| 76 | 77 | ** If one or more FILES are listed after the VERSION then only the |
| 77 | -** named files are candidates to be updated. If FILES is omitted, all | |
| 78 | -** files in the current checkout are subject to be updated. Using | |
| 79 | -** a directory name for one of the FILES arguments is the same as | |
| 80 | -** using every subdirectory and file beneath that directory. | |
| 81 | -** | |
| 82 | -** The -n or --dry-run option causes this command to do a "dry run". It | |
| 83 | -** prints out what would have happened but does not actually make any | |
| 84 | -** changes to the current checkout or the repository. | |
| 85 | -** | |
| 86 | -** The -v or --verbose option prints status information about unchanged | |
| 87 | -** files in addition to those file that actually do change. | |
| 78 | +** named files are candidates to be updated, and any updates to them | |
| 79 | +** will be treated as edits to the current version. Using a directory | |
| 80 | +** name for one of the FILES arguments is the same as using every | |
| 81 | +** subdirectory and file beneath that directory. | |
| 82 | +** | |
| 83 | +** If FILES is omitted, all files in the current checkout are subject | |
| 84 | +** to being updated and the version of the current checkout is changed | |
| 85 | +** to VERSION. Any uncommitted changes are retained and applied to the | |
| 86 | +** new checkout. | |
| 87 | +** | |
| 88 | +** The -n or --dry-run option causes this command to do a "dry run". | |
| 89 | +** It prints out what would have happened but does not actually make | |
| 90 | +** any changes to the current checkout or the repository. | |
| 91 | +** | |
| 92 | +** The -v or --verbose option prints status information about | |
| 93 | +** unchanged files in addition to those file that actually do change. | |
| 88 | 94 | ** |
| 89 | 95 | ** Options: |
| 90 | 96 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 91 | 97 | ** --debug print debug information on stdout |
| 92 | 98 | ** --latest acceptable in place of VERSION, update to latest version |
| @@ -139,10 +145,14 @@ | ||
| 139 | 145 | verboseFlag = find_option("verbose","v",0)!=0; |
| 140 | 146 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 141 | 147 | debugFlag = find_option("debug",0,0)!=0; |
| 142 | 148 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 143 | 149 | capture_case_sensitive_option(); |
| 150 | + | |
| 151 | + /* We should be done with options.. */ | |
| 152 | + verify_all_options(); | |
| 153 | + | |
| 144 | 154 | db_must_be_within_tree(); |
| 145 | 155 | vid = db_lget_int("checkout", 0); |
| 146 | 156 | user_select(); |
| 147 | 157 | if( !dryRunFlag && !internalUpdate ){ |
| 148 | 158 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| @@ -261,21 +271,23 @@ | ||
| 261 | 271 | ); |
| 262 | 272 | |
| 263 | 273 | /* Compute file name changes on V->T. Record name changes in files that |
| 264 | 274 | ** have changed locally. |
| 265 | 275 | */ |
| 266 | - find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0); | |
| 267 | - if( nChng ){ | |
| 268 | - for(i=0; i<nChng; i++){ | |
| 269 | - db_multi_exec( | |
| 270 | - "UPDATE fv" | |
| 271 | - " SET fnt=(SELECT name FROM filename WHERE fnid=%d)" | |
| 272 | - " WHERE fn=(SELECT name FROM filename WHERE fnid=%d) AND chnged", | |
| 273 | - aChng[i*2+1], aChng[i*2] | |
| 274 | - ); | |
| 275 | - } | |
| 276 | - fossil_free(aChng); | |
| 276 | + if( vid ){ | |
| 277 | + find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0); | |
| 278 | + if( nChng ){ | |
| 279 | + for(i=0; i<nChng; i++){ | |
| 280 | + db_multi_exec( | |
| 281 | + "UPDATE fv" | |
| 282 | + " SET fnt=(SELECT name FROM filename WHERE fnid=%d)" | |
| 283 | + " WHERE fn=(SELECT name FROM filename WHERE fnid=%d) AND chnged", | |
| 284 | + aChng[i*2+1], aChng[i*2] | |
| 285 | + ); | |
| 286 | + } | |
| 287 | + fossil_free(aChng); | |
| 288 | + } | |
| 277 | 289 | } |
| 278 | 290 | |
| 279 | 291 | /* Add files found in the target version T but missing from the current |
| 280 | 292 | ** version V. |
| 281 | 293 | */ |
| 282 | 294 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -62,31 +62,37 @@ | |
| 62 | /* |
| 63 | ** COMMAND: update |
| 64 | ** |
| 65 | ** Usage: %fossil update ?OPTIONS? ?VERSION? ?FILES...? |
| 66 | ** |
| 67 | ** Change the version of the current checkout to VERSION. Any uncommitted |
| 68 | ** changes are retained and applied to the new checkout. |
| 69 | ** |
| 70 | ** The VERSION argument can be a specific version or tag or branch name. |
| 71 | ** If the VERSION argument is omitted, then the leaf of the subtree |
| 72 | ** that begins at the current version is used, if there is only a single |
| 73 | ** leaf. VERSION can also be "current" to select the leaf of the current |
| 74 | ** version or "latest" to select the most recent check-in. |
| 75 | ** |
| 76 | ** If one or more FILES are listed after the VERSION then only the |
| 77 | ** named files are candidates to be updated. If FILES is omitted, all |
| 78 | ** files in the current checkout are subject to be updated. Using |
| 79 | ** a directory name for one of the FILES arguments is the same as |
| 80 | ** using every subdirectory and file beneath that directory. |
| 81 | ** |
| 82 | ** The -n or --dry-run option causes this command to do a "dry run". It |
| 83 | ** prints out what would have happened but does not actually make any |
| 84 | ** changes to the current checkout or the repository. |
| 85 | ** |
| 86 | ** The -v or --verbose option prints status information about unchanged |
| 87 | ** files in addition to those file that actually do change. |
| 88 | ** |
| 89 | ** Options: |
| 90 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 91 | ** --debug print debug information on stdout |
| 92 | ** --latest acceptable in place of VERSION, update to latest version |
| @@ -139,10 +145,14 @@ | |
| 139 | verboseFlag = find_option("verbose","v",0)!=0; |
| 140 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 141 | debugFlag = find_option("debug",0,0)!=0; |
| 142 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 143 | capture_case_sensitive_option(); |
| 144 | db_must_be_within_tree(); |
| 145 | vid = db_lget_int("checkout", 0); |
| 146 | user_select(); |
| 147 | if( !dryRunFlag && !internalUpdate ){ |
| 148 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| @@ -261,21 +271,23 @@ | |
| 261 | ); |
| 262 | |
| 263 | /* Compute file name changes on V->T. Record name changes in files that |
| 264 | ** have changed locally. |
| 265 | */ |
| 266 | find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0); |
| 267 | if( nChng ){ |
| 268 | for(i=0; i<nChng; i++){ |
| 269 | db_multi_exec( |
| 270 | "UPDATE fv" |
| 271 | " SET fnt=(SELECT name FROM filename WHERE fnid=%d)" |
| 272 | " WHERE fn=(SELECT name FROM filename WHERE fnid=%d) AND chnged", |
| 273 | aChng[i*2+1], aChng[i*2] |
| 274 | ); |
| 275 | } |
| 276 | fossil_free(aChng); |
| 277 | } |
| 278 | |
| 279 | /* Add files found in the target version T but missing from the current |
| 280 | ** version V. |
| 281 | */ |
| 282 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -62,31 +62,37 @@ | |
| 62 | /* |
| 63 | ** COMMAND: update |
| 64 | ** |
| 65 | ** Usage: %fossil update ?OPTIONS? ?VERSION? ?FILES...? |
| 66 | ** |
| 67 | ** Change the version of the current checkout to VERSION. Any |
| 68 | ** uncommitted changes are retained and applied to the new checkout. |
| 69 | ** |
| 70 | ** The VERSION argument can be a specific version or tag or branch |
| 71 | ** name. If the VERSION argument is omitted, then the leaf of the |
| 72 | ** subtree that begins at the current version is used, if there is |
| 73 | ** only a single leaf. VERSION can also be "current" to select the |
| 74 | ** leaf of the current version or "latest" to select the most recent |
| 75 | ** check-in. |
| 76 | ** |
| 77 | ** If one or more FILES are listed after the VERSION then only the |
| 78 | ** named files are candidates to be updated, and any updates to them |
| 79 | ** will be treated as edits to the current version. Using a directory |
| 80 | ** name for one of the FILES arguments is the same as using every |
| 81 | ** subdirectory and file beneath that directory. |
| 82 | ** |
| 83 | ** If FILES is omitted, all files in the current checkout are subject |
| 84 | ** to being updated and the version of the current checkout is changed |
| 85 | ** to VERSION. Any uncommitted changes are retained and applied to the |
| 86 | ** new checkout. |
| 87 | ** |
| 88 | ** The -n or --dry-run option causes this command to do a "dry run". |
| 89 | ** It prints out what would have happened but does not actually make |
| 90 | ** any changes to the current checkout or the repository. |
| 91 | ** |
| 92 | ** The -v or --verbose option prints status information about |
| 93 | ** unchanged files in addition to those file that actually do change. |
| 94 | ** |
| 95 | ** Options: |
| 96 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 97 | ** --debug print debug information on stdout |
| 98 | ** --latest acceptable in place of VERSION, update to latest version |
| @@ -139,10 +145,14 @@ | |
| 145 | verboseFlag = find_option("verbose","v",0)!=0; |
| 146 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 147 | debugFlag = find_option("debug",0,0)!=0; |
| 148 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 149 | capture_case_sensitive_option(); |
| 150 | |
| 151 | /* We should be done with options.. */ |
| 152 | verify_all_options(); |
| 153 | |
| 154 | db_must_be_within_tree(); |
| 155 | vid = db_lget_int("checkout", 0); |
| 156 | user_select(); |
| 157 | if( !dryRunFlag && !internalUpdate ){ |
| 158 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| @@ -261,21 +271,23 @@ | |
| 271 | ); |
| 272 | |
| 273 | /* Compute file name changes on V->T. Record name changes in files that |
| 274 | ** have changed locally. |
| 275 | */ |
| 276 | if( vid ){ |
| 277 | find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0); |
| 278 | if( nChng ){ |
| 279 | for(i=0; i<nChng; i++){ |
| 280 | db_multi_exec( |
| 281 | "UPDATE fv" |
| 282 | " SET fnt=(SELECT name FROM filename WHERE fnid=%d)" |
| 283 | " WHERE fn=(SELECT name FROM filename WHERE fnid=%d) AND chnged", |
| 284 | aChng[i*2+1], aChng[i*2] |
| 285 | ); |
| 286 | } |
| 287 | fossil_free(aChng); |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | /* Add files found in the target version T but missing from the current |
| 292 | ** version V. |
| 293 | */ |
| 294 |
+11
-6
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -682,15 +682,20 @@ | ||
| 682 | 682 | |
| 683 | 683 | verify_all_options(); |
| 684 | 684 | if( g.argc==4 ){ |
| 685 | 685 | zSvcName = g.argv[3]; |
| 686 | 686 | }else if( g.argc>4 ){ |
| 687 | - fossil_fatal("to much arguments for create method."); | |
| 687 | + fossil_fatal("too many arguments for create method."); | |
| 688 | 688 | } |
| 689 | 689 | /* Process service creation specific options. */ |
| 690 | 690 | if( !zDisplay ){ |
| 691 | 691 | zDisplay = zSvcName; |
| 692 | + } | |
| 693 | + /* Per MSDN, the password parameter cannot be NULL. Must use empty | |
| 694 | + ** string instead (i.e. in the call to CreateServiceW). */ | |
| 695 | + if( !zPassword ){ | |
| 696 | + zPassword = ""; | |
| 692 | 697 | } |
| 693 | 698 | if( zStart ){ |
| 694 | 699 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 695 | 700 | dwStartType = SERVICE_AUTO_START; |
| 696 | 701 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| @@ -736,11 +741,11 @@ | ||
| 736 | 741 | SERVICE_ERROR_NORMAL, /* Error control */ |
| 737 | 742 | fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */ |
| 738 | 743 | NULL, /* Load ordering group */ |
| 739 | 744 | NULL, /* Tag value */ |
| 740 | 745 | NULL, /* Service dependencies */ |
| 741 | - fossil_utf8_to_unicode(zUsername), /* Service account */ | |
| 746 | + zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */ | |
| 742 | 747 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 743 | 748 | ); |
| 744 | 749 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 745 | 750 | /* Set the service description. */ |
| 746 | 751 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| @@ -756,11 +761,11 @@ | ||
| 756 | 761 | |
| 757 | 762 | verify_all_options(); |
| 758 | 763 | if( g.argc==4 ){ |
| 759 | 764 | zSvcName = g.argv[3]; |
| 760 | 765 | }else if( g.argc>4 ){ |
| 761 | - fossil_fatal("to much arguments for delete method."); | |
| 766 | + fossil_fatal("too many arguments for delete method."); | |
| 762 | 767 | } |
| 763 | 768 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 764 | 769 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 765 | 770 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 766 | 771 | SERVICE_ALL_ACCESS); |
| @@ -825,11 +830,11 @@ | ||
| 825 | 830 | |
| 826 | 831 | verify_all_options(); |
| 827 | 832 | if( g.argc==4 ){ |
| 828 | 833 | zSvcName = g.argv[3]; |
| 829 | 834 | }else if( g.argc>4 ){ |
| 830 | - fossil_fatal("to much arguments for show method."); | |
| 835 | + fossil_fatal("too many arguments for show method."); | |
| 831 | 836 | } |
| 832 | 837 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 833 | 838 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 834 | 839 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 835 | 840 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| @@ -907,11 +912,11 @@ | ||
| 907 | 912 | |
| 908 | 913 | verify_all_options(); |
| 909 | 914 | if( g.argc==4 ){ |
| 910 | 915 | zSvcName = g.argv[3]; |
| 911 | 916 | }else if( g.argc>4 ){ |
| 912 | - fossil_fatal("to much arguments for start method."); | |
| 917 | + fossil_fatal("too many arguments for start method."); | |
| 913 | 918 | } |
| 914 | 919 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 915 | 920 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 916 | 921 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 917 | 922 | SERVICE_ALL_ACCESS); |
| @@ -944,11 +949,11 @@ | ||
| 944 | 949 | |
| 945 | 950 | verify_all_options(); |
| 946 | 951 | if( g.argc==4 ){ |
| 947 | 952 | zSvcName = g.argv[3]; |
| 948 | 953 | }else if( g.argc>4 ){ |
| 949 | - fossil_fatal("to much arguments for stop method."); | |
| 954 | + fossil_fatal("too many arguments for stop method."); | |
| 950 | 955 | } |
| 951 | 956 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 952 | 957 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 953 | 958 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 954 | 959 | SERVICE_ALL_ACCESS); |
| 955 | 960 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -682,15 +682,20 @@ | |
| 682 | |
| 683 | verify_all_options(); |
| 684 | if( g.argc==4 ){ |
| 685 | zSvcName = g.argv[3]; |
| 686 | }else if( g.argc>4 ){ |
| 687 | fossil_fatal("to much arguments for create method."); |
| 688 | } |
| 689 | /* Process service creation specific options. */ |
| 690 | if( !zDisplay ){ |
| 691 | zDisplay = zSvcName; |
| 692 | } |
| 693 | if( zStart ){ |
| 694 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 695 | dwStartType = SERVICE_AUTO_START; |
| 696 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| @@ -736,11 +741,11 @@ | |
| 736 | SERVICE_ERROR_NORMAL, /* Error control */ |
| 737 | fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */ |
| 738 | NULL, /* Load ordering group */ |
| 739 | NULL, /* Tag value */ |
| 740 | NULL, /* Service dependencies */ |
| 741 | fossil_utf8_to_unicode(zUsername), /* Service account */ |
| 742 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 743 | ); |
| 744 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 745 | /* Set the service description. */ |
| 746 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| @@ -756,11 +761,11 @@ | |
| 756 | |
| 757 | verify_all_options(); |
| 758 | if( g.argc==4 ){ |
| 759 | zSvcName = g.argv[3]; |
| 760 | }else if( g.argc>4 ){ |
| 761 | fossil_fatal("to much arguments for delete method."); |
| 762 | } |
| 763 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 764 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 765 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 766 | SERVICE_ALL_ACCESS); |
| @@ -825,11 +830,11 @@ | |
| 825 | |
| 826 | verify_all_options(); |
| 827 | if( g.argc==4 ){ |
| 828 | zSvcName = g.argv[3]; |
| 829 | }else if( g.argc>4 ){ |
| 830 | fossil_fatal("to much arguments for show method."); |
| 831 | } |
| 832 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 833 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 834 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 835 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| @@ -907,11 +912,11 @@ | |
| 907 | |
| 908 | verify_all_options(); |
| 909 | if( g.argc==4 ){ |
| 910 | zSvcName = g.argv[3]; |
| 911 | }else if( g.argc>4 ){ |
| 912 | fossil_fatal("to much arguments for start method."); |
| 913 | } |
| 914 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 915 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 916 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 917 | SERVICE_ALL_ACCESS); |
| @@ -944,11 +949,11 @@ | |
| 944 | |
| 945 | verify_all_options(); |
| 946 | if( g.argc==4 ){ |
| 947 | zSvcName = g.argv[3]; |
| 948 | }else if( g.argc>4 ){ |
| 949 | fossil_fatal("to much arguments for stop method."); |
| 950 | } |
| 951 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 952 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 953 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 954 | SERVICE_ALL_ACCESS); |
| 955 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -682,15 +682,20 @@ | |
| 682 | |
| 683 | verify_all_options(); |
| 684 | if( g.argc==4 ){ |
| 685 | zSvcName = g.argv[3]; |
| 686 | }else if( g.argc>4 ){ |
| 687 | fossil_fatal("too many arguments for create method."); |
| 688 | } |
| 689 | /* Process service creation specific options. */ |
| 690 | if( !zDisplay ){ |
| 691 | zDisplay = zSvcName; |
| 692 | } |
| 693 | /* Per MSDN, the password parameter cannot be NULL. Must use empty |
| 694 | ** string instead (i.e. in the call to CreateServiceW). */ |
| 695 | if( !zPassword ){ |
| 696 | zPassword = ""; |
| 697 | } |
| 698 | if( zStart ){ |
| 699 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 700 | dwStartType = SERVICE_AUTO_START; |
| 701 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| @@ -736,11 +741,11 @@ | |
| 741 | SERVICE_ERROR_NORMAL, /* Error control */ |
| 742 | fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */ |
| 743 | NULL, /* Load ordering group */ |
| 744 | NULL, /* Tag value */ |
| 745 | NULL, /* Service dependencies */ |
| 746 | zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */ |
| 747 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 748 | ); |
| 749 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 750 | /* Set the service description. */ |
| 751 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| @@ -756,11 +761,11 @@ | |
| 761 | |
| 762 | verify_all_options(); |
| 763 | if( g.argc==4 ){ |
| 764 | zSvcName = g.argv[3]; |
| 765 | }else if( g.argc>4 ){ |
| 766 | fossil_fatal("too many arguments for delete method."); |
| 767 | } |
| 768 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 769 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 770 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 771 | SERVICE_ALL_ACCESS); |
| @@ -825,11 +830,11 @@ | |
| 830 | |
| 831 | verify_all_options(); |
| 832 | if( g.argc==4 ){ |
| 833 | zSvcName = g.argv[3]; |
| 834 | }else if( g.argc>4 ){ |
| 835 | fossil_fatal("too many arguments for show method."); |
| 836 | } |
| 837 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 838 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 839 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 840 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| @@ -907,11 +912,11 @@ | |
| 912 | |
| 913 | verify_all_options(); |
| 914 | if( g.argc==4 ){ |
| 915 | zSvcName = g.argv[3]; |
| 916 | }else if( g.argc>4 ){ |
| 917 | fossil_fatal("too many arguments for start method."); |
| 918 | } |
| 919 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 920 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 921 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 922 | SERVICE_ALL_ACCESS); |
| @@ -944,11 +949,11 @@ | |
| 949 | |
| 950 | verify_all_options(); |
| 951 | if( g.argc==4 ){ |
| 952 | zSvcName = g.argv[3]; |
| 953 | }else if( g.argc>4 ){ |
| 954 | fossil_fatal("too many arguments for stop method."); |
| 955 | } |
| 956 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 957 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 958 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 959 | SERVICE_ALL_ACCESS); |
| 960 |
+2
-1
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -700,11 +700,12 @@ | ||
| 700 | 700 | blob_appendf(&deleteWhere, ",%d", rid); |
| 701 | 701 | } |
| 702 | 702 | } |
| 703 | 703 | db_finalize(&q); |
| 704 | 704 | db_multi_exec( |
| 705 | - "DELETE FROM unclustered WHERE rid NOT IN (0 %s)", | |
| 705 | + "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" | |
| 706 | + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", | |
| 706 | 707 | blob_str(&deleteWhere) |
| 707 | 708 | ); |
| 708 | 709 | blob_reset(&deleteWhere); |
| 709 | 710 | if( nRow>0 ){ |
| 710 | 711 | md5sum_blob(&cluster, &cksum); |
| 711 | 712 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -700,11 +700,12 @@ | |
| 700 | blob_appendf(&deleteWhere, ",%d", rid); |
| 701 | } |
| 702 | } |
| 703 | db_finalize(&q); |
| 704 | db_multi_exec( |
| 705 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)", |
| 706 | blob_str(&deleteWhere) |
| 707 | ); |
| 708 | blob_reset(&deleteWhere); |
| 709 | if( nRow>0 ){ |
| 710 | md5sum_blob(&cluster, &cksum); |
| 711 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -700,11 +700,12 @@ | |
| 700 | blob_appendf(&deleteWhere, ",%d", rid); |
| 701 | } |
| 702 | } |
| 703 | db_finalize(&q); |
| 704 | db_multi_exec( |
| 705 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 706 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 707 | blob_str(&deleteWhere) |
| 708 | ); |
| 709 | blob_reset(&deleteWhere); |
| 710 | if( nRow>0 ){ |
| 711 | md5sum_blob(&cluster, &cksum); |
| 712 |
+21
-7
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -393,10 +393,14 @@ | ||
| 393 | 393 | int rid; |
| 394 | 394 | Blob zip; |
| 395 | 395 | const char *zName; |
| 396 | 396 | zName = find_option("name", 0, 1); |
| 397 | 397 | db_find_and_open_repository(0, 0); |
| 398 | + | |
| 399 | + /* We should be done with options.. */ | |
| 400 | + verify_all_options(); | |
| 401 | + | |
| 398 | 402 | if( g.argc!=4 ){ |
| 399 | 403 | usage("VERSION OUTPUTFILE"); |
| 400 | 404 | } |
| 401 | 405 | rid = name_to_typed_rid(g.argv[2],"ci"); |
| 402 | 406 | if( zName==0 ){ |
| @@ -421,15 +425,17 @@ | ||
| 421 | 425 | ** Generate a ZIP archive for the baseline. |
| 422 | 426 | ** Return that ZIP archive as the HTTP reply content. |
| 423 | 427 | ** |
| 424 | 428 | ** Optional URL Parameters: |
| 425 | 429 | ** |
| 426 | -** - name=base name of the output file. Defaults to | |
| 427 | -** something project/version-specific. | |
| 430 | +** - name=NAME[.zip] is the name of the output file. Defaults to | |
| 431 | +** something project/version-specific. The base part of the | |
| 432 | +** name, up to the last dot, is used as the top-most directory | |
| 433 | +** name in the output file. | |
| 428 | 434 | ** |
| 429 | 435 | ** - uuid=the version to zip (may be a tag/branch name). |
| 430 | -** Defaults to trunk. | |
| 436 | +** Defaults to "trunk". | |
| 431 | 437 | ** |
| 432 | 438 | */ |
| 433 | 439 | void baseline_zip_page(void){ |
| 434 | 440 | int rid; |
| 435 | 441 | char *zName, *zRid; |
| @@ -442,14 +448,22 @@ | ||
| 442 | 448 | load_control(); |
| 443 | 449 | zName = mprintf("%s", PD("name","")); |
| 444 | 450 | nName = strlen(zName); |
| 445 | 451 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 446 | 452 | nRid = strlen(zRid); |
| 447 | - for(nName=strlen(zName)-1; nName>5; nName--){ | |
| 448 | - if( zName[nName]=='.' ){ | |
| 449 | - zName[nName] = 0; | |
| 450 | - break; | |
| 453 | + if( nName>4 && fossil_strcmp(&zName[nName-4], ".zip")==0 ){ | |
| 454 | + /* Special case: Remove the ".zip" suffix. */ | |
| 455 | + nName -= 4; | |
| 456 | + zName[nName] = 0; | |
| 457 | + }else{ | |
| 458 | + /* If the file suffix is not ".zip" then just remove the | |
| 459 | + ** suffix up to and including the last "." */ | |
| 460 | + for(nName=strlen(zName)-1; nName>5; nName--){ | |
| 461 | + if( zName[nName]=='.' ){ | |
| 462 | + zName[nName] = 0; | |
| 463 | + break; | |
| 464 | + } | |
| 451 | 465 | } |
| 452 | 466 | } |
| 453 | 467 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 454 | 468 | if( rid==0 ){ |
| 455 | 469 | @ Not found |
| 456 | 470 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -393,10 +393,14 @@ | |
| 393 | int rid; |
| 394 | Blob zip; |
| 395 | const char *zName; |
| 396 | zName = find_option("name", 0, 1); |
| 397 | db_find_and_open_repository(0, 0); |
| 398 | if( g.argc!=4 ){ |
| 399 | usage("VERSION OUTPUTFILE"); |
| 400 | } |
| 401 | rid = name_to_typed_rid(g.argv[2],"ci"); |
| 402 | if( zName==0 ){ |
| @@ -421,15 +425,17 @@ | |
| 421 | ** Generate a ZIP archive for the baseline. |
| 422 | ** Return that ZIP archive as the HTTP reply content. |
| 423 | ** |
| 424 | ** Optional URL Parameters: |
| 425 | ** |
| 426 | ** - name=base name of the output file. Defaults to |
| 427 | ** something project/version-specific. |
| 428 | ** |
| 429 | ** - uuid=the version to zip (may be a tag/branch name). |
| 430 | ** Defaults to trunk. |
| 431 | ** |
| 432 | */ |
| 433 | void baseline_zip_page(void){ |
| 434 | int rid; |
| 435 | char *zName, *zRid; |
| @@ -442,14 +448,22 @@ | |
| 442 | load_control(); |
| 443 | zName = mprintf("%s", PD("name","")); |
| 444 | nName = strlen(zName); |
| 445 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 446 | nRid = strlen(zRid); |
| 447 | for(nName=strlen(zName)-1; nName>5; nName--){ |
| 448 | if( zName[nName]=='.' ){ |
| 449 | zName[nName] = 0; |
| 450 | break; |
| 451 | } |
| 452 | } |
| 453 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 454 | if( rid==0 ){ |
| 455 | @ Not found |
| 456 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -393,10 +393,14 @@ | |
| 393 | int rid; |
| 394 | Blob zip; |
| 395 | const char *zName; |
| 396 | zName = find_option("name", 0, 1); |
| 397 | db_find_and_open_repository(0, 0); |
| 398 | |
| 399 | /* We should be done with options.. */ |
| 400 | verify_all_options(); |
| 401 | |
| 402 | if( g.argc!=4 ){ |
| 403 | usage("VERSION OUTPUTFILE"); |
| 404 | } |
| 405 | rid = name_to_typed_rid(g.argv[2],"ci"); |
| 406 | if( zName==0 ){ |
| @@ -421,15 +425,17 @@ | |
| 425 | ** Generate a ZIP archive for the baseline. |
| 426 | ** Return that ZIP archive as the HTTP reply content. |
| 427 | ** |
| 428 | ** Optional URL Parameters: |
| 429 | ** |
| 430 | ** - name=NAME[.zip] is the name of the output file. Defaults to |
| 431 | ** something project/version-specific. The base part of the |
| 432 | ** name, up to the last dot, is used as the top-most directory |
| 433 | ** name in the output file. |
| 434 | ** |
| 435 | ** - uuid=the version to zip (may be a tag/branch name). |
| 436 | ** Defaults to "trunk". |
| 437 | ** |
| 438 | */ |
| 439 | void baseline_zip_page(void){ |
| 440 | int rid; |
| 441 | char *zName, *zRid; |
| @@ -442,14 +448,22 @@ | |
| 448 | load_control(); |
| 449 | zName = mprintf("%s", PD("name","")); |
| 450 | nName = strlen(zName); |
| 451 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 452 | nRid = strlen(zRid); |
| 453 | if( nName>4 && fossil_strcmp(&zName[nName-4], ".zip")==0 ){ |
| 454 | /* Special case: Remove the ".zip" suffix. */ |
| 455 | nName -= 4; |
| 456 | zName[nName] = 0; |
| 457 | }else{ |
| 458 | /* If the file suffix is not ".zip" then just remove the |
| 459 | ** suffix up to and including the last "." */ |
| 460 | for(nName=strlen(zName)-1; nName>5; nName--){ |
| 461 | if( zName[nName]=='.' ){ |
| 462 | zName[nName] = 0; |
| 463 | break; |
| 464 | } |
| 465 | } |
| 466 | } |
| 467 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 468 | if( rid==0 ){ |
| 469 | @ Not found |
| 470 |
+229
-33
| --- test/comment.test | ||
| +++ test/comment.test | ||
| @@ -26,97 +26,293 @@ | ||
| 26 | 26 | fossil test-comment-format --decode "" "" |
| 27 | 27 | test comment-2 {$RESULT eq "\n(1 lines output)"} |
| 28 | 28 | |
| 29 | 29 | ############################################################################### |
| 30 | 30 | |
| 31 | -fossil test-comment-format " " "this is a short comment." 26 | |
| 31 | +fossil test-comment-format --width 26 " " "this is a short comment." | |
| 32 | 32 | test comment-3 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 33 | 33 | |
| 34 | 34 | ############################################################################### |
| 35 | 35 | |
| 36 | -fossil test-comment-format --decode " " "this is a short comment." 26 | |
| 36 | +fossil test-comment-format --width 26 --decode " " "this is a short comment." | |
| 37 | 37 | test comment-4 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 38 | 38 | |
| 39 | 39 | ############################################################################### |
| 40 | 40 | |
| 41 | -fossil test-comment-format "*PREFIX* " "this is a short comment." 25 | |
| 42 | -test comment-5 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} | |
| 41 | +fossil test-comment-format --width 26 "*PREFIX* " "this is a short comment." | |
| 42 | +test comment-5 {$RESULT eq "*PREFIX* this is a short c\n omment.\n(2 lines output)"} | |
| 43 | 43 | |
| 44 | 44 | ############################################################################### |
| 45 | 45 | |
| 46 | -fossil test-comment-format --decode "*PREFIX* " "this is a short comment." 25 | |
| 47 | -test comment-6 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} | |
| 46 | +fossil test-comment-format --width 26 --decode "*PREFIX* " "this is a short comment." | |
| 47 | +test comment-6 {$RESULT eq "*PREFIX* this is a short c\n omment.\n(2 lines output)"} | |
| 48 | 48 | |
| 49 | 49 | ############################################################################### |
| 50 | 50 | |
| 51 | -fossil test-comment-format "" "this\\sis\\sa\\sshort\\scomment." 26 | |
| 51 | +fossil test-comment-format --width 26 "" "this\\sis\\sa\\sshort\\scomment." | |
| 52 | 52 | test comment-7 {$RESULT eq "this\\sis\\sa\\sshort\\scommen\nt.\n(2 lines output)"} |
| 53 | 53 | |
| 54 | 54 | ############################################################################### |
| 55 | 55 | |
| 56 | -fossil test-comment-format --decode "" "this\\sis\\sa\\sshort\\scomment." 26 | |
| 56 | +fossil test-comment-format --width 26 --decode "" "this\\sis\\sa\\sshort\\scomment." | |
| 57 | 57 | test comment-8 {$RESULT eq "this is a short comment.\n(1 lines output)"} |
| 58 | 58 | |
| 59 | 59 | ############################################################################### |
| 60 | 60 | |
| 61 | -fossil test-comment-format --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." 78 | |
| 62 | -test comment-9 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly.\n(2 lines output)"} | |
| 61 | +fossil test-comment-format --width 78 --decode --trimspace "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." | |
| 62 | +test comment-9 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test is\n working correctly.\n(2 lines output)"} | |
| 63 | 63 | |
| 64 | 64 | ############################################################################### |
| 65 | 65 | |
| 66 | -fossil test-comment-format --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" 78 | |
| 67 | -test comment-10 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly. more text here describing the issue. another\n line\n here.................................................................\n .................*\n(5 lines output)"} | |
| 66 | +fossil test-comment-format --width 78 --decode --trimspace "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" | |
| 67 | +test comment-10 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test is\n working correctly. more text here describing the issue.\n another line here....................................................\n ..............................*\n(4 lines output)"} | |
| 68 | 68 | |
| 69 | 69 | ############################################################################### |
| 70 | 70 | |
| 71 | -fossil test-comment-format "HH:MM:SS " "....................................................................................*" 78 | |
| 71 | +fossil test-comment-format --width 78 "HH:MM:SS " "....................................................................................*" | |
| 72 | 72 | test comment-11 {$RESULT eq "HH:MM:SS .....................................................................\n ...............*\n(2 lines output)"} |
| 73 | 73 | |
| 74 | 74 | ############################################################################### |
| 75 | 75 | |
| 76 | -fossil test-comment-format "HH:MM:SS " ".....................................................................*" 78 | |
| 76 | +fossil test-comment-format --width 78 "HH:MM:SS " ".....................................................................*" 78 | |
| 77 | 77 | test comment-12 {$RESULT eq "HH:MM:SS .....................................................................\n *\n(2 lines output)"} |
| 78 | 78 | |
| 79 | 79 | ############################################################################### |
| 80 | 80 | |
| 81 | -fossil test-comment-format "*TEST* " "this\tis a test." 26 | |
| 82 | -test comment-13 {$RESULT eq "*TEST* this is a test.\n(1 lines output)"} | |
| 81 | +fossil test-comment-format --width 26 "*TEST* " "this\tis a test." | |
| 82 | +test comment-13 {$RESULT eq "*TEST* this\tis a te\n st.\n(2 lines output)"} | |
| 83 | 83 | |
| 84 | 84 | ############################################################################### |
| 85 | 85 | |
| 86 | -fossil test-comment-format "*TEST* " "this is a test......................................................................................................................." 60 | |
| 87 | -test comment-14 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 86 | +fossil test-comment-format --width 60 "*TEST* " "this is a test......................................................................................................................." | |
| 87 | +test comment-14 {$RESULT eq "*TEST* this is a test.......................................\n .....................................................\n ...........................\n(3 lines output)"} | |
| 88 | 88 | |
| 89 | 89 | ############################################################################### |
| 90 | 90 | |
| 91 | -fossil test-comment-format --wordbreak "*TEST* " "this is a test......................................................................................................................." 60 | |
| 91 | +fossil test-comment-format --width 60 --wordbreak "*TEST* " "this is a test......................................................................................................................." | |
| 92 | 92 | test comment-15 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 93 | 93 | |
| 94 | 94 | ############################################################################### |
| 95 | 95 | |
| 96 | -fossil test-comment-format "*TEST* " "this is a test......................................................................................................................." 60 | |
| 97 | -test comment-16 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 96 | +fossil test-comment-format --width 60 "*TEST* " "this is a test......................................................................................................................." | |
| 97 | +test comment-16 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 98 | + | |
| 99 | +############################################################################### | |
| 100 | + | |
| 101 | +fossil test-comment-format --width 60 --wordbreak "*TEST* " "this is a test......................................................................................................................." | |
| 102 | +test comment-17 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 98 | 103 | |
| 99 | 104 | ############################################################################### |
| 100 | 105 | |
| 101 | -fossil test-comment-format --wordbreak "*TEST* " "this is a test......................................................................................................................." 60 | |
| 102 | -test comment-17 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 106 | +fossil test-comment-format --width 60 "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 107 | +test comment-18 {$RESULT eq "*TEST* one two three four five six seven eight nine ten elev\n en twelve\n(2 lines output)"} | |
| 103 | 108 | |
| 104 | 109 | ############################################################################### |
| 105 | 110 | |
| 106 | -fossil test-comment-format "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 | |
| 107 | -test comment-18 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 108 | - | |
| 109 | -############################################################################### | |
| 110 | - | |
| 111 | -fossil test-comment-format --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 | |
| 111 | +fossil test-comment-format --width 60 --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 112 | 112 | test comment-19 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 113 | 113 | |
| 114 | 114 | ############################################################################### |
| 115 | 115 | |
| 116 | -fossil test-comment-format "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 | |
| 117 | -test comment-20 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 116 | +fossil test-comment-format --width 60 "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 117 | +test comment-20 {$RESULT eq "*TEST* one two three four five\n six seven eight nine ten\n eleven twelve\n(3 lines output)"} | |
| 118 | + | |
| 119 | +############################################################################### | |
| 120 | + | |
| 121 | +fossil test-comment-format --width 60 --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 122 | +test comment-21 {$RESULT eq "*TEST* one two three four five\n six seven eight nine ten\n eleven twelve\n(3 lines output)"} | |
| 123 | + | |
| 124 | +############################################################################### | |
| 125 | + | |
| 126 | +fossil test-comment-format --legacy "" "" | |
| 127 | +test comment-22 {$RESULT eq "\n(1 lines output)"} | |
| 128 | + | |
| 129 | +############################################################################### | |
| 130 | + | |
| 131 | +fossil test-comment-format --legacy --decode "" "" | |
| 132 | +test comment-23 {$RESULT eq "\n(1 lines output)"} | |
| 133 | + | |
| 134 | +############################################################################### | |
| 135 | + | |
| 136 | +fossil test-comment-format --width 26 --legacy " " "this is a short comment." | |
| 137 | +test comment-24 {$RESULT eq " this is a short comment.\n(1 lines output)"} | |
| 138 | + | |
| 139 | +############################################################################### | |
| 140 | + | |
| 141 | +fossil test-comment-format --width 26 --legacy --decode " " "this is a short comment." | |
| 142 | +test comment-25 {$RESULT eq " this is a short comment.\n(1 lines output)"} | |
| 143 | + | |
| 144 | +############################################################################### | |
| 145 | + | |
| 146 | +fossil test-comment-format --width 25 --legacy "*PREFIX* " "this is a short comment." | |
| 147 | +test comment-26 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} | |
| 148 | + | |
| 149 | +############################################################################### | |
| 150 | + | |
| 151 | +fossil test-comment-format --width 25 --legacy --decode "*PREFIX* " "this is a short comment." | |
| 152 | +test comment-27 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} | |
| 153 | + | |
| 154 | +############################################################################### | |
| 155 | + | |
| 156 | +fossil test-comment-format --width 26 --legacy "" "this\\sis\\sa\\sshort\\scomment." | |
| 157 | +test comment-28 {$RESULT eq "this\\sis\\sa\\sshort\\scommen\nt.\n(2 lines output)"} | |
| 158 | + | |
| 159 | +############################################################################### | |
| 160 | + | |
| 161 | +fossil test-comment-format --width 26 --legacy --decode "" "this\\sis\\sa\\sshort\\scomment." | |
| 162 | +test comment-29 {$RESULT eq "this is a short comment.\n(1 lines output)"} | |
| 163 | + | |
| 164 | +############################################################################### | |
| 165 | + | |
| 166 | +fossil test-comment-format --width 78 --legacy --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." | |
| 167 | +test comment-30 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly.\n(2 lines output)"} | |
| 168 | + | |
| 169 | +############################################################################### | |
| 170 | + | |
| 171 | +fossil test-comment-format --width 78 --legacy --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" | |
| 172 | +test comment-31 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly. more text here describing the issue. another\n line\n here.................................................................\n .................*\n(5 lines output)"} | |
| 173 | + | |
| 174 | +############################################################################### | |
| 175 | + | |
| 176 | +fossil test-comment-format --width 78 --legacy "HH:MM:SS " "....................................................................................*" | |
| 177 | +test comment-32 {$RESULT eq "HH:MM:SS .....................................................................\n ...............*\n(2 lines output)"} | |
| 178 | + | |
| 179 | +############################################################################### | |
| 180 | + | |
| 181 | +fossil test-comment-format --width 78 --legacy "HH:MM:SS " ".....................................................................*" | |
| 182 | +test comment-33 {$RESULT eq "HH:MM:SS .....................................................................\n *\n(2 lines output)"} | |
| 183 | + | |
| 184 | +############################################################################### | |
| 185 | + | |
| 186 | +fossil test-comment-format --width 26 --legacy "*TEST* " "this\tis a test." | |
| 187 | +test comment-34 {$RESULT eq "*TEST* this is a test.\n(1 lines output)"} | |
| 188 | + | |
| 189 | +############################################################################### | |
| 190 | + | |
| 191 | +fossil test-comment-format --width 60 --legacy "*TEST* " "this is a test......................................................................................................................." | |
| 192 | +test comment-35 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 193 | + | |
| 194 | +############################################################################### | |
| 195 | + | |
| 196 | +fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "this is a test......................................................................................................................." | |
| 197 | +test comment-36 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 198 | + | |
| 199 | +############################################################################### | |
| 200 | + | |
| 201 | +fossil test-comment-format --width 60 --legacy "*TEST* " "this is a test......................................................................................................................." | |
| 202 | +test comment-37 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 203 | + | |
| 204 | +############################################################################### | |
| 205 | + | |
| 206 | +fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "this is a test......................................................................................................................." | |
| 207 | +test comment-38 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} | |
| 208 | + | |
| 209 | +############################################################################### | |
| 210 | + | |
| 211 | +fossil test-comment-format --width 60 --legacy "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 212 | +test comment-39 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 213 | + | |
| 214 | +############################################################################### | |
| 215 | + | |
| 216 | +fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 217 | +test comment-40 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 218 | + | |
| 219 | +############################################################################### | |
| 220 | + | |
| 221 | +fossil test-comment-format --width 60 --legacy "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 222 | +test comment-41 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 223 | + | |
| 224 | +############################################################################### | |
| 225 | + | |
| 226 | +fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" | |
| 227 | +test comment-42 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 228 | + | |
| 229 | +############################################################################### | |
| 230 | + | |
| 231 | +set orig "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\\nxxxxxxx." | |
| 232 | +fossil test-comment-format --width 73 --decode --origbreak "" $orig | |
| 233 | +test comment-43 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 234 | + | |
| 235 | +############################################################################### | |
| 236 | + | |
| 237 | +fossil test-comment-format --width 73 --decode --origbreak "" $orig $orig | |
| 238 | +test comment-44 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 239 | + | |
| 240 | +############################################################################### | |
| 241 | + | |
| 242 | +fossil test-comment-format --width 73 --decode --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig | |
| 243 | +test comment-45 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} | |
| 244 | + | |
| 245 | +############################################################################### | |
| 246 | + | |
| 247 | +fossil test-comment-format --width 82 --indent 9 --decode --origbreak " " $orig | |
| 248 | +test comment-46 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 249 | + | |
| 250 | +############################################################################### | |
| 251 | + | |
| 252 | +fossil test-comment-format --width 82 --indent 9 --decode --origbreak " " $orig $orig | |
| 253 | +test comment-47 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 254 | + | |
| 255 | +############################################################################### | |
| 256 | + | |
| 257 | +fossil test-comment-format --width 82 --indent 9 --decode --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig | |
| 258 | +test comment-48 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} | |
| 259 | + | |
| 260 | +############################################################################### | |
| 261 | + | |
| 262 | +fossil test-comment-format --width 72 --decode --trimspace --origbreak "" $orig | |
| 263 | +test comment-49 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 264 | + | |
| 265 | +############################################################################### | |
| 266 | + | |
| 267 | +fossil test-comment-format --width 72 --decode --trimspace --origbreak "" $orig $orig | |
| 268 | +test comment-50 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 269 | + | |
| 270 | +############################################################################### | |
| 271 | + | |
| 272 | +fossil test-comment-format --width 72 --decode --trimspace --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig | |
| 273 | +test comment-51 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} | |
| 274 | + | |
| 275 | +############################################################################### | |
| 276 | + | |
| 277 | +fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak " " $orig | |
| 278 | +test comment-52 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 279 | + | |
| 280 | +############################################################################### | |
| 281 | + | |
| 282 | +fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak " " $orig $orig | |
| 283 | +test comment-53 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 284 | + | |
| 285 | +############################################################################### | |
| 286 | + | |
| 287 | +fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig | |
| 288 | +test comment-54 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} | |
| 289 | + | |
| 290 | +############################################################################### | |
| 291 | + | |
| 292 | +fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" $orig | |
| 293 | +test comment-55 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 294 | + | |
| 295 | +############################################################################### | |
| 296 | + | |
| 297 | +fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" $orig $orig | |
| 298 | +test comment-56 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} | |
| 299 | + | |
| 300 | +############################################################################### | |
| 301 | + | |
| 302 | +fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig | |
| 303 | +test comment-57 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} | |
| 304 | + | |
| 305 | +############################################################################### | |
| 306 | + | |
| 307 | +fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak " " $orig | |
| 308 | +test comment-58 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 309 | + | |
| 310 | +############################################################################### | |
| 311 | + | |
| 312 | +fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak " " $orig $orig | |
| 313 | +test comment-59 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} | |
| 118 | 314 | |
| 119 | 315 | ############################################################################### |
| 120 | 316 | |
| 121 | -fossil test-comment-format --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 | |
| 122 | -test comment-21 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} | |
| 317 | +fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig | |
| 318 | +test comment-60 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} | |
| 123 | 319 |
| --- test/comment.test | |
| +++ test/comment.test | |
| @@ -26,97 +26,293 @@ | |
| 26 | fossil test-comment-format --decode "" "" |
| 27 | test comment-2 {$RESULT eq "\n(1 lines output)"} |
| 28 | |
| 29 | ############################################################################### |
| 30 | |
| 31 | fossil test-comment-format " " "this is a short comment." 26 |
| 32 | test comment-3 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 33 | |
| 34 | ############################################################################### |
| 35 | |
| 36 | fossil test-comment-format --decode " " "this is a short comment." 26 |
| 37 | test comment-4 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 38 | |
| 39 | ############################################################################### |
| 40 | |
| 41 | fossil test-comment-format "*PREFIX* " "this is a short comment." 25 |
| 42 | test comment-5 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} |
| 43 | |
| 44 | ############################################################################### |
| 45 | |
| 46 | fossil test-comment-format --decode "*PREFIX* " "this is a short comment." 25 |
| 47 | test comment-6 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} |
| 48 | |
| 49 | ############################################################################### |
| 50 | |
| 51 | fossil test-comment-format "" "this\\sis\\sa\\sshort\\scomment." 26 |
| 52 | test comment-7 {$RESULT eq "this\\sis\\sa\\sshort\\scommen\nt.\n(2 lines output)"} |
| 53 | |
| 54 | ############################################################################### |
| 55 | |
| 56 | fossil test-comment-format --decode "" "this\\sis\\sa\\sshort\\scomment." 26 |
| 57 | test comment-8 {$RESULT eq "this is a short comment.\n(1 lines output)"} |
| 58 | |
| 59 | ############################################################################### |
| 60 | |
| 61 | fossil test-comment-format --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." 78 |
| 62 | test comment-9 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly.\n(2 lines output)"} |
| 63 | |
| 64 | ############################################################################### |
| 65 | |
| 66 | fossil test-comment-format --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" 78 |
| 67 | test comment-10 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly. more text here describing the issue. another\n line\n here.................................................................\n .................*\n(5 lines output)"} |
| 68 | |
| 69 | ############################################################################### |
| 70 | |
| 71 | fossil test-comment-format "HH:MM:SS " "....................................................................................*" 78 |
| 72 | test comment-11 {$RESULT eq "HH:MM:SS .....................................................................\n ...............*\n(2 lines output)"} |
| 73 | |
| 74 | ############################################################################### |
| 75 | |
| 76 | fossil test-comment-format "HH:MM:SS " ".....................................................................*" 78 |
| 77 | test comment-12 {$RESULT eq "HH:MM:SS .....................................................................\n *\n(2 lines output)"} |
| 78 | |
| 79 | ############################################################################### |
| 80 | |
| 81 | fossil test-comment-format "*TEST* " "this\tis a test." 26 |
| 82 | test comment-13 {$RESULT eq "*TEST* this is a test.\n(1 lines output)"} |
| 83 | |
| 84 | ############################################################################### |
| 85 | |
| 86 | fossil test-comment-format "*TEST* " "this is a test......................................................................................................................." 60 |
| 87 | test comment-14 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 88 | |
| 89 | ############################################################################### |
| 90 | |
| 91 | fossil test-comment-format --wordbreak "*TEST* " "this is a test......................................................................................................................." 60 |
| 92 | test comment-15 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 93 | |
| 94 | ############################################################################### |
| 95 | |
| 96 | fossil test-comment-format "*TEST* " "this is a test......................................................................................................................." 60 |
| 97 | test comment-16 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 98 | |
| 99 | ############################################################################### |
| 100 | |
| 101 | fossil test-comment-format --wordbreak "*TEST* " "this is a test......................................................................................................................." 60 |
| 102 | test comment-17 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 103 | |
| 104 | ############################################################################### |
| 105 | |
| 106 | fossil test-comment-format "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 |
| 107 | test comment-18 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 108 | |
| 109 | ############################################################################### |
| 110 | |
| 111 | fossil test-comment-format --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 |
| 112 | test comment-19 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 113 | |
| 114 | ############################################################################### |
| 115 | |
| 116 | fossil test-comment-format "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 |
| 117 | test comment-20 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 118 | |
| 119 | ############################################################################### |
| 120 | |
| 121 | fossil test-comment-format --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" 60 |
| 122 | test comment-21 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 123 |
| --- test/comment.test | |
| +++ test/comment.test | |
| @@ -26,97 +26,293 @@ | |
| 26 | fossil test-comment-format --decode "" "" |
| 27 | test comment-2 {$RESULT eq "\n(1 lines output)"} |
| 28 | |
| 29 | ############################################################################### |
| 30 | |
| 31 | fossil test-comment-format --width 26 " " "this is a short comment." |
| 32 | test comment-3 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 33 | |
| 34 | ############################################################################### |
| 35 | |
| 36 | fossil test-comment-format --width 26 --decode " " "this is a short comment." |
| 37 | test comment-4 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 38 | |
| 39 | ############################################################################### |
| 40 | |
| 41 | fossil test-comment-format --width 26 "*PREFIX* " "this is a short comment." |
| 42 | test comment-5 {$RESULT eq "*PREFIX* this is a short c\n omment.\n(2 lines output)"} |
| 43 | |
| 44 | ############################################################################### |
| 45 | |
| 46 | fossil test-comment-format --width 26 --decode "*PREFIX* " "this is a short comment." |
| 47 | test comment-6 {$RESULT eq "*PREFIX* this is a short c\n omment.\n(2 lines output)"} |
| 48 | |
| 49 | ############################################################################### |
| 50 | |
| 51 | fossil test-comment-format --width 26 "" "this\\sis\\sa\\sshort\\scomment." |
| 52 | test comment-7 {$RESULT eq "this\\sis\\sa\\sshort\\scommen\nt.\n(2 lines output)"} |
| 53 | |
| 54 | ############################################################################### |
| 55 | |
| 56 | fossil test-comment-format --width 26 --decode "" "this\\sis\\sa\\sshort\\scomment." |
| 57 | test comment-8 {$RESULT eq "this is a short comment.\n(1 lines output)"} |
| 58 | |
| 59 | ############################################################################### |
| 60 | |
| 61 | fossil test-comment-format --width 78 --decode --trimspace "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." |
| 62 | test comment-9 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test is\n working correctly.\n(2 lines output)"} |
| 63 | |
| 64 | ############################################################################### |
| 65 | |
| 66 | fossil test-comment-format --width 78 --decode --trimspace "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" |
| 67 | test comment-10 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test is\n working correctly. more text here describing the issue.\n another line here....................................................\n ..............................*\n(4 lines output)"} |
| 68 | |
| 69 | ############################################################################### |
| 70 | |
| 71 | fossil test-comment-format --width 78 "HH:MM:SS " "....................................................................................*" |
| 72 | test comment-11 {$RESULT eq "HH:MM:SS .....................................................................\n ...............*\n(2 lines output)"} |
| 73 | |
| 74 | ############################################################################### |
| 75 | |
| 76 | fossil test-comment-format --width 78 "HH:MM:SS " ".....................................................................*" 78 |
| 77 | test comment-12 {$RESULT eq "HH:MM:SS .....................................................................\n *\n(2 lines output)"} |
| 78 | |
| 79 | ############################################################################### |
| 80 | |
| 81 | fossil test-comment-format --width 26 "*TEST* " "this\tis a test." |
| 82 | test comment-13 {$RESULT eq "*TEST* this\tis a te\n st.\n(2 lines output)"} |
| 83 | |
| 84 | ############################################################################### |
| 85 | |
| 86 | fossil test-comment-format --width 60 "*TEST* " "this is a test......................................................................................................................." |
| 87 | test comment-14 {$RESULT eq "*TEST* this is a test.......................................\n .....................................................\n ...........................\n(3 lines output)"} |
| 88 | |
| 89 | ############################################################################### |
| 90 | |
| 91 | fossil test-comment-format --width 60 --wordbreak "*TEST* " "this is a test......................................................................................................................." |
| 92 | test comment-15 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 93 | |
| 94 | ############################################################################### |
| 95 | |
| 96 | fossil test-comment-format --width 60 "*TEST* " "this is a test......................................................................................................................." |
| 97 | test comment-16 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 98 | |
| 99 | ############################################################################### |
| 100 | |
| 101 | fossil test-comment-format --width 60 --wordbreak "*TEST* " "this is a test......................................................................................................................." |
| 102 | test comment-17 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 103 | |
| 104 | ############################################################################### |
| 105 | |
| 106 | fossil test-comment-format --width 60 "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 107 | test comment-18 {$RESULT eq "*TEST* one two three four five six seven eight nine ten elev\n en twelve\n(2 lines output)"} |
| 108 | |
| 109 | ############################################################################### |
| 110 | |
| 111 | fossil test-comment-format --width 60 --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 112 | test comment-19 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 113 | |
| 114 | ############################################################################### |
| 115 | |
| 116 | fossil test-comment-format --width 60 "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 117 | test comment-20 {$RESULT eq "*TEST* one two three four five\n six seven eight nine ten\n eleven twelve\n(3 lines output)"} |
| 118 | |
| 119 | ############################################################################### |
| 120 | |
| 121 | fossil test-comment-format --width 60 --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 122 | test comment-21 {$RESULT eq "*TEST* one two three four five\n six seven eight nine ten\n eleven twelve\n(3 lines output)"} |
| 123 | |
| 124 | ############################################################################### |
| 125 | |
| 126 | fossil test-comment-format --legacy "" "" |
| 127 | test comment-22 {$RESULT eq "\n(1 lines output)"} |
| 128 | |
| 129 | ############################################################################### |
| 130 | |
| 131 | fossil test-comment-format --legacy --decode "" "" |
| 132 | test comment-23 {$RESULT eq "\n(1 lines output)"} |
| 133 | |
| 134 | ############################################################################### |
| 135 | |
| 136 | fossil test-comment-format --width 26 --legacy " " "this is a short comment." |
| 137 | test comment-24 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 138 | |
| 139 | ############################################################################### |
| 140 | |
| 141 | fossil test-comment-format --width 26 --legacy --decode " " "this is a short comment." |
| 142 | test comment-25 {$RESULT eq " this is a short comment.\n(1 lines output)"} |
| 143 | |
| 144 | ############################################################################### |
| 145 | |
| 146 | fossil test-comment-format --width 25 --legacy "*PREFIX* " "this is a short comment." |
| 147 | test comment-26 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} |
| 148 | |
| 149 | ############################################################################### |
| 150 | |
| 151 | fossil test-comment-format --width 25 --legacy --decode "*PREFIX* " "this is a short comment." |
| 152 | test comment-27 {$RESULT eq "*PREFIX* this is a short\n comment.\n(2 lines output)"} |
| 153 | |
| 154 | ############################################################################### |
| 155 | |
| 156 | fossil test-comment-format --width 26 --legacy "" "this\\sis\\sa\\sshort\\scomment." |
| 157 | test comment-28 {$RESULT eq "this\\sis\\sa\\sshort\\scommen\nt.\n(2 lines output)"} |
| 158 | |
| 159 | ############################################################################### |
| 160 | |
| 161 | fossil test-comment-format --width 26 --legacy --decode "" "this\\sis\\sa\\sshort\\scomment." |
| 162 | test comment-29 {$RESULT eq "this is a short comment.\n(1 lines output)"} |
| 163 | |
| 164 | ############################################################################### |
| 165 | |
| 166 | fossil test-comment-format --width 78 --legacy --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly." |
| 167 | test comment-30 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly.\n(2 lines output)"} |
| 168 | |
| 169 | ############################################################################### |
| 170 | |
| 171 | fossil test-comment-format --width 78 --legacy --decode "HH:MM:SS " "this is a long comment that should span multiple lines if the test is working correctly. more text here describing the issue.\\nanother line here..................................................................................*" |
| 172 | test comment-31 {$RESULT eq "HH:MM:SS this is a long comment that should span multiple lines if the test\n is working correctly. more text here describing the issue. another\n line\n here.................................................................\n .................*\n(5 lines output)"} |
| 173 | |
| 174 | ############################################################################### |
| 175 | |
| 176 | fossil test-comment-format --width 78 --legacy "HH:MM:SS " "....................................................................................*" |
| 177 | test comment-32 {$RESULT eq "HH:MM:SS .....................................................................\n ...............*\n(2 lines output)"} |
| 178 | |
| 179 | ############################################################################### |
| 180 | |
| 181 | fossil test-comment-format --width 78 --legacy "HH:MM:SS " ".....................................................................*" |
| 182 | test comment-33 {$RESULT eq "HH:MM:SS .....................................................................\n *\n(2 lines output)"} |
| 183 | |
| 184 | ############################################################################### |
| 185 | |
| 186 | fossil test-comment-format --width 26 --legacy "*TEST* " "this\tis a test." |
| 187 | test comment-34 {$RESULT eq "*TEST* this is a test.\n(1 lines output)"} |
| 188 | |
| 189 | ############################################################################### |
| 190 | |
| 191 | fossil test-comment-format --width 60 --legacy "*TEST* " "this is a test......................................................................................................................." |
| 192 | test comment-35 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 193 | |
| 194 | ############################################################################### |
| 195 | |
| 196 | fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "this is a test......................................................................................................................." |
| 197 | test comment-36 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 198 | |
| 199 | ############################################################################### |
| 200 | |
| 201 | fossil test-comment-format --width 60 --legacy "*TEST* " "this is a test......................................................................................................................." |
| 202 | test comment-37 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 203 | |
| 204 | ############################################################################### |
| 205 | |
| 206 | fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "this is a test......................................................................................................................." |
| 207 | test comment-38 {$RESULT eq "*TEST* this is a\n test.................................................\n .....................................................\n .................\n(4 lines output)"} |
| 208 | |
| 209 | ############################################################################### |
| 210 | |
| 211 | fossil test-comment-format --width 60 --legacy "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 212 | test comment-39 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 213 | |
| 214 | ############################################################################### |
| 215 | |
| 216 | fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 217 | test comment-40 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 218 | |
| 219 | ############################################################################### |
| 220 | |
| 221 | fossil test-comment-format --width 60 --legacy "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 222 | test comment-41 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 223 | |
| 224 | ############################################################################### |
| 225 | |
| 226 | fossil test-comment-format --width 60 --legacy --wordbreak "*TEST* " "one two three four five six seven eight nine ten eleven twelve" |
| 227 | test comment-42 {$RESULT eq "*TEST* one two three four five six seven eight nine ten\n eleven twelve\n(2 lines output)"} |
| 228 | |
| 229 | ############################################################################### |
| 230 | |
| 231 | set orig "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\\nxxxxxxx." |
| 232 | fossil test-comment-format --width 73 --decode --origbreak "" $orig |
| 233 | test comment-43 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 234 | |
| 235 | ############################################################################### |
| 236 | |
| 237 | fossil test-comment-format --width 73 --decode --origbreak "" $orig $orig |
| 238 | test comment-44 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 239 | |
| 240 | ############################################################################### |
| 241 | |
| 242 | fossil test-comment-format --width 73 --decode --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig |
| 243 | test comment-45 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} |
| 244 | |
| 245 | ############################################################################### |
| 246 | |
| 247 | fossil test-comment-format --width 82 --indent 9 --decode --origbreak " " $orig |
| 248 | test comment-46 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 249 | |
| 250 | ############################################################################### |
| 251 | |
| 252 | fossil test-comment-format --width 82 --indent 9 --decode --origbreak " " $orig $orig |
| 253 | test comment-47 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 254 | |
| 255 | ############################################################################### |
| 256 | |
| 257 | fossil test-comment-format --width 82 --indent 9 --decode --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig |
| 258 | test comment-48 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} |
| 259 | |
| 260 | ############################################################################### |
| 261 | |
| 262 | fossil test-comment-format --width 72 --decode --trimspace --origbreak "" $orig |
| 263 | test comment-49 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 264 | |
| 265 | ############################################################################### |
| 266 | |
| 267 | fossil test-comment-format --width 72 --decode --trimspace --origbreak "" $orig $orig |
| 268 | test comment-50 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 269 | |
| 270 | ############################################################################### |
| 271 | |
| 272 | fossil test-comment-format --width 72 --decode --trimspace --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig |
| 273 | test comment-51 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} |
| 274 | |
| 275 | ############################################################################### |
| 276 | |
| 277 | fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak " " $orig |
| 278 | test comment-52 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 279 | |
| 280 | ############################################################################### |
| 281 | |
| 282 | fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak " " $orig $orig |
| 283 | test comment-53 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 284 | |
| 285 | ############################################################################### |
| 286 | |
| 287 | fossil test-comment-format --width 81 --indent 9 --decode --trimspace --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig |
| 288 | test comment-54 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} |
| 289 | |
| 290 | ############################################################################### |
| 291 | |
| 292 | fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" $orig |
| 293 | test comment-55 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 294 | |
| 295 | ############################################################################### |
| 296 | |
| 297 | fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" $orig $orig |
| 298 | test comment-56 {$RESULT eq "xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(5 lines output)"} |
| 299 | |
| 300 | ############################################################################### |
| 301 | |
| 302 | fossil test-comment-format --width 72 --decode --trimcrlf --origbreak "" "00:00:00 \[0000000000\] *CURRENT* $orig" $orig |
| 303 | test comment-57 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \nxxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\nxxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\nxxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\nxxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\nxxxxxxx.\n(6 lines output)"} |
| 304 | |
| 305 | ############################################################################### |
| 306 | |
| 307 | fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak " " $orig |
| 308 | test comment-58 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 309 | |
| 310 | ############################################################################### |
| 311 | |
| 312 | fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak " " $orig $orig |
| 313 | test comment-59 {$RESULT eq " xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(5 lines output)"} |
| 314 | |
| 315 | ############################################################################### |
| 316 | |
| 317 | fossil test-comment-format --width 81 --indent 9 --decode --trimcrlf --origbreak "00:00:00 " "\[0000000000\] *CURRENT* $orig" $orig |
| 318 | test comment-60 {$RESULT eq "00:00:00 \[0000000000\] *CURRENT* \n xxxx xx xxxxxxx xxxx xxxxxx xxxxxxx, xxxxxxx, x xxxx xxxxxx xx xxxx xxxx\n xxxxxxx xxxxx xxxx xxxx xx xxxxxxx xxxxxxx (xxxxxx xxxxxxxxx x xxxxx).\n xxx'x xxx xxx xx xxxxx xxxx xxx xxx --xxxxxxxxxxx xxxxxx xx xx xxxx. x\n xxxxx x xxxxxx xxxx xxxx xxxx xxxx xxxx x xxxxx xx xxx x xxxxxxxx\n xxxxxxx.\n(6 lines output)"} |
| 319 |
+36
-3
| --- test/merge_renames.test | ||
| +++ test/merge_renames.test | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # Tests for merging with renames |
| 3 | -# | |
| 3 | +# | |
| 4 | 4 | # |
| 5 | 5 | |
| 6 | 6 | catch {exec $::fossilexe info} res |
| 7 | 7 | puts res=$res |
| 8 | 8 | if {![regexp {use --repository} $res]} { |
| @@ -169,11 +169,44 @@ | ||
| 169 | 169 | # Reported: Ticket [67176c3aa4] # |
| 170 | 170 | ###################################### |
| 171 | 171 | |
| 172 | 172 | # TO BE WRITTEN. |
| 173 | 173 | |
| 174 | +###################################### | |
| 175 | +# Test 5 # | |
| 176 | +# Handle Rename/Add via Merge # | |
| 177 | +###################################### | |
| 178 | + | |
| 179 | +repo_init | |
| 180 | + | |
| 181 | +write_file f1 "old f1 line" | |
| 182 | +fossil add f1 | |
| 183 | +fossil commit -m "base file" | |
| 184 | + | |
| 185 | +write_file f3 "f3 line" | |
| 186 | +fossil add f3 | |
| 187 | +fossil commit -m "branch file" -b branch_for_f3 | |
| 188 | + | |
| 189 | +fossil update trunk | |
| 190 | +fossil mv f1 f2 | |
| 191 | +file rename -force f1 f2 | |
| 192 | +write_file f1 "new f1 line" | |
| 193 | +fossil add f1 | |
| 194 | +fossil commit -m "rename and add file with old name" | |
| 195 | + | |
| 196 | +fossil update branch_for_f3 | |
| 197 | +fossil merge trunk | |
| 198 | +fossil commit -m "trunk merged, should have 3 files" | |
| 199 | + | |
| 200 | +fossil ls | |
| 201 | + | |
| 202 | +test merge_renames-5 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1 | |
| 203 | +f2 | |
| 204 | +f3}} | |
| 174 | 205 | |
| 206 | +###################################### | |
| 207 | +# | |
| 175 | 208 | # Tests for troubles not specifically linked with renames but that I'd like to |
| 176 | 209 | # write: |
| 177 | 210 | # [c26c63eb1b] - 'merge --backout' does not handle conflicts properly |
| 178 | -# [953031915f] - Lack of warning when overwriting extra files | |
| 179 | -# [4df5f38f1e] - Troubles merging a file delete with a file change | |
| 211 | +# [953031915f] - Lack of warning when overwriting extra files | |
| 212 | +# [4df5f38f1e] - Troubles merging a file delete with a file change | |
| 180 | 213 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,8 +1,8 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | catch {exec $::fossilexe info} res |
| 7 | puts res=$res |
| 8 | if {![regexp {use --repository} $res]} { |
| @@ -169,11 +169,44 @@ | |
| 169 | # Reported: Ticket [67176c3aa4] # |
| 170 | ###################################### |
| 171 | |
| 172 | # TO BE WRITTEN. |
| 173 | |
| 174 | |
| 175 | # Tests for troubles not specifically linked with renames but that I'd like to |
| 176 | # write: |
| 177 | # [c26c63eb1b] - 'merge --backout' does not handle conflicts properly |
| 178 | # [953031915f] - Lack of warning when overwriting extra files |
| 179 | # [4df5f38f1e] - Troubles merging a file delete with a file change |
| 180 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,8 +1,8 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | catch {exec $::fossilexe info} res |
| 7 | puts res=$res |
| 8 | if {![regexp {use --repository} $res]} { |
| @@ -169,11 +169,44 @@ | |
| 169 | # Reported: Ticket [67176c3aa4] # |
| 170 | ###################################### |
| 171 | |
| 172 | # TO BE WRITTEN. |
| 173 | |
| 174 | ###################################### |
| 175 | # Test 5 # |
| 176 | # Handle Rename/Add via Merge # |
| 177 | ###################################### |
| 178 | |
| 179 | repo_init |
| 180 | |
| 181 | write_file f1 "old f1 line" |
| 182 | fossil add f1 |
| 183 | fossil commit -m "base file" |
| 184 | |
| 185 | write_file f3 "f3 line" |
| 186 | fossil add f3 |
| 187 | fossil commit -m "branch file" -b branch_for_f3 |
| 188 | |
| 189 | fossil update trunk |
| 190 | fossil mv f1 f2 |
| 191 | file rename -force f1 f2 |
| 192 | write_file f1 "new f1 line" |
| 193 | fossil add f1 |
| 194 | fossil commit -m "rename and add file with old name" |
| 195 | |
| 196 | fossil update branch_for_f3 |
| 197 | fossil merge trunk |
| 198 | fossil commit -m "trunk merged, should have 3 files" |
| 199 | |
| 200 | fossil ls |
| 201 | |
| 202 | test merge_renames-5 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1 |
| 203 | f2 |
| 204 | f3}} |
| 205 | |
| 206 | ###################################### |
| 207 | # |
| 208 | # Tests for troubles not specifically linked with renames but that I'd like to |
| 209 | # write: |
| 210 | # [c26c63eb1b] - 'merge --backout' does not handle conflicts properly |
| 211 | # [953031915f] - Lack of warning when overwriting extra files |
| 212 | # [4df5f38f1e] - Troubles merging a file delete with a file change |
| 213 |
+5
-1
| --- test/release-checklist.wiki | ||
| +++ test/release-checklist.wiki | ||
| @@ -17,13 +17,17 @@ | ||
| 17 | 17 | |
| 18 | 18 | <li><p> |
| 19 | 19 | Click on each of the links in in the |
| 20 | 20 | [./diff-test-1.wiki] document and verify that all diffs are |
| 21 | 21 | rendered correctly. |
| 22 | - | |
| 23 | 22 | <li><p> |
| 24 | 23 | Click on the following link to verify that it works: [./test-page%2b%2b.wiki | ./test-page++.wiki] |
| 24 | +(NB: Many web servers automatically block | |
| 25 | +or rewrite URLs that contain "+" characters, even when those "+" | |
| 26 | +characters are encoded as "%2B". On such web servers, the URL | |
| 27 | +above will not work. This test is only guaranteed to work | |
| 28 | +when running "fossil ui".) | |
| 25 | 29 | |
| 26 | 30 | <li><p> |
| 27 | 31 | Verify correct name-change tracking behavior (no net changes) for: |
| 28 | 32 | <blockquote><b> |
| 29 | 33 | fossil test-name-changes --debug b120bc8b262ac 374920b20944b |
| 30 | 34 |
| --- test/release-checklist.wiki | |
| +++ test/release-checklist.wiki | |
| @@ -17,13 +17,17 @@ | |
| 17 | |
| 18 | <li><p> |
| 19 | Click on each of the links in in the |
| 20 | [./diff-test-1.wiki] document and verify that all diffs are |
| 21 | rendered correctly. |
| 22 | |
| 23 | <li><p> |
| 24 | Click on the following link to verify that it works: [./test-page%2b%2b.wiki | ./test-page++.wiki] |
| 25 | |
| 26 | <li><p> |
| 27 | Verify correct name-change tracking behavior (no net changes) for: |
| 28 | <blockquote><b> |
| 29 | fossil test-name-changes --debug b120bc8b262ac 374920b20944b |
| 30 |
| --- test/release-checklist.wiki | |
| +++ test/release-checklist.wiki | |
| @@ -17,13 +17,17 @@ | |
| 17 | |
| 18 | <li><p> |
| 19 | Click on each of the links in in the |
| 20 | [./diff-test-1.wiki] document and verify that all diffs are |
| 21 | rendered correctly. |
| 22 | <li><p> |
| 23 | Click on the following link to verify that it works: [./test-page%2b%2b.wiki | ./test-page++.wiki] |
| 24 | (NB: Many web servers automatically block |
| 25 | or rewrite URLs that contain "+" characters, even when those "+" |
| 26 | characters are encoded as "%2B". On such web servers, the URL |
| 27 | above will not work. This test is only guaranteed to work |
| 28 | when running "fossil ui".) |
| 29 | |
| 30 | <li><p> |
| 31 | Verify correct name-change tracking behavior (no net changes) for: |
| 32 | <blockquote><b> |
| 33 | fossil test-name-changes --debug b120bc8b262ac 374920b20944b |
| 34 |
+2
-2
| --- win/Makefile.PellesCGMake | ||
| +++ win/Makefile.PellesCGMake | ||
| @@ -83,17 +83,17 @@ | ||
| 83 | 83 | |
| 84 | 84 | # define the sqlite files, which need special flags on compile |
| 85 | 85 | SQLITESRC=sqlite3.c |
| 86 | 86 | ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) |
| 87 | 87 | SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) |
| 88 | -SQLITEDEFINES=-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS | |
| 88 | +SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS | |
| 89 | 89 | |
| 90 | 90 | # define the sqlite shell files, which need special flags on compile |
| 91 | 91 | SQLITESHELLSRC=shell.c |
| 92 | 92 | ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf)) |
| 93 | 93 | SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj)) |
| 94 | -SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | |
| 94 | +SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | |
| 95 | 95 | |
| 96 | 96 | # define the th scripting files, which need special flags on compile |
| 97 | 97 | THSRC=th.c th_lang.c |
| 98 | 98 | ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf)) |
| 99 | 99 | THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj)) |
| 100 | 100 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -83,17 +83,17 @@ | |
| 83 | |
| 84 | # define the sqlite files, which need special flags on compile |
| 85 | SQLITESRC=sqlite3.c |
| 86 | ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) |
| 87 | SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) |
| 88 | SQLITEDEFINES=-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 89 | |
| 90 | # define the sqlite shell files, which need special flags on compile |
| 91 | SQLITESHELLSRC=shell.c |
| 92 | ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf)) |
| 93 | SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj)) |
| 94 | SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 95 | |
| 96 | # define the th scripting files, which need special flags on compile |
| 97 | THSRC=th.c th_lang.c |
| 98 | ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf)) |
| 99 | THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj)) |
| 100 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -83,17 +83,17 @@ | |
| 83 | |
| 84 | # define the sqlite files, which need special flags on compile |
| 85 | SQLITESRC=sqlite3.c |
| 86 | ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) |
| 87 | SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) |
| 88 | SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 89 | |
| 90 | # define the sqlite shell files, which need special flags on compile |
| 91 | SQLITESHELLSRC=shell.c |
| 92 | ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf)) |
| 93 | SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj)) |
| 94 | SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 95 | |
| 96 | # define the th scripting files, which need special flags on compile |
| 97 | THSRC=th.c th_lang.c |
| 98 | ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf)) |
| 99 | THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj)) |
| 100 |
+2
-2
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -24,13 +24,13 @@ | ||
| 24 | 24 | CFLAGS = -o |
| 25 | 25 | BCC = $(DMDIR)\bin\dmc $(CFLAGS) |
| 26 | 26 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 27 | 27 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 |
| 28 | 28 | |
| 29 | -SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS | |
| 29 | +SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS | |
| 30 | 30 | |
| 31 | -SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | |
| 31 | +SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | |
| 32 | 32 | |
| 33 | 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | 34 | |
| 35 | 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | 36 | |
| 37 | 37 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -24,13 +24,13 @@ | |
| 24 | CFLAGS = -o |
| 25 | BCC = $(DMDIR)\bin\dmc $(CFLAGS) |
| 26 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 27 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 |
| 28 | |
| 29 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -24,13 +24,13 @@ | |
| 24 | CFLAGS = -o |
| 25 | BCC = $(DMDIR)\bin\dmc $(CFLAGS) |
| 26 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 27 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 |
| 28 | |
| 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 |
+3
-1
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -1765,11 +1765,12 @@ | ||
| 1765 | 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | 1767 | |
| 1768 | 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | 1769 | |
| 1770 | -SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 1770 | +SQLITE_OPTIONS = -DNDEBUG=1 \ | |
| 1771 | + -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 1771 | 1772 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1772 | 1773 | -DSQLITE_THREADSAFE=0 \ |
| 1773 | 1774 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1774 | 1775 | -DSQLITE_OMIT_DEPRECATED \ |
| 1775 | 1776 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | ||
| 1780 | 1781 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1781 | 1782 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1782 | 1783 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1783 | 1784 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1784 | 1785 | -Daccess=file_access \ |
| 1786 | + -Dsystem=fossil_system \ | |
| 1785 | 1787 | -Dgetenv=fossil_getenv \ |
| 1786 | 1788 | -Dfopen=fossil_fopen |
| 1787 | 1789 | |
| 1788 | 1790 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw |
| 1789 | 1791 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1790 | 1792 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -1765,11 +1765,12 @@ | |
| 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | |
| 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | |
| 1770 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1771 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1772 | -DSQLITE_THREADSAFE=0 \ |
| 1773 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1774 | -DSQLITE_OMIT_DEPRECATED \ |
| 1775 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | |
| 1780 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1781 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1782 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1783 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1784 | -Daccess=file_access \ |
| 1785 | -Dgetenv=fossil_getenv \ |
| 1786 | -Dfopen=fossil_fopen |
| 1787 | |
| 1788 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw |
| 1789 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1790 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -1765,11 +1765,12 @@ | |
| 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | |
| 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | |
| 1770 | SQLITE_OPTIONS = -DNDEBUG=1 \ |
| 1771 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1772 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1773 | -DSQLITE_THREADSAFE=0 \ |
| 1774 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1775 | -DSQLITE_OMIT_DEPRECATED \ |
| 1776 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | |
| 1781 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1782 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1783 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1784 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1785 | -Daccess=file_access \ |
| 1786 | -Dsystem=fossil_system \ |
| 1787 | -Dgetenv=fossil_getenv \ |
| 1788 | -Dfopen=fossil_fopen |
| 1789 | |
| 1790 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw |
| 1791 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1792 |
+3
-1
| --- win/Makefile.mingw.mistachkin | ||
| +++ win/Makefile.mingw.mistachkin | ||
| @@ -1765,11 +1765,12 @@ | ||
| 1765 | 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | 1767 | |
| 1768 | 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | 1769 | |
| 1770 | -SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 1770 | +SQLITE_OPTIONS = -DNDEBUG=1 \ | |
| 1771 | + -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 1771 | 1772 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1772 | 1773 | -DSQLITE_THREADSAFE=0 \ |
| 1773 | 1774 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1774 | 1775 | -DSQLITE_OMIT_DEPRECATED \ |
| 1775 | 1776 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | ||
| 1780 | 1781 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1781 | 1782 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1782 | 1783 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1783 | 1784 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1784 | 1785 | -Daccess=file_access \ |
| 1786 | + -Dsystem=fossil_system \ | |
| 1785 | 1787 | -Dgetenv=fossil_getenv \ |
| 1786 | 1788 | -Dfopen=fossil_fopen |
| 1787 | 1789 | |
| 1788 | 1790 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw.mistachkin |
| 1789 | 1791 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1790 | 1792 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -1765,11 +1765,12 @@ | |
| 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | |
| 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | |
| 1770 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1771 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1772 | -DSQLITE_THREADSAFE=0 \ |
| 1773 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1774 | -DSQLITE_OMIT_DEPRECATED \ |
| 1775 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | |
| 1780 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1781 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1782 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1783 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1784 | -Daccess=file_access \ |
| 1785 | -Dgetenv=fossil_getenv \ |
| 1786 | -Dfopen=fossil_fopen |
| 1787 | |
| 1788 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw.mistachkin |
| 1789 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1790 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -1765,11 +1765,12 @@ | |
| 1765 | $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h |
| 1766 | $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| 1767 | |
| 1768 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 1769 | |
| 1770 | SQLITE_OPTIONS = -DNDEBUG=1 \ |
| 1771 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1772 | -DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 1773 | -DSQLITE_THREADSAFE=0 \ |
| 1774 | -DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 1775 | -DSQLITE_OMIT_DEPRECATED \ |
| 1776 | -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ |
| @@ -1780,10 +1781,11 @@ | |
| 1781 | SHELL_OPTIONS = -Dmain=sqlite3_shell \ |
| 1782 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 1783 | -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 1784 | -DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 1785 | -Daccess=file_access \ |
| 1786 | -Dsystem=fossil_system \ |
| 1787 | -Dgetenv=fossil_getenv \ |
| 1788 | -Dfopen=fossil_fopen |
| 1789 | |
| 1790 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c $(SRCDIR)/../win/Makefile.mingw.mistachkin |
| 1791 | $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1792 |
+3
-1
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -99,11 +99,12 @@ | ||
| 99 | 99 | RCC = $(RCC) /DFOSSIL_ENABLE_TCL_PRIVATE_STUBS=1 |
| 100 | 100 | TCC = $(TCC) /DUSE_TCL_STUBS=1 |
| 101 | 101 | RCC = $(RCC) /DUSE_TCL_STUBS=1 |
| 102 | 102 | !endif |
| 103 | 103 | |
| 104 | -SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 104 | +SQLITE_OPTIONS = /DNDEBUG=1 \ | |
| 105 | + /DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 105 | 106 | /DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 106 | 107 | /DSQLITE_THREADSAFE=0 \ |
| 107 | 108 | /DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 108 | 109 | /DSQLITE_OMIT_DEPRECATED \ |
| 109 | 110 | /DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| @@ -111,10 +112,11 @@ | ||
| 111 | 112 | SHELL_OPTIONS = /Dmain=sqlite3_shell \ |
| 112 | 113 | /DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 113 | 114 | /DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 114 | 115 | /DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 115 | 116 | /Daccess=file_access \ |
| 117 | + /Dsystem=fossil_system \ | |
| 116 | 118 | /Dgetenv=fossil_getenv \ |
| 117 | 119 | /Dfopen=fossil_fopen |
| 118 | 120 | |
| 119 | 121 | SRC = add_.c \ |
| 120 | 122 | allrepo_.c \ |
| 121 | 123 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -99,11 +99,12 @@ | |
| 99 | RCC = $(RCC) /DFOSSIL_ENABLE_TCL_PRIVATE_STUBS=1 |
| 100 | TCC = $(TCC) /DUSE_TCL_STUBS=1 |
| 101 | RCC = $(RCC) /DUSE_TCL_STUBS=1 |
| 102 | !endif |
| 103 | |
| 104 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 105 | /DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 106 | /DSQLITE_THREADSAFE=0 \ |
| 107 | /DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 108 | /DSQLITE_OMIT_DEPRECATED \ |
| 109 | /DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| @@ -111,10 +112,11 @@ | |
| 111 | SHELL_OPTIONS = /Dmain=sqlite3_shell \ |
| 112 | /DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 113 | /DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 114 | /DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 115 | /Daccess=file_access \ |
| 116 | /Dgetenv=fossil_getenv \ |
| 117 | /Dfopen=fossil_fopen |
| 118 | |
| 119 | SRC = add_.c \ |
| 120 | allrepo_.c \ |
| 121 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -99,11 +99,12 @@ | |
| 99 | RCC = $(RCC) /DFOSSIL_ENABLE_TCL_PRIVATE_STUBS=1 |
| 100 | TCC = $(TCC) /DUSE_TCL_STUBS=1 |
| 101 | RCC = $(RCC) /DUSE_TCL_STUBS=1 |
| 102 | !endif |
| 103 | |
| 104 | SQLITE_OPTIONS = /DNDEBUG=1 \ |
| 105 | /DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 106 | /DSQLITE_ENABLE_LOCKING_STYLE=0 \ |
| 107 | /DSQLITE_THREADSAFE=0 \ |
| 108 | /DSQLITE_DEFAULT_FILE_FORMAT=4 \ |
| 109 | /DSQLITE_OMIT_DEPRECATED \ |
| 110 | /DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| @@ -111,10 +112,11 @@ | |
| 112 | SHELL_OPTIONS = /Dmain=sqlite3_shell \ |
| 113 | /DSQLITE_OMIT_LOAD_EXTENSION=1 \ |
| 114 | /DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \ |
| 115 | /DSQLITE_SHELL_DBNAME_PROC=fossil_open \ |
| 116 | /Daccess=file_access \ |
| 117 | /Dsystem=fossil_system \ |
| 118 | /Dgetenv=fossil_getenv \ |
| 119 | /Dfopen=fossil_fopen |
| 120 | |
| 121 | SRC = add_.c \ |
| 122 | allrepo_.c \ |
| 123 |
+29
-30
| --- www/branching.wiki | ||
| +++ www/branching.wiki | ||
| @@ -19,19 +19,19 @@ | ||
| 19 | 19 | |
| 20 | 20 | The arrows in figure 1 show the evolution of a project. The initial |
| 21 | 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | -and that 1 is a <i>parent</i> of 2. | |
| 24 | +and that 1 is a <i>parent</i> of 2. | |
| 25 | 25 | Check-in 3 is derived from check-in 2, making |
| 26 | 26 | 3 a child of 2. We say that 3 is a <i>descendant</i> of both 1 and 2 and that 1 |
| 27 | -and 2 are both <i>ancestors</i> of 3. | |
| 27 | +and 2 are both <i>ancestors</i> of 3. | |
| 28 | 28 | |
| 29 | 29 | <a name="dag"></a> |
| 30 | 30 | <h2>DAGs</h2> |
| 31 | 31 | |
| 32 | -The graph of check-ins is a | |
| 32 | +The graph of check-ins is a | |
| 33 | 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | 34 | commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG |
| 35 | 35 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 36 | 36 | it has no descendants. (We will give a more precise definition later of |
| 37 | 37 | "leaf.") |
| @@ -47,29 +47,29 @@ | ||
| 47 | 47 | </td></tr></table></center> |
| 48 | 48 | |
| 49 | 49 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 50 | 50 | two children, check-ins 3 and 4. We call this state a <i>fork</i>. |
| 51 | 51 | |
| 52 | -Fossil tries to prevent forks. Suppose two programmers named Alice and | |
| 53 | -Bob are each editing check-in 2 separately. Alice finishes her edits | |
| 54 | -first and commits her changes, resulting in check-in 3. Later, when Bob | |
| 55 | -attempts to commit his changes, fossil verifies that check-in 2 is still | |
| 56 | -a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit | |
| 57 | -attempt with a message "would fork." This allows Bob to do a "fossil | |
| 58 | -update" which pulls in Alice's changes, merging them into his own | |
| 59 | -changes. After merging, Bob commits check-in 4 as a child of check-in 3. | |
| 60 | -The result is a linear graph as shown in figure 1. This is how CVS | |
| 61 | -works. This is also how fossil works in [./concepts.wiki#workflow | | |
| 62 | -"autosync"] mode. | |
| 52 | +Fossil tries to prevent forks. Suppose two programmers named Alice and | |
| 53 | +Bob are each editing check-in 2 separately. Alice finishes her edits | |
| 54 | +first and commits her changes, resulting in check-in 3. Later, when Bob | |
| 55 | +attempts to commit his changes, fossil verifies that check-in 2 is still | |
| 56 | +a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit | |
| 57 | +attempt with a message "would fork." This allows Bob to do a "fossil | |
| 58 | +update" which pulls in Alice's changes, merging them into his own | |
| 59 | +changes. After merging, Bob commits check-in 4 as a child of check-in 3. | |
| 60 | +The result is a linear graph as shown in figure 1. This is how CVS | |
| 61 | +works. This is also how fossil works in [./concepts.wiki#workflow | | |
| 62 | +"autosync"] mode. | |
| 63 | 63 | |
| 64 | 64 | But perhaps Bob is off-network when he does his commit, so he |
| 65 | 65 | has no way of knowing that Alice has already committed her changes. |
| 66 | 66 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 67 | 67 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 68 | -saved his own, so he forces the commit to occur using the "--force" option | |
| 69 | -to the fossil <b>commit</b> command. For any of these reasons, two commits against | |
| 70 | -check-in 2 have occurred and now the DAG has two leaves. | |
| 68 | +saved his own, so he forces the commit to occur using the "--allow-fork" | |
| 69 | +option to the fossil <b>commit</b> command. For any of these reasons, | |
| 70 | +two commits against check-in 2 have occurred and now the DAG has two leaves. | |
| 71 | 71 | |
| 72 | 72 | So which version of the project is the "latest" in the sense of having |
| 73 | 73 | the most features and the most bug fixes? When there is more than |
| 74 | 74 | one leaf in the graph, you don't really know. So we like to have |
| 75 | 75 | graphs with a single leaf. |
| @@ -86,11 +86,11 @@ | ||
| 86 | 86 | </td></tr></table></center> |
| 87 | 87 | |
| 88 | 88 | Check-in 5 is a child of check-in 3 because it was created by editing |
| 89 | 89 | check-in 3. But check-in 5 also inherits the changes from check-in 4 by |
| 90 | 90 | virtue of the merge. So we say that check-in 5 is a <i>merge child</i> |
| 91 | -of check-in 4 and that it is a <i>direct child</i> of check-in 3. | |
| 91 | +of check-in 4 and that it is a <i>direct child</i> of check-in 3. | |
| 92 | 92 | The graph is now back to a single leaf (check-in 5). |
| 93 | 93 | |
| 94 | 94 | We have already seen that if fossil is in autosync mode then Bob would |
| 95 | 95 | have been warned about the potential fork the first time he tried to |
| 96 | 96 | commit check-in 4. If Bob had updated his local check-out to merge in |
| @@ -112,11 +112,11 @@ | ||
| 112 | 112 | instead of as a separate manual step. We will not take sides in that |
| 113 | 113 | debate. We will simply point out that fossil enables you to do it either way. |
| 114 | 114 | |
| 115 | 115 | <h2>Forking Versus Branching</h2> |
| 116 | 116 | |
| 117 | -Having more than one leaf in the check-in DAG is called a "fork." This | |
| 117 | +Having more than one leaf in the check-in DAG is called a "fork." This | |
| 118 | 118 | is usually undesirable and either avoided entirely, |
| 119 | 119 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 120 | 120 | But sometimes, one does want to have multiple leaves. For example, a project |
| 121 | 121 | might have one leaf that is the latest version of the project under |
| 122 | 122 | development and another leaf that is the latest version that has been |
| @@ -131,19 +131,19 @@ | ||
| 131 | 131 | <img src="branch04.gif" width=426 height=123><br> |
| 132 | 132 | Figure 4 |
| 133 | 133 | </td></tr></table></center> |
| 134 | 134 | |
| 135 | 135 | The hypothetical scenario of figure 4 is this: The project starts and |
| 136 | -progresses to a point where (at check-in 2) | |
| 136 | +progresses to a point where (at check-in 2) | |
| 137 | 137 | it is ready to enter testing for its first release. |
| 138 | 138 | In a real project, of course, there might be hundreds or thousands of |
| 139 | 139 | check-ins before a project reaches this point, but for simplicity of |
| 140 | 140 | presentation we will say that the project is ready after check-in 2. |
| 141 | 141 | The project then splits into two branches that are used by separate |
| 142 | 142 | teams. The testing team, using the blue branch, finds and fixes a few |
| 143 | 143 | bugs. This is shown by check-ins 6 and 9. Meanwhile the development |
| 144 | -team, working on the top uncolored branch, | |
| 144 | +team, working on the top uncolored branch, | |
| 145 | 145 | is busy adding features for the second |
| 146 | 146 | release. Of course, the development team would like to take advantage of |
| 147 | 147 | the bug fixes implemented by the testing team. So periodically, the |
| 148 | 148 | changes in the test branch are merged into the dev branch. This is |
| 149 | 149 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| @@ -174,13 +174,13 @@ | ||
| 174 | 174 | |
| 175 | 175 | A <i>tag</i> is a name that is attached to a check-in. A |
| 176 | 176 | <i>property</i> is a name/value pair. Internally, fossil implements |
| 177 | 177 | tags as properties with a NULL value. So, tags and properties really |
| 178 | 178 | are much the same thing, and henceforth we will use the word "tag" |
| 179 | -to mean either a tag or a property. | |
| 179 | +to mean either a tag or a property. | |
| 180 | 180 | |
| 181 | -A tag can be a one-time tag, a propagating tag or a cancellation tag. | |
| 181 | +A tag can be a one-time tag, a propagating tag or a cancellation tag. | |
| 182 | 182 | A one-time tag only applies to the check-in to which it is attached. A |
| 183 | 183 | propagating tag applies to the check-in to which it is attached and also |
| 184 | 184 | to all direct descendants of that check-in. A <i>direct descendant</i> |
| 185 | 185 | is a descendant through direct children. Tags propagation does not |
| 186 | 186 | cross merges. Tag propagation also stops as soon |
| @@ -187,14 +187,13 @@ | ||
| 187 | 187 | as it encounters another check-in with the same tag. A cancellation tag |
| 188 | 188 | is attached to a single check-in in order to either override a one-time |
| 189 | 189 | tag that was previously placed on that same check-in, or to block |
| 190 | 190 | tag propagation from an ancestor. |
| 191 | 191 | |
| 192 | -Every repository is created with a single empty check-in that has two | |
| 193 | -propagating tags. In figure 5, that initial empty check-in is check-in 1. | |
| 194 | -The <b>branch</b> tag tells (by its value) | |
| 195 | -what branch the check-in is a member of. | |
| 192 | +The initial checkin of every repository has two propagating tags. In | |
| 193 | +figure 5, that initial check-in is check-in 1. The <b>branch</b> tag | |
| 194 | +tells (by its value) what branch the check-in is a member of. | |
| 196 | 195 | The default branch is called "trunk." All tags that begin with "<b>sym-</b>" |
| 197 | 196 | are symbolic name tags. When a symbolic name tag is attached to a |
| 198 | 197 | check-in, that allows you to refer to that check-in by its symbolic |
| 199 | 198 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 200 | 199 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| @@ -212,12 +211,12 @@ | ||
| 212 | 211 | |
| 213 | 212 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 214 | 213 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 215 | 214 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 216 | 215 | are hence not known by the name "test." |
| 217 | -To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 | |
| 218 | -into check-ins 4, 6, and 9, there is a cancellation tag for | |
| 216 | +To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 | |
| 217 | +into check-ins 4, 6, and 9, there is a cancellation tag for | |
| 219 | 218 | <b>sym-trunk</b> on check-in 4. The net effect is that |
| 220 | 219 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 221 | 220 | on the test branch go by the symbolic name "test." |
| 222 | 221 | |
| 223 | 222 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| @@ -225,11 +224,11 @@ | ||
| 225 | 224 | |
| 226 | 225 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 227 | 226 | not make a graphical distinction between one-time and propagating tags.) |
| 228 | 227 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 229 | 228 | using the more meaningful name "release-1.0." The <b>closed</b> tag means |
| 230 | -that check-in 9 is a "closed leaf." A closed leaf is a leaf that should | |
| 229 | +that check-in 9 is a "closed leaf." A closed leaf is a leaf that should | |
| 231 | 230 | never have direct children. |
| 232 | 231 | |
| 233 | 232 | <h2>Review Of Terminology</h2> |
| 234 | 233 | |
| 235 | 234 | <blockquote><dl> |
| 236 | 235 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -19,19 +19,19 @@ | |
| 19 | |
| 20 | The arrows in figure 1 show the evolution of a project. The initial |
| 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | and that 1 is a <i>parent</i> of 2. |
| 25 | Check-in 3 is derived from check-in 2, making |
| 26 | 3 a child of 2. We say that 3 is a <i>descendant</i> of both 1 and 2 and that 1 |
| 27 | and 2 are both <i>ancestors</i> of 3. |
| 28 | |
| 29 | <a name="dag"></a> |
| 30 | <h2>DAGs</h2> |
| 31 | |
| 32 | The graph of check-ins is a |
| 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG |
| 35 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 36 | it has no descendants. (We will give a more precise definition later of |
| 37 | "leaf.") |
| @@ -47,29 +47,29 @@ | |
| 47 | </td></tr></table></center> |
| 48 | |
| 49 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 50 | two children, check-ins 3 and 4. We call this state a <i>fork</i>. |
| 51 | |
| 52 | Fossil tries to prevent forks. Suppose two programmers named Alice and |
| 53 | Bob are each editing check-in 2 separately. Alice finishes her edits |
| 54 | first and commits her changes, resulting in check-in 3. Later, when Bob |
| 55 | attempts to commit his changes, fossil verifies that check-in 2 is still |
| 56 | a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit |
| 57 | attempt with a message "would fork." This allows Bob to do a "fossil |
| 58 | update" which pulls in Alice's changes, merging them into his own |
| 59 | changes. After merging, Bob commits check-in 4 as a child of check-in 3. |
| 60 | The result is a linear graph as shown in figure 1. This is how CVS |
| 61 | works. This is also how fossil works in [./concepts.wiki#workflow | |
| 62 | "autosync"] mode. |
| 63 | |
| 64 | But perhaps Bob is off-network when he does his commit, so he |
| 65 | has no way of knowing that Alice has already committed her changes. |
| 66 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 67 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 68 | saved his own, so he forces the commit to occur using the "--force" option |
| 69 | to the fossil <b>commit</b> command. For any of these reasons, two commits against |
| 70 | check-in 2 have occurred and now the DAG has two leaves. |
| 71 | |
| 72 | So which version of the project is the "latest" in the sense of having |
| 73 | the most features and the most bug fixes? When there is more than |
| 74 | one leaf in the graph, you don't really know. So we like to have |
| 75 | graphs with a single leaf. |
| @@ -86,11 +86,11 @@ | |
| 86 | </td></tr></table></center> |
| 87 | |
| 88 | Check-in 5 is a child of check-in 3 because it was created by editing |
| 89 | check-in 3. But check-in 5 also inherits the changes from check-in 4 by |
| 90 | virtue of the merge. So we say that check-in 5 is a <i>merge child</i> |
| 91 | of check-in 4 and that it is a <i>direct child</i> of check-in 3. |
| 92 | The graph is now back to a single leaf (check-in 5). |
| 93 | |
| 94 | We have already seen that if fossil is in autosync mode then Bob would |
| 95 | have been warned about the potential fork the first time he tried to |
| 96 | commit check-in 4. If Bob had updated his local check-out to merge in |
| @@ -112,11 +112,11 @@ | |
| 112 | instead of as a separate manual step. We will not take sides in that |
| 113 | debate. We will simply point out that fossil enables you to do it either way. |
| 114 | |
| 115 | <h2>Forking Versus Branching</h2> |
| 116 | |
| 117 | Having more than one leaf in the check-in DAG is called a "fork." This |
| 118 | is usually undesirable and either avoided entirely, |
| 119 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 120 | But sometimes, one does want to have multiple leaves. For example, a project |
| 121 | might have one leaf that is the latest version of the project under |
| 122 | development and another leaf that is the latest version that has been |
| @@ -131,19 +131,19 @@ | |
| 131 | <img src="branch04.gif" width=426 height=123><br> |
| 132 | Figure 4 |
| 133 | </td></tr></table></center> |
| 134 | |
| 135 | The hypothetical scenario of figure 4 is this: The project starts and |
| 136 | progresses to a point where (at check-in 2) |
| 137 | it is ready to enter testing for its first release. |
| 138 | In a real project, of course, there might be hundreds or thousands of |
| 139 | check-ins before a project reaches this point, but for simplicity of |
| 140 | presentation we will say that the project is ready after check-in 2. |
| 141 | The project then splits into two branches that are used by separate |
| 142 | teams. The testing team, using the blue branch, finds and fixes a few |
| 143 | bugs. This is shown by check-ins 6 and 9. Meanwhile the development |
| 144 | team, working on the top uncolored branch, |
| 145 | is busy adding features for the second |
| 146 | release. Of course, the development team would like to take advantage of |
| 147 | the bug fixes implemented by the testing team. So periodically, the |
| 148 | changes in the test branch are merged into the dev branch. This is |
| 149 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| @@ -174,13 +174,13 @@ | |
| 174 | |
| 175 | A <i>tag</i> is a name that is attached to a check-in. A |
| 176 | <i>property</i> is a name/value pair. Internally, fossil implements |
| 177 | tags as properties with a NULL value. So, tags and properties really |
| 178 | are much the same thing, and henceforth we will use the word "tag" |
| 179 | to mean either a tag or a property. |
| 180 | |
| 181 | A tag can be a one-time tag, a propagating tag or a cancellation tag. |
| 182 | A one-time tag only applies to the check-in to which it is attached. A |
| 183 | propagating tag applies to the check-in to which it is attached and also |
| 184 | to all direct descendants of that check-in. A <i>direct descendant</i> |
| 185 | is a descendant through direct children. Tags propagation does not |
| 186 | cross merges. Tag propagation also stops as soon |
| @@ -187,14 +187,13 @@ | |
| 187 | as it encounters another check-in with the same tag. A cancellation tag |
| 188 | is attached to a single check-in in order to either override a one-time |
| 189 | tag that was previously placed on that same check-in, or to block |
| 190 | tag propagation from an ancestor. |
| 191 | |
| 192 | Every repository is created with a single empty check-in that has two |
| 193 | propagating tags. In figure 5, that initial empty check-in is check-in 1. |
| 194 | The <b>branch</b> tag tells (by its value) |
| 195 | what branch the check-in is a member of. |
| 196 | The default branch is called "trunk." All tags that begin with "<b>sym-</b>" |
| 197 | are symbolic name tags. When a symbolic name tag is attached to a |
| 198 | check-in, that allows you to refer to that check-in by its symbolic |
| 199 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 200 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| @@ -212,12 +211,12 @@ | |
| 212 | |
| 213 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 214 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 215 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 216 | are hence not known by the name "test." |
| 217 | To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 |
| 218 | into check-ins 4, 6, and 9, there is a cancellation tag for |
| 219 | <b>sym-trunk</b> on check-in 4. The net effect is that |
| 220 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 221 | on the test branch go by the symbolic name "test." |
| 222 | |
| 223 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| @@ -225,11 +224,11 @@ | |
| 225 | |
| 226 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 227 | not make a graphical distinction between one-time and propagating tags.) |
| 228 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 229 | using the more meaningful name "release-1.0." The <b>closed</b> tag means |
| 230 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 231 | never have direct children. |
| 232 | |
| 233 | <h2>Review Of Terminology</h2> |
| 234 | |
| 235 | <blockquote><dl> |
| 236 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -19,19 +19,19 @@ | |
| 19 | |
| 20 | The arrows in figure 1 show the evolution of a project. The initial |
| 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | and that 1 is a <i>parent</i> of 2. |
| 25 | Check-in 3 is derived from check-in 2, making |
| 26 | 3 a child of 2. We say that 3 is a <i>descendant</i> of both 1 and 2 and that 1 |
| 27 | and 2 are both <i>ancestors</i> of 3. |
| 28 | |
| 29 | <a name="dag"></a> |
| 30 | <h2>DAGs</h2> |
| 31 | |
| 32 | The graph of check-ins is a |
| 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG |
| 35 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 36 | it has no descendants. (We will give a more precise definition later of |
| 37 | "leaf.") |
| @@ -47,29 +47,29 @@ | |
| 47 | </td></tr></table></center> |
| 48 | |
| 49 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 50 | two children, check-ins 3 and 4. We call this state a <i>fork</i>. |
| 51 | |
| 52 | Fossil tries to prevent forks. Suppose two programmers named Alice and |
| 53 | Bob are each editing check-in 2 separately. Alice finishes her edits |
| 54 | first and commits her changes, resulting in check-in 3. Later, when Bob |
| 55 | attempts to commit his changes, fossil verifies that check-in 2 is still |
| 56 | a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit |
| 57 | attempt with a message "would fork." This allows Bob to do a "fossil |
| 58 | update" which pulls in Alice's changes, merging them into his own |
| 59 | changes. After merging, Bob commits check-in 4 as a child of check-in 3. |
| 60 | The result is a linear graph as shown in figure 1. This is how CVS |
| 61 | works. This is also how fossil works in [./concepts.wiki#workflow | |
| 62 | "autosync"] mode. |
| 63 | |
| 64 | But perhaps Bob is off-network when he does his commit, so he |
| 65 | has no way of knowing that Alice has already committed her changes. |
| 66 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 67 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 68 | saved his own, so he forces the commit to occur using the "--allow-fork" |
| 69 | option to the fossil <b>commit</b> command. For any of these reasons, |
| 70 | two commits against check-in 2 have occurred and now the DAG has two leaves. |
| 71 | |
| 72 | So which version of the project is the "latest" in the sense of having |
| 73 | the most features and the most bug fixes? When there is more than |
| 74 | one leaf in the graph, you don't really know. So we like to have |
| 75 | graphs with a single leaf. |
| @@ -86,11 +86,11 @@ | |
| 86 | </td></tr></table></center> |
| 87 | |
| 88 | Check-in 5 is a child of check-in 3 because it was created by editing |
| 89 | check-in 3. But check-in 5 also inherits the changes from check-in 4 by |
| 90 | virtue of the merge. So we say that check-in 5 is a <i>merge child</i> |
| 91 | of check-in 4 and that it is a <i>direct child</i> of check-in 3. |
| 92 | The graph is now back to a single leaf (check-in 5). |
| 93 | |
| 94 | We have already seen that if fossil is in autosync mode then Bob would |
| 95 | have been warned about the potential fork the first time he tried to |
| 96 | commit check-in 4. If Bob had updated his local check-out to merge in |
| @@ -112,11 +112,11 @@ | |
| 112 | instead of as a separate manual step. We will not take sides in that |
| 113 | debate. We will simply point out that fossil enables you to do it either way. |
| 114 | |
| 115 | <h2>Forking Versus Branching</h2> |
| 116 | |
| 117 | Having more than one leaf in the check-in DAG is called a "fork." This |
| 118 | is usually undesirable and either avoided entirely, |
| 119 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 120 | But sometimes, one does want to have multiple leaves. For example, a project |
| 121 | might have one leaf that is the latest version of the project under |
| 122 | development and another leaf that is the latest version that has been |
| @@ -131,19 +131,19 @@ | |
| 131 | <img src="branch04.gif" width=426 height=123><br> |
| 132 | Figure 4 |
| 133 | </td></tr></table></center> |
| 134 | |
| 135 | The hypothetical scenario of figure 4 is this: The project starts and |
| 136 | progresses to a point where (at check-in 2) |
| 137 | it is ready to enter testing for its first release. |
| 138 | In a real project, of course, there might be hundreds or thousands of |
| 139 | check-ins before a project reaches this point, but for simplicity of |
| 140 | presentation we will say that the project is ready after check-in 2. |
| 141 | The project then splits into two branches that are used by separate |
| 142 | teams. The testing team, using the blue branch, finds and fixes a few |
| 143 | bugs. This is shown by check-ins 6 and 9. Meanwhile the development |
| 144 | team, working on the top uncolored branch, |
| 145 | is busy adding features for the second |
| 146 | release. Of course, the development team would like to take advantage of |
| 147 | the bug fixes implemented by the testing team. So periodically, the |
| 148 | changes in the test branch are merged into the dev branch. This is |
| 149 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| @@ -174,13 +174,13 @@ | |
| 174 | |
| 175 | A <i>tag</i> is a name that is attached to a check-in. A |
| 176 | <i>property</i> is a name/value pair. Internally, fossil implements |
| 177 | tags as properties with a NULL value. So, tags and properties really |
| 178 | are much the same thing, and henceforth we will use the word "tag" |
| 179 | to mean either a tag or a property. |
| 180 | |
| 181 | A tag can be a one-time tag, a propagating tag or a cancellation tag. |
| 182 | A one-time tag only applies to the check-in to which it is attached. A |
| 183 | propagating tag applies to the check-in to which it is attached and also |
| 184 | to all direct descendants of that check-in. A <i>direct descendant</i> |
| 185 | is a descendant through direct children. Tags propagation does not |
| 186 | cross merges. Tag propagation also stops as soon |
| @@ -187,14 +187,13 @@ | |
| 187 | as it encounters another check-in with the same tag. A cancellation tag |
| 188 | is attached to a single check-in in order to either override a one-time |
| 189 | tag that was previously placed on that same check-in, or to block |
| 190 | tag propagation from an ancestor. |
| 191 | |
| 192 | The initial checkin of every repository has two propagating tags. In |
| 193 | figure 5, that initial check-in is check-in 1. The <b>branch</b> tag |
| 194 | tells (by its value) what branch the check-in is a member of. |
| 195 | The default branch is called "trunk." All tags that begin with "<b>sym-</b>" |
| 196 | are symbolic name tags. When a symbolic name tag is attached to a |
| 197 | check-in, that allows you to refer to that check-in by its symbolic |
| 198 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 199 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| @@ -212,12 +211,12 @@ | |
| 211 | |
| 212 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 213 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 214 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 215 | are hence not known by the name "test." |
| 216 | To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 |
| 217 | into check-ins 4, 6, and 9, there is a cancellation tag for |
| 218 | <b>sym-trunk</b> on check-in 4. The net effect is that |
| 219 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 220 | on the test branch go by the symbolic name "test." |
| 221 | |
| 222 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| @@ -225,11 +224,11 @@ | |
| 224 | |
| 225 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 226 | not make a graphical distinction between one-time and propagating tags.) |
| 227 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 228 | using the more meaningful name "release-1.0." The <b>closed</b> tag means |
| 229 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 230 | never have direct children. |
| 231 | |
| 232 | <h2>Review Of Terminology</h2> |
| 233 | |
| 234 | <blockquote><dl> |
| 235 |
+8
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -12,10 +12,18 @@ | ||
| 12 | 12 | via a compile-time option. |
| 13 | 13 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 14 | 14 | [trace], [getParameter], [setParameter], and [artifact]</nowiki> commands |
| 15 | 15 | to TH1, primarily for use by TH1 hooks. |
| 16 | 16 | * Bring in the latest version of autosetup from upstream. |
| 17 | + * When committing a (non-binary) file which contains bytes forming an | |
| 18 | + invalid UTF-8 stream, fossil now adds the possibility to convert it | |
| 19 | + to a valid UTF-8 stream ('c') if you like. | |
| 20 | + * Let [/help?cmd=new|fossil new] no longer create an initial empty commit | |
| 21 | + by default. The first commit after checking out an empty repository will | |
| 22 | + become the initial commit. (NOT PLANNED FOR 1.30, BUT DONE TO EXPOSE | |
| 23 | + [/help?cmd=new|fossil new --empty] TO MORE FIELD TESTING BEFORE | |
| 24 | + MAKING ANY DECISION ON IT!) | |
| 17 | 25 | |
| 18 | 26 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 19 | 27 | * Add the ability to display content, diffs and annotations for UTF16 |
| 20 | 28 | text files in the web interface. |
| 21 | 29 | * Add the "SaveAs..." and "Invert" buttons |
| 22 | 30 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -12,10 +12,18 @@ | |
| 12 | via a compile-time option. |
| 13 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 14 | [trace], [getParameter], [setParameter], and [artifact]</nowiki> commands |
| 15 | to TH1, primarily for use by TH1 hooks. |
| 16 | * Bring in the latest version of autosetup from upstream. |
| 17 | |
| 18 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 19 | * Add the ability to display content, diffs and annotations for UTF16 |
| 20 | text files in the web interface. |
| 21 | * Add the "SaveAs..." and "Invert" buttons |
| 22 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -12,10 +12,18 @@ | |
| 12 | via a compile-time option. |
| 13 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 14 | [trace], [getParameter], [setParameter], and [artifact]</nowiki> commands |
| 15 | to TH1, primarily for use by TH1 hooks. |
| 16 | * Bring in the latest version of autosetup from upstream. |
| 17 | * When committing a (non-binary) file which contains bytes forming an |
| 18 | invalid UTF-8 stream, fossil now adds the possibility to convert it |
| 19 | to a valid UTF-8 stream ('c') if you like. |
| 20 | * Let [/help?cmd=new|fossil new] no longer create an initial empty commit |
| 21 | by default. The first commit after checking out an empty repository will |
| 22 | become the initial commit. (NOT PLANNED FOR 1.30, BUT DONE TO EXPOSE |
| 23 | [/help?cmd=new|fossil new --empty] TO MORE FIELD TESTING BEFORE |
| 24 | MAKING ANY DECISION ON IT!) |
| 25 | |
| 26 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 27 | * Add the ability to display content, diffs and annotations for UTF16 |
| 28 | text files in the web interface. |
| 29 | * Add the "SaveAs..." and "Invert" buttons |
| 30 |
+3
-3
| --- www/fileformat.wiki | ||
| +++ www/fileformat.wiki | ||
| @@ -28,12 +28,12 @@ | ||
| 28 | 28 | The local state is not composed of artifacts and is not intended to be enduring. |
| 29 | 29 | This document is concerned with global state only. Local state is only |
| 30 | 30 | mentioned here in order to distinguish it from global state. |
| 31 | 31 | |
| 32 | 32 | Each artifact in the repository is named by its SHA1 hash. |
| 33 | -No prefixes or meta information is added to a artifact before | |
| 34 | -its hash is computed. The name of a artifact in the repository | |
| 33 | +No prefixes or meta information is added to an artifact before | |
| 34 | +its hash is computed. The name of an artifact in the repository | |
| 35 | 35 | is exactly the same SHA1 hash that is computed by sha1sum |
| 36 | 36 | on the file as it exists in your source tree.</p> |
| 37 | 37 | |
| 38 | 38 | Some artifacts have a particular format which gives them special |
| 39 | 39 | meaning to fossil. Fossil recognizes: |
| @@ -238,11 +238,11 @@ | ||
| 238 | 238 | [/artifact/28987096ac | here]. |
| 239 | 239 | |
| 240 | 240 | <a name="cluster"></a> |
| 241 | 241 | <h2>2.0 Clusters</h2> |
| 242 | 242 | |
| 243 | -A cluster is a artifact that declares the existence of other artifacts. | |
| 243 | +A cluster is an artifact that declares the existence of other artifacts. | |
| 244 | 244 | Clusters are used during repository synchronization to help |
| 245 | 245 | reduce network traffic. As such, clusters are an optimization and |
| 246 | 246 | may be removed from a repository without loss or damage to the |
| 247 | 247 | underlying project code. |
| 248 | 248 | |
| 249 | 249 |
| --- www/fileformat.wiki | |
| +++ www/fileformat.wiki | |
| @@ -28,12 +28,12 @@ | |
| 28 | The local state is not composed of artifacts and is not intended to be enduring. |
| 29 | This document is concerned with global state only. Local state is only |
| 30 | mentioned here in order to distinguish it from global state. |
| 31 | |
| 32 | Each artifact in the repository is named by its SHA1 hash. |
| 33 | No prefixes or meta information is added to a artifact before |
| 34 | its hash is computed. The name of a artifact in the repository |
| 35 | is exactly the same SHA1 hash that is computed by sha1sum |
| 36 | on the file as it exists in your source tree.</p> |
| 37 | |
| 38 | Some artifacts have a particular format which gives them special |
| 39 | meaning to fossil. Fossil recognizes: |
| @@ -238,11 +238,11 @@ | |
| 238 | [/artifact/28987096ac | here]. |
| 239 | |
| 240 | <a name="cluster"></a> |
| 241 | <h2>2.0 Clusters</h2> |
| 242 | |
| 243 | A cluster is a artifact that declares the existence of other artifacts. |
| 244 | Clusters are used during repository synchronization to help |
| 245 | reduce network traffic. As such, clusters are an optimization and |
| 246 | may be removed from a repository without loss or damage to the |
| 247 | underlying project code. |
| 248 | |
| 249 |
| --- www/fileformat.wiki | |
| +++ www/fileformat.wiki | |
| @@ -28,12 +28,12 @@ | |
| 28 | The local state is not composed of artifacts and is not intended to be enduring. |
| 29 | This document is concerned with global state only. Local state is only |
| 30 | mentioned here in order to distinguish it from global state. |
| 31 | |
| 32 | Each artifact in the repository is named by its SHA1 hash. |
| 33 | No prefixes or meta information is added to an artifact before |
| 34 | its hash is computed. The name of an artifact in the repository |
| 35 | is exactly the same SHA1 hash that is computed by sha1sum |
| 36 | on the file as it exists in your source tree.</p> |
| 37 | |
| 38 | Some artifacts have a particular format which gives them special |
| 39 | meaning to fossil. Fossil recognizes: |
| @@ -238,11 +238,11 @@ | |
| 238 | [/artifact/28987096ac | here]. |
| 239 | |
| 240 | <a name="cluster"></a> |
| 241 | <h2>2.0 Clusters</h2> |
| 242 | |
| 243 | A cluster is an artifact that declares the existence of other artifacts. |
| 244 | Clusters are used during repository synchronization to help |
| 245 | reduce network traffic. As such, clusters are an optimization and |
| 246 | may be removed from a repository without loss or damage to the |
| 247 | underlying project code. |
| 248 | |
| 249 |
+1
-1
| --- www/pop.wiki | ||
| +++ www/pop.wiki | ||
| @@ -31,11 +31,11 @@ | ||
| 31 | 31 | In many contexts, the name can be |
| 32 | 32 | abbreviated to a unique prefix. A five- or six-character |
| 33 | 33 | prefix usually suffices to uniquely identify a file.</p></li> |
| 34 | 34 | |
| 35 | 35 | <li><p>Because artifacts are named by their SHA1 hash, all artifacts |
| 36 | -are immutable. Any change to the content of a artifact also | |
| 36 | +are immutable. Any change to the content of an artifact also | |
| 37 | 37 | changes the hash that forms the artifacts name, thus |
| 38 | 38 | creating a new artifact. Both the old original version of the |
| 39 | 39 | artifact and the new change are preserved under different names.</p></li> |
| 40 | 40 | |
| 41 | 41 | <li><p>It is theoretically possible for two artifacts with different |
| 42 | 42 |
| --- www/pop.wiki | |
| +++ www/pop.wiki | |
| @@ -31,11 +31,11 @@ | |
| 31 | In many contexts, the name can be |
| 32 | abbreviated to a unique prefix. A five- or six-character |
| 33 | prefix usually suffices to uniquely identify a file.</p></li> |
| 34 | |
| 35 | <li><p>Because artifacts are named by their SHA1 hash, all artifacts |
| 36 | are immutable. Any change to the content of a artifact also |
| 37 | changes the hash that forms the artifacts name, thus |
| 38 | creating a new artifact. Both the old original version of the |
| 39 | artifact and the new change are preserved under different names.</p></li> |
| 40 | |
| 41 | <li><p>It is theoretically possible for two artifacts with different |
| 42 |
| --- www/pop.wiki | |
| +++ www/pop.wiki | |
| @@ -31,11 +31,11 @@ | |
| 31 | In many contexts, the name can be |
| 32 | abbreviated to a unique prefix. A five- or six-character |
| 33 | prefix usually suffices to uniquely identify a file.</p></li> |
| 34 | |
| 35 | <li><p>Because artifacts are named by their SHA1 hash, all artifacts |
| 36 | are immutable. Any change to the content of an artifact also |
| 37 | changes the hash that forms the artifacts name, thus |
| 38 | creating a new artifact. Both the old original version of the |
| 39 | artifact and the new change are preserved under different names.</p></li> |
| 40 | |
| 41 | <li><p>It is theoretically possible for two artifacts with different |
| 42 |
+11
-1
| --- www/quotes.wiki | ||
| +++ www/quotes.wiki | ||
| @@ -70,10 +70,20 @@ | ||
| 70 | 70 | get a bug-tracking system to work with mercurial. |
| 71 | 71 | |
| 72 | 72 | <blockquote> |
| 73 | 73 | <i>rawjeev at [http://stackoverflow.com/questions/156322/what-do-people-think-of-the-fossil-dvcs]</i> |
| 74 | 74 | </blockquote> |
| 75 | + | |
| 76 | +<li>Fossil is the best thing to happen | |
| 77 | +to my development workflow this year, as I am pretty sure that using | |
| 78 | +Git has resulted in the premature death of too many of my brain cells. | |
| 79 | +I'm glad to be able to replace Git in every place that I possibly can | |
| 80 | +with Fossil. | |
| 81 | + | |
| 82 | +<blockquote> | |
| 83 | +<i>Joe Prostko at [http://www.mail-archive.com/[email protected]/msg16716.html] | |
| 84 | +</blockquote> | |
| 75 | 85 | |
| 76 | 86 | <li>Fossil is awesome!!! I have never seen an app like that before, |
| 77 | 87 | such simplicity and flexibility!!! |
| 78 | 88 | |
| 79 | 89 | <blockquote> |
| @@ -85,11 +95,11 @@ | ||
| 85 | 95 | |
| 86 | 96 | |
| 87 | 97 | <h2>On Git Versus Fossil</h2> |
| 88 | 98 | |
| 89 | 99 | <ol> |
| 90 | -<li value=9> | |
| 100 | +<li value=10> | |
| 91 | 101 | Just want to say thanks for fossil making my life easier.... |
| 92 | 102 | Also <nowiki>[for]</nowiki> not having a misanthropic command line interface. |
| 93 | 103 | |
| 94 | 104 | <blockquote> |
| 95 | 105 | <i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i> |
| 96 | 106 |
| --- www/quotes.wiki | |
| +++ www/quotes.wiki | |
| @@ -70,10 +70,20 @@ | |
| 70 | get a bug-tracking system to work with mercurial. |
| 71 | |
| 72 | <blockquote> |
| 73 | <i>rawjeev at [http://stackoverflow.com/questions/156322/what-do-people-think-of-the-fossil-dvcs]</i> |
| 74 | </blockquote> |
| 75 | |
| 76 | <li>Fossil is awesome!!! I have never seen an app like that before, |
| 77 | such simplicity and flexibility!!! |
| 78 | |
| 79 | <blockquote> |
| @@ -85,11 +95,11 @@ | |
| 85 | |
| 86 | |
| 87 | <h2>On Git Versus Fossil</h2> |
| 88 | |
| 89 | <ol> |
| 90 | <li value=9> |
| 91 | Just want to say thanks for fossil making my life easier.... |
| 92 | Also <nowiki>[for]</nowiki> not having a misanthropic command line interface. |
| 93 | |
| 94 | <blockquote> |
| 95 | <i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i> |
| 96 |
| --- www/quotes.wiki | |
| +++ www/quotes.wiki | |
| @@ -70,10 +70,20 @@ | |
| 70 | get a bug-tracking system to work with mercurial. |
| 71 | |
| 72 | <blockquote> |
| 73 | <i>rawjeev at [http://stackoverflow.com/questions/156322/what-do-people-think-of-the-fossil-dvcs]</i> |
| 74 | </blockquote> |
| 75 | |
| 76 | <li>Fossil is the best thing to happen |
| 77 | to my development workflow this year, as I am pretty sure that using |
| 78 | Git has resulted in the premature death of too many of my brain cells. |
| 79 | I'm glad to be able to replace Git in every place that I possibly can |
| 80 | with Fossil. |
| 81 | |
| 82 | <blockquote> |
| 83 | <i>Joe Prostko at [http://www.mail-archive.com/[email protected]/msg16716.html] |
| 84 | </blockquote> |
| 85 | |
| 86 | <li>Fossil is awesome!!! I have never seen an app like that before, |
| 87 | such simplicity and flexibility!!! |
| 88 | |
| 89 | <blockquote> |
| @@ -85,11 +95,11 @@ | |
| 95 | |
| 96 | |
| 97 | <h2>On Git Versus Fossil</h2> |
| 98 | |
| 99 | <ol> |
| 100 | <li value=10> |
| 101 | Just want to say thanks for fossil making my life easier.... |
| 102 | Also <nowiki>[for]</nowiki> not having a misanthropic command line interface. |
| 103 | |
| 104 | <blockquote> |
| 105 | <i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i> |
| 106 |
+1
-1
| --- www/shunning.wiki | ||
| +++ www/shunning.wiki | ||
| @@ -42,11 +42,11 @@ | ||
| 42 | 42 | the shunning list does not propagate is a security feature. If the |
| 43 | 43 | shunning list propagated then a malicious user (or |
| 44 | 44 | a bug in the fossil code) might introduce a shun record that would |
| 45 | 45 | propagate through all repositories in a network and permanently |
| 46 | 46 | destroy vital information. By refusing to propagate the shunning list, |
| 47 | -Fossil insures that no remote user will ever be able to remove | |
| 47 | +Fossil ensures that no remote user will ever be able to remove | |
| 48 | 48 | information from your personal repositories without your permission. |
| 49 | 49 | |
| 50 | 50 | The shunning list does not propagate to a remote repository |
| 51 | 51 | by the normal "sync" mechanism, |
| 52 | 52 | but it is still possible to copy shuns from one repository to another |
| 53 | 53 |
| --- www/shunning.wiki | |
| +++ www/shunning.wiki | |
| @@ -42,11 +42,11 @@ | |
| 42 | the shunning list does not propagate is a security feature. If the |
| 43 | shunning list propagated then a malicious user (or |
| 44 | a bug in the fossil code) might introduce a shun record that would |
| 45 | propagate through all repositories in a network and permanently |
| 46 | destroy vital information. By refusing to propagate the shunning list, |
| 47 | Fossil insures that no remote user will ever be able to remove |
| 48 | information from your personal repositories without your permission. |
| 49 | |
| 50 | The shunning list does not propagate to a remote repository |
| 51 | by the normal "sync" mechanism, |
| 52 | but it is still possible to copy shuns from one repository to another |
| 53 |
| --- www/shunning.wiki | |
| +++ www/shunning.wiki | |
| @@ -42,11 +42,11 @@ | |
| 42 | the shunning list does not propagate is a security feature. If the |
| 43 | shunning list propagated then a malicious user (or |
| 44 | a bug in the fossil code) might introduce a shun record that would |
| 45 | propagate through all repositories in a network and permanently |
| 46 | destroy vital information. By refusing to propagate the shunning list, |
| 47 | Fossil ensures that no remote user will ever be able to remove |
| 48 | information from your personal repositories without your permission. |
| 49 | |
| 50 | The shunning list does not propagate to a remote repository |
| 51 | by the normal "sync" mechanism, |
| 52 | but it is still possible to copy shuns from one repository to another |
| 53 |
+58
-12
| --- www/sync.wiki | ||
| +++ www/sync.wiki | ||
| @@ -159,15 +159,21 @@ | ||
| 159 | 159 | |
| 160 | 160 | <p>Privileges are cumulative. There can be multiple successful |
| 161 | 161 | login cards. The session privileges are the bit-wise OR of the |
| 162 | 162 | privileges of each individual login.</p> |
| 163 | 163 | |
| 164 | -<h3>3.3 File Cards</h3> | |
| 164 | +<h3>3.3 File and Compressed File Cards</h3> | |
| 165 | 165 | |
| 166 | -<p>Artifacts are transferred using "file" cards. (The name "file" | |
| 167 | -card comes from the fact that most artifacts correspond to files.) | |
| 168 | -File cards come in two different formats depending | |
| 166 | +<p>Artifacts are transferred using either "file" cards, or "cfile" cards. | |
| 167 | +(The name "file" card comes from the fact that most artifacts correspond to | |
| 168 | +files, and "cfile" is just a compressed file.) | |
| 169 | +</p> | |
| 170 | + | |
| 171 | +<h4>3.3.1 File Cards</h4> | |
| 172 | + | |
| 173 | +<p>For sync protocols, artifacts are transferred using "file" | |
| 174 | +cards. File cards come in two different formats depending | |
| 169 | 175 | on whether the artifact is sent directly or as a delta from some |
| 170 | 176 | other artifact.</p> |
| 171 | 177 | |
| 172 | 178 | <blockquote> |
| 173 | 179 | <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i><br> |
| @@ -176,11 +182,11 @@ | ||
| 176 | 182 | |
| 177 | 183 | <p>File cards are different from all other cards in that they |
| 178 | 184 | followed by in-line "payload" data. The content of the artifact |
| 179 | 185 | or the artifact delta consists of the first <i>size</i> bytes of the |
| 180 | 186 | x-fossil content that immediately follow the newline that |
| 181 | -terminates the file card. No other cards have this characteristic. | |
| 187 | +terminates the file card. Only file and cfile cards have this characteristic. | |
| 182 | 188 | </p> |
| 183 | 189 | |
| 184 | 190 | <p>The first argument of a file card is the ID of the artifact that |
| 185 | 191 | is being transferred. The artifact ID is the lower-case hexadecimal |
| 186 | 192 | representation of the SHA1 hash of the artifact. |
| @@ -194,10 +200,43 @@ | ||
| 194 | 200 | <p>File cards are sent in both directions: client to server and |
| 195 | 201 | server to client. A delta might be sent before the source of |
| 196 | 202 | the delta, so both client and server should remember deltas |
| 197 | 203 | and be able to apply them when their source arrives.</p> |
| 198 | 204 | |
| 205 | +<h4>3.3.2 Compressed File Cards</h4> | |
| 206 | + | |
| 207 | +<p>A client that sends a clone protocol version "3" or greater will | |
| 208 | +receive artifacts as "cfile" cards while cloning. This card was | |
| 209 | +introduced to improve the speed of the transfer of content by sending the | |
| 210 | +compressed artifact directly from the server database to the client.</p> | |
| 211 | + | |
| 212 | +<p>Compressed File cards are similar to File cards, sharing the same | |
| 213 | +in-line "payload" data characteristics and also the same treatment of | |
| 214 | +direct content or delta content. It comes in two different formats | |
| 215 | +depending on whether the artifact is sent directly or as a delta from | |
| 216 | +some other artifact.</p> | |
| 217 | + | |
| 218 | +<blockquote> | |
| 219 | +<b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br> | |
| 220 | +<b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br> | |
| 221 | +</blockquote> | |
| 222 | + | |
| 223 | +<p>The first argument of the cfile card is the ID of the artifact that | |
| 224 | +is being transferred. The artifact ID is the lower-case hexadecimal | |
| 225 | +representation of the SHA1 hash of the artifact. The second argument of | |
| 226 | +the cfile card is the original size in bytes of the artifact. The last | |
| 227 | +argument of the cfile card is the number of compressed bytes of payload | |
| 228 | +that immediately follow the cfile card. If the cfile card has only | |
| 229 | +three arguments, that means the payload is the complete content of the | |
| 230 | +artifact. If the cfile card has four arguments, then the payload is a | |
| 231 | +delta and the second argument is the ID of another artifact that is the | |
| 232 | +source of the delta and the third argument is the original size of the | |
| 233 | +delta artifact.</p> | |
| 234 | + | |
| 235 | +<p>Unlike file cards, cfile cards are only sent in one direction during a | |
| 236 | +clone from server to client for clone protocol version "3" or greater.</p> | |
| 237 | + | |
| 199 | 238 | <h3>3.4 Push and Pull Cards</h3> |
| 200 | 239 | |
| 201 | 240 | <p>Among the first cards in a client-to-server message are |
| 202 | 241 | the push and pull cards. The push card tells the server that |
| 203 | 242 | the client is pushing content. The pull card tells the server |
| @@ -232,15 +271,22 @@ | ||
| 232 | 271 | <blockquote> |
| 233 | 272 | <b>clone</b><br> |
| 234 | 273 | <b>clone</b> <i>protocol-version sequence-number</i> |
| 235 | 274 | </blockquote> |
| 236 | 275 | |
| 237 | -<h4>3.5.1 Protocol 2</h4> | |
| 276 | +<h4>3.5.1 Protocol 3</h4> | |
| 238 | 277 | |
| 239 | 278 | <p>The latest clients send a two-argument clone message with a |
| 240 | -protocol version of "2". (Future versions of Fossil might use larger | |
| 241 | -protocol version numbers.) The sequence-number sent is the number | |
| 279 | +protocol version of "3". (Future versions of Fossil might use larger | |
| 280 | +protocol version numbers.) Version "3" of the protocol enhanced version | |
| 281 | +"2" by introducing the "cfile" card which is intended to speed up clone | |
| 282 | +operations. Instead of sending "file" cards, the server will send "cfile" | |
| 283 | +cards</p> | |
| 284 | + | |
| 285 | +<h4>3.5.2 Protocol 2</h4> | |
| 286 | + | |
| 287 | +<p>The sequence-number sent is the number | |
| 242 | 288 | of artifacts received so far. For the first clone message, the |
| 243 | 289 | sequence number is 0. The server will respond by sending file |
| 244 | 290 | cards for some number of artifacts up to the maximum message size. |
| 245 | 291 | |
| 246 | 292 | <p>The server will also send a single "clone_seqno" card to the client |
| @@ -256,11 +302,11 @@ | ||
| 256 | 302 | |
| 257 | 303 | <p>In response to an initial clone message, the server also sends the client |
| 258 | 304 | a push message so that the client can discover the projectcode for |
| 259 | 305 | this project.</p> |
| 260 | 306 | |
| 261 | -<h4>3.5.2 Legacy Protocol</h4> | |
| 307 | +<h4>3.5.3 Legacy Protocol</h4> | |
| 262 | 308 | |
| 263 | 309 | <p>Older clients send a clone card with no argument. The server responds |
| 264 | 310 | to a blank clone card by sending an "igot" card for every artifact in the |
| 265 | 311 | repository. The client will then issue "gimme" cards to pull down all the |
| 266 | 312 | content it needs. |
| @@ -447,14 +493,14 @@ | ||
| 447 | 493 | <p>If either the client or the server sees a card that is not |
| 448 | 494 | described above, then it generates an error and aborts.</p> |
| 449 | 495 | |
| 450 | 496 | <h2>4.0 Phantoms And Clusters</h2> |
| 451 | 497 | |
| 452 | -<p>When a repository knows that a artifact exists and knows the ID of | |
| 498 | +<p>When a repository knows that an artifact exists and knows the ID of | |
| 453 | 499 | that artifact, but it does not know the artifact content, then it stores that |
| 454 | 500 | artifact as a "phantom". A repository will typically create a phantom when |
| 455 | -it receives an igot card for a artifact that it does not hold or when it | |
| 501 | +it receives an igot card for an artifact that it does not hold or when it | |
| 456 | 502 | receives a file card that references a delta source that it does not |
| 457 | 503 | hold. When a server is generating its reply or when a client is |
| 458 | 504 | generating a new request, it will usually send gimme cards for every |
| 459 | 505 | phantom that it holds.</p> |
| 460 | 506 | |
| @@ -468,11 +514,11 @@ | ||
| 468 | 514 | single argument. No extra whitespace and no trailing or leading |
| 469 | 515 | whitespace is allowed. All cards in the cluster must occur in |
| 470 | 516 | strict lexicographical order.</p> |
| 471 | 517 | |
| 472 | 518 | <p>A cluster consists of one or more "M" cards followed by a single |
| 473 | -"Z" card. Each M card holds an argument which is a artifact ID for an | |
| 519 | +"Z" card. Each M card holds an argument which is an artifact ID for an | |
| 474 | 520 | artifact in the repository. The Z card has a single argument which is the |
| 475 | 521 | lower-case hexadecimal representation of the MD5 checksum of all |
| 476 | 522 | preceding M cards up to and included the newline character that |
| 477 | 523 | occurred just before the Z that starts the Z card.</p> |
| 478 | 524 | |
| 479 | 525 |
| --- www/sync.wiki | |
| +++ www/sync.wiki | |
| @@ -159,15 +159,21 @@ | |
| 159 | |
| 160 | <p>Privileges are cumulative. There can be multiple successful |
| 161 | login cards. The session privileges are the bit-wise OR of the |
| 162 | privileges of each individual login.</p> |
| 163 | |
| 164 | <h3>3.3 File Cards</h3> |
| 165 | |
| 166 | <p>Artifacts are transferred using "file" cards. (The name "file" |
| 167 | card comes from the fact that most artifacts correspond to files.) |
| 168 | File cards come in two different formats depending |
| 169 | on whether the artifact is sent directly or as a delta from some |
| 170 | other artifact.</p> |
| 171 | |
| 172 | <blockquote> |
| 173 | <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i><br> |
| @@ -176,11 +182,11 @@ | |
| 176 | |
| 177 | <p>File cards are different from all other cards in that they |
| 178 | followed by in-line "payload" data. The content of the artifact |
| 179 | or the artifact delta consists of the first <i>size</i> bytes of the |
| 180 | x-fossil content that immediately follow the newline that |
| 181 | terminates the file card. No other cards have this characteristic. |
| 182 | </p> |
| 183 | |
| 184 | <p>The first argument of a file card is the ID of the artifact that |
| 185 | is being transferred. The artifact ID is the lower-case hexadecimal |
| 186 | representation of the SHA1 hash of the artifact. |
| @@ -194,10 +200,43 @@ | |
| 194 | <p>File cards are sent in both directions: client to server and |
| 195 | server to client. A delta might be sent before the source of |
| 196 | the delta, so both client and server should remember deltas |
| 197 | and be able to apply them when their source arrives.</p> |
| 198 | |
| 199 | <h3>3.4 Push and Pull Cards</h3> |
| 200 | |
| 201 | <p>Among the first cards in a client-to-server message are |
| 202 | the push and pull cards. The push card tells the server that |
| 203 | the client is pushing content. The pull card tells the server |
| @@ -232,15 +271,22 @@ | |
| 232 | <blockquote> |
| 233 | <b>clone</b><br> |
| 234 | <b>clone</b> <i>protocol-version sequence-number</i> |
| 235 | </blockquote> |
| 236 | |
| 237 | <h4>3.5.1 Protocol 2</h4> |
| 238 | |
| 239 | <p>The latest clients send a two-argument clone message with a |
| 240 | protocol version of "2". (Future versions of Fossil might use larger |
| 241 | protocol version numbers.) The sequence-number sent is the number |
| 242 | of artifacts received so far. For the first clone message, the |
| 243 | sequence number is 0. The server will respond by sending file |
| 244 | cards for some number of artifacts up to the maximum message size. |
| 245 | |
| 246 | <p>The server will also send a single "clone_seqno" card to the client |
| @@ -256,11 +302,11 @@ | |
| 256 | |
| 257 | <p>In response to an initial clone message, the server also sends the client |
| 258 | a push message so that the client can discover the projectcode for |
| 259 | this project.</p> |
| 260 | |
| 261 | <h4>3.5.2 Legacy Protocol</h4> |
| 262 | |
| 263 | <p>Older clients send a clone card with no argument. The server responds |
| 264 | to a blank clone card by sending an "igot" card for every artifact in the |
| 265 | repository. The client will then issue "gimme" cards to pull down all the |
| 266 | content it needs. |
| @@ -447,14 +493,14 @@ | |
| 447 | <p>If either the client or the server sees a card that is not |
| 448 | described above, then it generates an error and aborts.</p> |
| 449 | |
| 450 | <h2>4.0 Phantoms And Clusters</h2> |
| 451 | |
| 452 | <p>When a repository knows that a artifact exists and knows the ID of |
| 453 | that artifact, but it does not know the artifact content, then it stores that |
| 454 | artifact as a "phantom". A repository will typically create a phantom when |
| 455 | it receives an igot card for a artifact that it does not hold or when it |
| 456 | receives a file card that references a delta source that it does not |
| 457 | hold. When a server is generating its reply or when a client is |
| 458 | generating a new request, it will usually send gimme cards for every |
| 459 | phantom that it holds.</p> |
| 460 | |
| @@ -468,11 +514,11 @@ | |
| 468 | single argument. No extra whitespace and no trailing or leading |
| 469 | whitespace is allowed. All cards in the cluster must occur in |
| 470 | strict lexicographical order.</p> |
| 471 | |
| 472 | <p>A cluster consists of one or more "M" cards followed by a single |
| 473 | "Z" card. Each M card holds an argument which is a artifact ID for an |
| 474 | artifact in the repository. The Z card has a single argument which is the |
| 475 | lower-case hexadecimal representation of the MD5 checksum of all |
| 476 | preceding M cards up to and included the newline character that |
| 477 | occurred just before the Z that starts the Z card.</p> |
| 478 | |
| 479 |
| --- www/sync.wiki | |
| +++ www/sync.wiki | |
| @@ -159,15 +159,21 @@ | |
| 159 | |
| 160 | <p>Privileges are cumulative. There can be multiple successful |
| 161 | login cards. The session privileges are the bit-wise OR of the |
| 162 | privileges of each individual login.</p> |
| 163 | |
| 164 | <h3>3.3 File and Compressed File Cards</h3> |
| 165 | |
| 166 | <p>Artifacts are transferred using either "file" cards, or "cfile" cards. |
| 167 | (The name "file" card comes from the fact that most artifacts correspond to |
| 168 | files, and "cfile" is just a compressed file.) |
| 169 | </p> |
| 170 | |
| 171 | <h4>3.3.1 File Cards</h4> |
| 172 | |
| 173 | <p>For sync protocols, artifacts are transferred using "file" |
| 174 | cards. File cards come in two different formats depending |
| 175 | on whether the artifact is sent directly or as a delta from some |
| 176 | other artifact.</p> |
| 177 | |
| 178 | <blockquote> |
| 179 | <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i><br> |
| @@ -176,11 +182,11 @@ | |
| 182 | |
| 183 | <p>File cards are different from all other cards in that they |
| 184 | followed by in-line "payload" data. The content of the artifact |
| 185 | or the artifact delta consists of the first <i>size</i> bytes of the |
| 186 | x-fossil content that immediately follow the newline that |
| 187 | terminates the file card. Only file and cfile cards have this characteristic. |
| 188 | </p> |
| 189 | |
| 190 | <p>The first argument of a file card is the ID of the artifact that |
| 191 | is being transferred. The artifact ID is the lower-case hexadecimal |
| 192 | representation of the SHA1 hash of the artifact. |
| @@ -194,10 +200,43 @@ | |
| 200 | <p>File cards are sent in both directions: client to server and |
| 201 | server to client. A delta might be sent before the source of |
| 202 | the delta, so both client and server should remember deltas |
| 203 | and be able to apply them when their source arrives.</p> |
| 204 | |
| 205 | <h4>3.3.2 Compressed File Cards</h4> |
| 206 | |
| 207 | <p>A client that sends a clone protocol version "3" or greater will |
| 208 | receive artifacts as "cfile" cards while cloning. This card was |
| 209 | introduced to improve the speed of the transfer of content by sending the |
| 210 | compressed artifact directly from the server database to the client.</p> |
| 211 | |
| 212 | <p>Compressed File cards are similar to File cards, sharing the same |
| 213 | in-line "payload" data characteristics and also the same treatment of |
| 214 | direct content or delta content. It comes in two different formats |
| 215 | depending on whether the artifact is sent directly or as a delta from |
| 216 | some other artifact.</p> |
| 217 | |
| 218 | <blockquote> |
| 219 | <b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br> |
| 220 | <b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br> |
| 221 | </blockquote> |
| 222 | |
| 223 | <p>The first argument of the cfile card is the ID of the artifact that |
| 224 | is being transferred. The artifact ID is the lower-case hexadecimal |
| 225 | representation of the SHA1 hash of the artifact. The second argument of |
| 226 | the cfile card is the original size in bytes of the artifact. The last |
| 227 | argument of the cfile card is the number of compressed bytes of payload |
| 228 | that immediately follow the cfile card. If the cfile card has only |
| 229 | three arguments, that means the payload is the complete content of the |
| 230 | artifact. If the cfile card has four arguments, then the payload is a |
| 231 | delta and the second argument is the ID of another artifact that is the |
| 232 | source of the delta and the third argument is the original size of the |
| 233 | delta artifact.</p> |
| 234 | |
| 235 | <p>Unlike file cards, cfile cards are only sent in one direction during a |
| 236 | clone from server to client for clone protocol version "3" or greater.</p> |
| 237 | |
| 238 | <h3>3.4 Push and Pull Cards</h3> |
| 239 | |
| 240 | <p>Among the first cards in a client-to-server message are |
| 241 | the push and pull cards. The push card tells the server that |
| 242 | the client is pushing content. The pull card tells the server |
| @@ -232,15 +271,22 @@ | |
| 271 | <blockquote> |
| 272 | <b>clone</b><br> |
| 273 | <b>clone</b> <i>protocol-version sequence-number</i> |
| 274 | </blockquote> |
| 275 | |
| 276 | <h4>3.5.1 Protocol 3</h4> |
| 277 | |
| 278 | <p>The latest clients send a two-argument clone message with a |
| 279 | protocol version of "3". (Future versions of Fossil might use larger |
| 280 | protocol version numbers.) Version "3" of the protocol enhanced version |
| 281 | "2" by introducing the "cfile" card which is intended to speed up clone |
| 282 | operations. Instead of sending "file" cards, the server will send "cfile" |
| 283 | cards</p> |
| 284 | |
| 285 | <h4>3.5.2 Protocol 2</h4> |
| 286 | |
| 287 | <p>The sequence-number sent is the number |
| 288 | of artifacts received so far. For the first clone message, the |
| 289 | sequence number is 0. The server will respond by sending file |
| 290 | cards for some number of artifacts up to the maximum message size. |
| 291 | |
| 292 | <p>The server will also send a single "clone_seqno" card to the client |
| @@ -256,11 +302,11 @@ | |
| 302 | |
| 303 | <p>In response to an initial clone message, the server also sends the client |
| 304 | a push message so that the client can discover the projectcode for |
| 305 | this project.</p> |
| 306 | |
| 307 | <h4>3.5.3 Legacy Protocol</h4> |
| 308 | |
| 309 | <p>Older clients send a clone card with no argument. The server responds |
| 310 | to a blank clone card by sending an "igot" card for every artifact in the |
| 311 | repository. The client will then issue "gimme" cards to pull down all the |
| 312 | content it needs. |
| @@ -447,14 +493,14 @@ | |
| 493 | <p>If either the client or the server sees a card that is not |
| 494 | described above, then it generates an error and aborts.</p> |
| 495 | |
| 496 | <h2>4.0 Phantoms And Clusters</h2> |
| 497 | |
| 498 | <p>When a repository knows that an artifact exists and knows the ID of |
| 499 | that artifact, but it does not know the artifact content, then it stores that |
| 500 | artifact as a "phantom". A repository will typically create a phantom when |
| 501 | it receives an igot card for an artifact that it does not hold or when it |
| 502 | receives a file card that references a delta source that it does not |
| 503 | hold. When a server is generating its reply or when a client is |
| 504 | generating a new request, it will usually send gimme cards for every |
| 505 | phantom that it holds.</p> |
| 506 | |
| @@ -468,11 +514,11 @@ | |
| 514 | single argument. No extra whitespace and no trailing or leading |
| 515 | whitespace is allowed. All cards in the cluster must occur in |
| 516 | strict lexicographical order.</p> |
| 517 | |
| 518 | <p>A cluster consists of one or more "M" cards followed by a single |
| 519 | "Z" card. Each M card holds an argument which is an artifact ID for an |
| 520 | artifact in the repository. The Z card has a single argument which is the |
| 521 | lower-case hexadecimal representation of the MD5 checksum of all |
| 522 | preceding M cards up to and included the newline character that |
| 523 | occurred just before the Z that starts the Z card.</p> |
| 524 | |
| 525 |