Fossil SCM
Merge trunk with ben-testing
Commit
74d65bab28c8c27ba544df42a16c84342bc7b4d2
Parent
7bbeb8820592aea…
53 files changed
+18
-5
+45
+1
-1
+2
+35
+1
+30
+63
+30
+314
+307
+1
+9
+388
+2
+130
+21
+3
+51
-32
+1
-1
+12
-2
+8
-3
+8
-3
+5
-1
+9
-6
+9
-6
+11
-5
+6
-2
+6
-2
+10
-2
+18
-10
+1
-1
+1
-1
+444
-269
+12
-11
+1
+1
-1
+8
-20
+644
-9
+7
-1
+2
-2
+1
-1
+2
-2
+3
-3
+24
-15
+3
+73
-16
+60
+2
+20
-14
+8
-6
+4
-1
+15
-7
~
BUILD.txt
~
GNUmakefile.in
~
VERSION
~
auto.def
~
autosetup/LICENSE
~
autosetup/README.autosetup
~
autosetup/autosetup
~
autosetup/cc-lib.tcl
~
autosetup/cc-shared.tcl
~
autosetup/cc.tcl
~
autosetup/config.guess
~
autosetup/config.sub
~
autosetup/find-tclsh
~
autosetup/jimsh0.c
~
autosetup/local.tcl
~
autosetup/system.tcl
~
autosetup/test-tclsh
~
configure
~
src/branch.c
~
src/browse.c
~
src/cgi.c
~
src/clone.c
~
src/clone.c
~
src/config.h
~
src/db.c
~
src/db.c
~
src/info.c
~
src/main.c
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/printf.c
~
src/rebuild.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/stash.c
~
src/tkt.c
~
src/wiki.c
~
src/winhttp.c
~
test/release-checklist.wiki
~
win/Makefile.PellesCGMake
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.msc
~
www/build.wiki
~
www/changes.wiki
~
www/checkin.wiki
~
www/foss-cklist.wiki
~
www/index.wiki
~
www/makefile.wiki
~
www/mkindex.tcl
~
www/permutedindex.wiki
~
www/quickstart.wiki
+18
-5
| --- BUILD.txt | ||
| +++ BUILD.txt | ||
| @@ -1,15 +1,28 @@ | ||
| 1 | -All of the source code for fossil is contained in the src/ subdirectory. | |
| 2 | -But there is a lot of generated code, so you will probably want to | |
| 3 | -use the Makefile. To do a complete build on unix, just type: | |
| 1 | +To do a complete build on most unix systems, just type: | |
| 4 | 2 | |
| 5 | 3 | make |
| 4 | + | |
| 5 | +If you have an unusual unix system for which the standard Makefile | |
| 6 | +will not work, or if you want to do some non-standard options, you can | |
| 7 | +also run: | |
| 8 | + | |
| 9 | + ./configure; make | |
| 10 | + | |
| 11 | +The ./configure script builds GNUmakefile which will be used in place | |
| 12 | +of Makefile. Run "./configure --help" for a listing of the available | |
| 13 | +options. | |
| 6 | 14 | |
| 7 | 15 | On a windows box, use one of the Makefiles in the win/ subdirectory, |
| 8 | -according to your compiler and environment. For example: | |
| 16 | +according to your compiler and environment. If you have GCC and MSYS | |
| 17 | +installed on your system, the consider: | |
| 18 | + | |
| 19 | + make -f win/Makefile.mingw | |
| 20 | + | |
| 21 | +If you have VC++ installed on your system, then consider: | |
| 9 | 22 | |
| 10 | - make -f win/Makefile.w32 | |
| 23 | + cd win; nmake /f Makefile.msc | |
| 11 | 24 | |
| 12 | 25 | If you have trouble, or you want to do something fancy, just look at |
| 13 | 26 | top level makefile. There are 6 configuration options that are all well |
| 14 | 27 | commented. Instead of editing the Makefile, consider copying the Makefile |
| 15 | 28 | to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile" |
| 16 | 29 | |
| 17 | 30 | ADDED GNUmakefile.in |
| --- BUILD.txt | |
| +++ BUILD.txt | |
| @@ -1,15 +1,28 @@ | |
| 1 | All of the source code for fossil is contained in the src/ subdirectory. |
| 2 | But there is a lot of generated code, so you will probably want to |
| 3 | use the Makefile. To do a complete build on unix, just type: |
| 4 | |
| 5 | make |
| 6 | |
| 7 | On a windows box, use one of the Makefiles in the win/ subdirectory, |
| 8 | according to your compiler and environment. For example: |
| 9 | |
| 10 | make -f win/Makefile.w32 |
| 11 | |
| 12 | If you have trouble, or you want to do something fancy, just look at |
| 13 | top level makefile. There are 6 configuration options that are all well |
| 14 | commented. Instead of editing the Makefile, consider copying the Makefile |
| 15 | to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile" |
| 16 | |
| 17 | DDED GNUmakefile.in |
| --- BUILD.txt | |
| +++ BUILD.txt | |
| @@ -1,15 +1,28 @@ | |
| 1 | To do a complete build on most unix systems, just type: |
| 2 | |
| 3 | make |
| 4 | |
| 5 | If you have an unusual unix system for which the standard Makefile |
| 6 | will not work, or if you want to do some non-standard options, you can |
| 7 | also run: |
| 8 | |
| 9 | ./configure; make |
| 10 | |
| 11 | The ./configure script builds GNUmakefile which will be used in place |
| 12 | of Makefile. Run "./configure --help" for a listing of the available |
| 13 | options. |
| 14 | |
| 15 | On a windows box, use one of the Makefiles in the win/ subdirectory, |
| 16 | according to your compiler and environment. If you have GCC and MSYS |
| 17 | installed on your system, the consider: |
| 18 | |
| 19 | make -f win/Makefile.mingw |
| 20 | |
| 21 | If you have VC++ installed on your system, then consider: |
| 22 | |
| 23 | cd win; nmake /f Makefile.msc |
| 24 | |
| 25 | If you have trouble, or you want to do something fancy, just look at |
| 26 | top level makefile. There are 6 configuration options that are all well |
| 27 | commented. Instead of editing the Makefile, consider copying the Makefile |
| 28 | to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile" |
| 29 | |
| 30 | DDED GNUmakefile.in |
+45
| --- a/GNUmakefile.in | ||
| +++ b/GNUmakefile.in | ||
| @@ -0,0 +1,45 @@ | ||
| 1 | +#!/usr/bin/make | |
| 2 | +# | |
| 3 | +# This is the top-level makefile for Fossil when the build is occurring | |
| 4 | +# on a unix platform. This works out-of-the-box on most unix platforms. | |
| 5 | +# But you are free to vary some of the definitions if desired. | |
| 6 | +# | |
| 7 | +#### The toplevel directory of the source tree. Fossil can be built | |
| 8 | +# in a directory that is separate from the source tree. Just change | |
| 9 | +# the following to point from the build directory to the src/ folder. | |
| 10 | +# | |
| 11 | +SRCDIR = @srcdir@/src | |
| 12 | + | |
| 13 | +#### The directory into which object code files should be written. | |
| 14 | +# | |
| 15 | +# | |
| 16 | +OBJDIR = ./bld | |
| 17 | + | |
| 18 | +#### C Compiler and options for use in building executables that | |
| 19 | +# will run on the platform that is doing the build. This is used | |
| 20 | +# to compile code-generator programs as part of the build process. | |
| 21 | +# See TCC below for the C compiler for building the finished binary. | |
| 22 | +# | |
| 23 | +BCC = @CC_FOR_BUILD@ | |
| 24 | + | |
| 25 | +#### The suffix to add to final executable file. When cross-compiling | |
| 26 | +# to windows, make this ".exe". Otherwise leave it blank. | |
| 27 | +# | |
| 28 | +E = @EXEEXT@ | |
| 29 | + | |
| 30 | +TCC = @CC@ | |
| 31 | + | |
| 32 | +#### Tcl shell for use in running the fossil testsuite. If you do not | |
| 33 | +# care about testing the end result, this can be blank. | |
| 34 | +# | |
| 35 | +TCLSH = tclsh | |
| 36 | + | |
| 37 | +LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ | |
| 38 | +TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H | |
| 39 | +INSTALLDIR = $(DESTDIR)@prefix@/bin | |
| 40 | +USE_SYSTEM_SQLFORM_CHECK_KIND = disable | |
| 41 | + | |
| 42 | +include $(SRCDIR)/main.mk | |
| 43 | + | |
| 44 | +distclean: clean | |
| 45 | + rm -f autoconfi |
| --- a/GNUmakefile.in | |
| +++ b/GNUmakefile.in | |
| @@ -0,0 +1,45 @@ | |
| --- a/GNUmakefile.in | |
| +++ b/GNUmakefile.in | |
| @@ -0,0 +1,45 @@ | |
| 1 | #!/usr/bin/make |
| 2 | # |
| 3 | # This is the top-level makefile for Fossil when the build is occurring |
| 4 | # on a unix platform. This works out-of-the-box on most unix platforms. |
| 5 | # But you are free to vary some of the definitions if desired. |
| 6 | # |
| 7 | #### The toplevel directory of the source tree. Fossil can be built |
| 8 | # in a directory that is separate from the source tree. Just change |
| 9 | # the following to point from the build directory to the src/ folder. |
| 10 | # |
| 11 | SRCDIR = @srcdir@/src |
| 12 | |
| 13 | #### The directory into which object code files should be written. |
| 14 | # |
| 15 | # |
| 16 | OBJDIR = ./bld |
| 17 | |
| 18 | #### C Compiler and options for use in building executables that |
| 19 | # will run on the platform that is doing the build. This is used |
| 20 | # to compile code-generator programs as part of the build process. |
| 21 | # See TCC below for the C compiler for building the finished binary. |
| 22 | # |
| 23 | BCC = @CC_FOR_BUILD@ |
| 24 | |
| 25 | #### The suffix to add to final executable file. When cross-compiling |
| 26 | # to windows, make this ".exe". Otherwise leave it blank. |
| 27 | # |
| 28 | E = @EXEEXT@ |
| 29 | |
| 30 | TCC = @CC@ |
| 31 | |
| 32 | #### Tcl shell for use in running the fossil testsuite. If you do not |
| 33 | # care about testing the end result, this can be blank. |
| 34 | # |
| 35 | TCLSH = tclsh |
| 36 | |
| 37 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 38 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H |
| 39 | INSTALLDIR = $(DESTDIR)@prefix@/bin |
| 40 | USE_SYSTEM_SQLFORM_CHECK_KIND = disable |
| 41 | |
| 42 | include $(SRCDIR)/main.mk |
| 43 | |
| 44 | distclean: clean |
| 45 | rm -f autoconfi |
M
VERSION
+1
-1
| --- VERSION | ||
| +++ VERSION | ||
| @@ -1,1 +1,1 @@ | ||
| 1 | -1.18 | |
| 1 | +1.19 | |
| 2 | 2 | |
| 3 | 3 | ADDED auto.def |
| 4 | 4 | ADDED autosetup/LICENSE |
| 5 | 5 | ADDED autosetup/README.autosetup |
| 6 | 6 | ADDED autosetup/autosetup |
| 7 | 7 | ADDED autosetup/cc-lib.tcl |
| 8 | 8 | ADDED autosetup/cc-shared.tcl |
| 9 | 9 | ADDED autosetup/cc.tcl |
| 10 | 10 | ADDED autosetup/config.guess |
| 11 | 11 | ADDED autosetup/config.sub |
| 12 | 12 | ADDED autosetup/find-tclsh |
| 13 | 13 | ADDED autosetup/jimsh0.c |
| 14 | 14 | ADDED autosetup/local.tcl |
| 15 | 15 | ADDED autosetup/system.tcl |
| 16 | 16 | ADDED autosetup/test-tclsh |
| 17 | 17 | ADDED configure |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 1.18 |
| 2 | |
| 3 | DDED auto.def |
| 4 | DDED autosetup/LICENSE |
| 5 | DDED autosetup/README.autosetup |
| 6 | DDED autosetup/autosetup |
| 7 | DDED autosetup/cc-lib.tcl |
| 8 | DDED autosetup/cc-shared.tcl |
| 9 | DDED autosetup/cc.tcl |
| 10 | DDED autosetup/config.guess |
| 11 | DDED autosetup/config.sub |
| 12 | DDED autosetup/find-tclsh |
| 13 | DDED autosetup/jimsh0.c |
| 14 | DDED autosetup/local.tcl |
| 15 | DDED autosetup/system.tcl |
| 16 | DDED autosetup/test-tclsh |
| 17 | DDED configure |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 1.19 |
| 2 | |
| 3 | DDED auto.def |
| 4 | DDED autosetup/LICENSE |
| 5 | DDED autosetup/README.autosetup |
| 6 | DDED autosetup/autosetup |
| 7 | DDED autosetup/cc-lib.tcl |
| 8 | DDED autosetup/cc-shared.tcl |
| 9 | DDED autosetup/cc.tcl |
| 10 | DDED autosetup/config.guess |
| 11 | DDED autosetup/config.sub |
| 12 | DDED autosetup/find-tclsh |
| 13 | DDED autosetup/jimsh0.c |
| 14 | DDED autosetup/local.tcl |
| 15 | DDED autosetup/system.tcl |
| 16 | DDED autosetup/test-tclsh |
| 17 | DDED configure |
M
auto.def
+2
| --- a/auto.def | ||
| +++ b/auto.def | ||
| @@ -0,0 +1,2 @@ | ||
| 1 | +D markdown=0 => {Build with markdown enginemarkdown]} { | |
| 2 | +MARKDOWMARKDOWipv6=1 =>GNUm |
| --- a/auto.def | |
| +++ b/auto.def | |
| @@ -0,0 +1,2 @@ | |
| --- a/auto.def | |
| +++ b/auto.def | |
| @@ -0,0 +1,2 @@ | |
| 1 | D markdown=0 => {Build with markdown enginemarkdown]} { |
| 2 | MARKDOWMARKDOWipv6=1 =>GNUm |
+35
| --- a/autosetup/LICENSE | ||
| +++ b/autosetup/LICENSE | ||
| @@ -0,0 +1,35 @@ | ||
| 1 | +Unless explicitly stated, all files which form part of autosetup | |
| 2 | +are released under the following license: | |
| 3 | + | |
| 4 | +--------------------------------------------------------------------- | |
| 5 | +autosetup - A build environment "autoconfigurator" | |
| 6 | + | |
| 7 | +Copyright (c) 2010-2011, WorkWare Systems <http://workware.net.au/> | |
| 8 | + | |
| 9 | +Redistribution and use in source and binary forms, with or without | |
| 10 | +modification, are permitted provided that the following conditions | |
| 11 | +are met: | |
| 12 | + | |
| 13 | +1. Redistributions of source code must retain the above copyright | |
| 14 | + notice, this list of conditions and the following disclaimer. | |
| 15 | +2. Redistributions in binary form must reproduce the above | |
| 16 | + copyright notice, this list of conditions and the following | |
| 17 | + disclaimer in the documentation and/or other materials | |
| 18 | + provided with the distribution. | |
| 19 | + | |
| 20 | +THIS SOFTWARE IS PROVIDED BY THE WORKWARE SYSTEMS ``AS IS'' AND ANY | |
| 21 | +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 22 | +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
| 23 | +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WORKWARE | |
| 24 | +SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |
| 25 | +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 26 | +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 27 | +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 28 | +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 29 | +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 30 | +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
| 31 | +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 32 | + | |
| 33 | +The views and conclusions contained in the software and documentation | |
| 34 | +are those of the authors and should not be interpreted as representing | |
| 35 | +official policies, either expressed or implied, of WorkWare Systems. |
| --- a/autosetup/LICENSE | |
| +++ b/autosetup/LICENSE | |
| @@ -0,0 +1,35 @@ | |
| --- a/autosetup/LICENSE | |
| +++ b/autosetup/LICENSE | |
| @@ -0,0 +1,35 @@ | |
| 1 | Unless explicitly stated, all files which form part of autosetup |
| 2 | are released under the following license: |
| 3 | |
| 4 | --------------------------------------------------------------------- |
| 5 | autosetup - A build environment "autoconfigurator" |
| 6 | |
| 7 | Copyright (c) 2010-2011, WorkWare Systems <http://workware.net.au/> |
| 8 | |
| 9 | Redistribution and use in source and binary forms, with or without |
| 10 | modification, are permitted provided that the following conditions |
| 11 | are met: |
| 12 | |
| 13 | 1. Redistributions of source code must retain the above copyright |
| 14 | notice, this list of conditions and the following disclaimer. |
| 15 | 2. Redistributions in binary form must reproduce the above |
| 16 | copyright notice, this list of conditions and the following |
| 17 | disclaimer in the documentation and/or other materials |
| 18 | provided with the distribution. |
| 19 | |
| 20 | THIS SOFTWARE IS PROVIDED BY THE WORKWARE SYSTEMS ``AS IS'' AND ANY |
| 21 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 22 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
| 23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WORKWARE |
| 24 | SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| 25 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 27 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 28 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 29 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 30 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 31 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 32 | |
| 33 | The views and conclusions contained in the software and documentation |
| 34 | are those of the authors and should not be interpreted as representing |
| 35 | official policies, either expressed or implied, of WorkWare Systems. |
| --- a/autosetup/README.autosetup | ||
| +++ b/autosetup/README.autosetup | ||
| @@ -0,0 +1 @@ | ||
| 1 | +This is autosetup v0.6.2. S |
| --- a/autosetup/README.autosetup | |
| +++ b/autosetup/README.autosetup | |
| @@ -0,0 +1 @@ | |
| --- a/autosetup/README.autosetup | |
| +++ b/autosetup/README.autosetup | |
| @@ -0,0 +1 @@ | |
| 1 | This is autosetup v0.6.2. S |
+30
| --- a/autosetup/autosetup | ||
| +++ b/autosetup/autosetup | ||
| @@ -0,0 +1,30 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +4 => "create an initiaefine | |
| 3 | + } else { | |
| 4 | + return $alias | |
| 5 | + }[error-location $msg]use cc cc-sharedupleve`"$dir/find-tclsh" || echo false`eduplevel #0#!/bin/sh | |
| 6 | +${m}.tcl | |
| 7 | +uplevel #0 [list source $source]put2put3 "Looking for $source"![string m 2>/dev/null} { | |
| 8 | + set create_configure 1Use --initset cre#!/bin/sh | |
| 9 | +4 => "creat # Jim uses system() for exec under mingw, so | |
| 10 | + # we need to fetch the output ourselves | |
| 11 | + set tmpfile auto[format %04x [rand 10000]].tmp | |
| 12 | + set rc [catch [list exec {*}$readfile $tmpfile] | |
| 13 | + file delete $tmpfile | |
| 14 | + return -code $rc $result breakn/sh | |
| 15 | +4 => "create an in"create an initial 'c[lrange $argv $i end]`"$dir/find-tclsh" || echo false`autoconf-hsh | |
| 16 | +4 => "create an initial 'confbool init]$source#!/bin/sh | |
| 17 | +parray define | |
| 18 | + } else { | |
| 19 | + return $alias | |
| 20 | + }[error-location $msg]use cc cc-shareduplevel #0#!/bin/sh | |
| 21 | +${m}.tcl | |
| 22 | +uplevel #0 [list source $source]put2put3 m 2>/dev/nullcreate_configure 1Use --initset cre#!/bin/sh | |
| 23 | +4 => "creat # Jim uses system() for exec under mingw, so | |
| 24 | + # we need to fetch the output ourselves | |
| 25 | + set tmpfile auto[format %04x [rand 10000]].tmp | |
| 26 | + set rc [catch [list exec {*}$readfile $tmpfile] | |
| 27 | + file delete $tmpfile | |
| 28 | + return -code $rc $result!/bin/sh | |
| 29 | +4 => "create anbool install]} { | |
| 30 | + if {[catch { |
| --- a/autosetup/autosetup | |
| +++ b/autosetup/autosetup | |
| @@ -0,0 +1,30 @@ | |
| --- a/autosetup/autosetup | |
| +++ b/autosetup/autosetup | |
| @@ -0,0 +1,30 @@ | |
| 1 | #!/bin/sh |
| 2 | 4 => "create an initiaefine |
| 3 | } else { |
| 4 | return $alias |
| 5 | }[error-location $msg]use cc cc-sharedupleve`"$dir/find-tclsh" || echo false`eduplevel #0#!/bin/sh |
| 6 | ${m}.tcl |
| 7 | uplevel #0 [list source $source]put2put3 "Looking for $source"![string m 2>/dev/null} { |
| 8 | set create_configure 1Use --initset cre#!/bin/sh |
| 9 | 4 => "creat # Jim uses system() for exec under mingw, so |
| 10 | # we need to fetch the output ourselves |
| 11 | set tmpfile auto[format %04x [rand 10000]].tmp |
| 12 | set rc [catch [list exec {*}$readfile $tmpfile] |
| 13 | file delete $tmpfile |
| 14 | return -code $rc $result breakn/sh |
| 15 | 4 => "create an in"create an initial 'c[lrange $argv $i end]`"$dir/find-tclsh" || echo false`autoconf-hsh |
| 16 | 4 => "create an initial 'confbool init]$source#!/bin/sh |
| 17 | parray define |
| 18 | } else { |
| 19 | return $alias |
| 20 | }[error-location $msg]use cc cc-shareduplevel #0#!/bin/sh |
| 21 | ${m}.tcl |
| 22 | uplevel #0 [list source $source]put2put3 m 2>/dev/nullcreate_configure 1Use --initset cre#!/bin/sh |
| 23 | 4 => "creat # Jim uses system() for exec under mingw, so |
| 24 | # we need to fetch the output ourselves |
| 25 | set tmpfile auto[format %04x [rand 10000]].tmp |
| 26 | set rc [catch [list exec {*}$readfile $tmpfile] |
| 27 | file delete $tmpfile |
| 28 | return -code $rc $result!/bin/sh |
| 29 | 4 => "create anbool install]} { |
| 30 | if {[catch { |
+63
| --- a/autosetup/cc-lib.tcl | ||
| +++ b/autosetup/cc-lib.tcl | ||
| @@ -0,0 +1,63 @@ | ||
| 1 | +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ | |
| 2 | +# All rights reserved | |
| 3 | + | |
| 4 | +# @synopsis: | |
| 5 | +# | |
| 6 | +# Provides a library of common tests on top ofmodule-options {}of the 'cc' module. | |
| 7 | + | |
| 8 | +use cc | |
| 9 | + | |
| 10 | +# @cc-check-lfsAC_SYS_LARGEFILE macro | |
| 11 | +# | |
| 12 | +# defines 'HAVE_LFS' if L S is available, | |
| 13 | +# and defines '_FILE_OFFSET_BITS=64' if necessary | |
| 14 | +# | |
| 15 | +# Returns 1 if 'LFS' is available or 0 otherwise | |
| 16 | +# | |
| 17 | +proc cc-check-lfs {} { | |
| 18 | + cc-check-includes sys/types.h | |
| 19 | + msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..." | |
| 20 | + set lfs 1 | |
| 21 | + if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} { | |
| 22 | + msg-result no | |
| 23 | + } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} { | |
| 24 | + define _FILE_OFFSET_BITS 64 | |
| 25 | + msg-result yes | |
| 26 | + } else { | |
| 27 | + set lfs 0 | |
| 28 | + msg-result none | |
| 29 | + } | |
| 30 | + define-feature lfs $lfs | |
| 31 | + return $lfs | |
| 32 | +} | |
| 33 | + | |
| 34 | +# @cc-check-endian | |
| 35 | +# | |
| 36 | +# The equivalent of th eAC_C_BIGENDIAN macroth e 'AC_C_BIGENDIAN' macro. | |
| 37 | +# | |
| 38 | +# defines 'HAVE_BIG_ENDIAN' if endian is known to be big, | |
| 39 | +# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. | |
| 40 | +# | |
| 41 | +# Returns 1 if determined, or 0 if not. | |
| 42 | +# | |
| 43 | +proc cc-check-endian {} { | |
| 44 | + cc-check-includes sys/types.h sys/param.h | |
| 45 | + set rc 0 | |
| 46 | + msg-checking "Checking endian..." | |
| 47 | + cc-with {-includes {sys/types.h sys/param.h}} { | |
| 48 | + if {[cctest -code { | |
| 49 | + #if! ! defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER) | |
| 50 | + #error unknown | |
| 51 | + #elif BYTE_ORDER != LITTLE_ENDIAN | |
| 52 | + #error big | |
| 53 | + #endif | |
| 54 | + }]} { | |
| 55 | + define-feature little-endian | |
| 56 | + msg-result "little" | |
| 57 | + set rc 1 | |
| 58 | + } else { | |
| 59 | + msg-result "unknown" | |
| 60 | + } | |
| 61 | + } | |
| 62 | + return $rc | |
| 63 | +} |
| --- a/autosetup/cc-lib.tcl | |
| +++ b/autosetup/cc-lib.tcl | |
| @@ -0,0 +1,63 @@ | |
| --- a/autosetup/cc-lib.tcl | |
| +++ b/autosetup/cc-lib.tcl | |
| @@ -0,0 +1,63 @@ | |
| 1 | # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ |
| 2 | # All rights reserved |
| 3 | |
| 4 | # @synopsis: |
| 5 | # |
| 6 | # Provides a library of common tests on top ofmodule-options {}of the 'cc' module. |
| 7 | |
| 8 | use cc |
| 9 | |
| 10 | # @cc-check-lfsAC_SYS_LARGEFILE macro |
| 11 | # |
| 12 | # defines 'HAVE_LFS' if L S is available, |
| 13 | # and defines '_FILE_OFFSET_BITS=64' if necessary |
| 14 | # |
| 15 | # Returns 1 if 'LFS' is available or 0 otherwise |
| 16 | # |
| 17 | proc cc-check-lfs {} { |
| 18 | cc-check-includes sys/types.h |
| 19 | msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..." |
| 20 | set lfs 1 |
| 21 | if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} { |
| 22 | msg-result no |
| 23 | } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} { |
| 24 | define _FILE_OFFSET_BITS 64 |
| 25 | msg-result yes |
| 26 | } else { |
| 27 | set lfs 0 |
| 28 | msg-result none |
| 29 | } |
| 30 | define-feature lfs $lfs |
| 31 | return $lfs |
| 32 | } |
| 33 | |
| 34 | # @cc-check-endian |
| 35 | # |
| 36 | # The equivalent of th eAC_C_BIGENDIAN macroth e 'AC_C_BIGENDIAN' macro. |
| 37 | # |
| 38 | # defines 'HAVE_BIG_ENDIAN' if endian is known to be big, |
| 39 | # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. |
| 40 | # |
| 41 | # Returns 1 if determined, or 0 if not. |
| 42 | # |
| 43 | proc cc-check-endian {} { |
| 44 | cc-check-includes sys/types.h sys/param.h |
| 45 | set rc 0 |
| 46 | msg-checking "Checking endian..." |
| 47 | cc-with {-includes {sys/types.h sys/param.h}} { |
| 48 | if {[cctest -code { |
| 49 | #if! ! defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER) |
| 50 | #error unknown |
| 51 | #elif BYTE_ORDER != LITTLE_ENDIAN |
| 52 | #error big |
| 53 | #endif |
| 54 | }]} { |
| 55 | define-feature little-endian |
| 56 | msg-result "little" |
| 57 | set rc 1 |
| 58 | } else { |
| 59 | msg-result "unknown" |
| 60 | } |
| 61 | } |
| 62 | return $rc |
| 63 | } |
+30
| --- a/autosetup/cc-shared.tcl | ||
| +++ b/autosetup/cc-shared.tcl | ||
| @@ -0,0 +1,30 @@ | ||
| 1 | +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 2 | +# All rights reserved | |
| 3 | + | |
| 4 | +# @synopsis: | |
| 5 | +# | |
| 6 | +# The 'cc-shared' module provides support for shared libraries and shared objects. | |
| 7 | +# It defines the following variables: | |
| 8 | +# | |
| 9 | +## SH_CFLAGS Flags to use compiling sources destined for a shared library | |
| 10 | +## SH_LDFLAGS Flags to use linking t the soname when cread libs - %s = version | |
| 11 | +## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object | |
| 12 | +## ll symbols table, %s = path | |
| 13 | +## SH_LINKFLAGS Flags to use linking an executable which will load shared objects | |
| 14 | +## LD_LIBRARY_PATH Environment variable which specifie | |
| 15 | +module-options {} | |
| 16 | + | |
| 17 | +foreach i {SH_LINKFLAGS SH_CFLAGS SH_LDFLAGS SHOBJ_CFLAGS SHOBJ_LLD_LIBRARY_PATH define SHOBJ_LDFLAGS_R -bobject | |
| 18 | +## SHOBJ_LDFLAGS Flags to are System# Copyright ( Flags to usDYLD_LIBRARY_PATH | |
| 19 | + } | |
| 20 | + *-*-ming* {sharedOBJ_LDFLAGSshared} | |
| 21 | + *-*-solaris* { | |
| 22 | +# Copyright (c) 20mwed | |
| 23 | +## SHOBJ_LD-Kpic Flags to us-Kpic"-G" | |
| 24 | +define LD_LIBthe toolch-strip-unneeded | |
| 25 | + | |
| 26 | +# Note: Thiain | |
| 27 | +# http://sourceforge sparc* { | |
| 28 | +AGS SHOBJ_LDFLAGS_rdynamicference for identify-fPICshared Flags to us-fPIC} | |
| 29 | + * { | |
| 30 | + # Generic Unix settingsstems http://www.workwa# Copyrigference for identifying PICmicference for idCtify-fPfPICicference for identify-f |
| --- a/autosetup/cc-shared.tcl | |
| +++ b/autosetup/cc-shared.tcl | |
| @@ -0,0 +1,30 @@ | |
| --- a/autosetup/cc-shared.tcl | |
| +++ b/autosetup/cc-shared.tcl | |
| @@ -0,0 +1,30 @@ | |
| 1 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 2 | # All rights reserved |
| 3 | |
| 4 | # @synopsis: |
| 5 | # |
| 6 | # The 'cc-shared' module provides support for shared libraries and shared objects. |
| 7 | # It defines the following variables: |
| 8 | # |
| 9 | ## SH_CFLAGS Flags to use compiling sources destined for a shared library |
| 10 | ## SH_LDFLAGS Flags to use linking t the soname when cread libs - %s = version |
| 11 | ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object |
| 12 | ## ll symbols table, %s = path |
| 13 | ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects |
| 14 | ## LD_LIBRARY_PATH Environment variable which specifie |
| 15 | module-options {} |
| 16 | |
| 17 | foreach i {SH_LINKFLAGS SH_CFLAGS SH_LDFLAGS SHOBJ_CFLAGS SHOBJ_LLD_LIBRARY_PATH define SHOBJ_LDFLAGS_R -bobject |
| 18 | ## SHOBJ_LDFLAGS Flags to are System# Copyright ( Flags to usDYLD_LIBRARY_PATH |
| 19 | } |
| 20 | *-*-ming* {sharedOBJ_LDFLAGSshared} |
| 21 | *-*-solaris* { |
| 22 | # Copyright (c) 20mwed |
| 23 | ## SHOBJ_LD-Kpic Flags to us-Kpic"-G" |
| 24 | define LD_LIBthe toolch-strip-unneeded |
| 25 | |
| 26 | # Note: Thiain |
| 27 | # http://sourceforge sparc* { |
| 28 | AGS SHOBJ_LDFLAGS_rdynamicference for identify-fPICshared Flags to us-fPIC} |
| 29 | * { |
| 30 | # Generic Unix settingsstems http://www.workwa# Copyrigference for identifying PICmicference for idCtify-fPfPICicference for identify-f |
+314
| --- a/autosetup/cc.tcl | ||
| +++ b/autosetup/cc.tcl | ||
| @@ -0,0 +1,314 @@ | ||
| 1 | +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 2 | +# All rights reserved | |
| 3 | + | |
| 4 | +# @synopsis: | |
| 5 | +# | |
| 6 | +# The 'cc' module supports checking various 'features' of the C or C++ | |
| 7 | +# compiler/linker environment. Common commands are , | |
| 8 | +# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: | |
| 9 | +# | |
| 10 | +## CC - C compiler | |
| 11 | +## CXX - C++ compiler | |
| 12 | +## CPP - C preprocessor | |
| 13 | +##CACHE - Set to "none" to disable automatic use of ccache | |
| 14 | +## Ciler flags | |
| 15 | +## CXXFLAGS - Additional C++ compiler flags | |
| 16 | +## LDFLAGS - Additional compiler flags during linking | |
| 17 | +## LINKFLAGS - ?How is this diffes to use (for all tests) | |
| 18 | +## CROSS - Tool prefix for cross compilation | |
| 19 | +# | |
| 20 | +# The following variables are defined from the corresponding | |
| 21 | +# environment variables if set. | |
| 22 | +# | |
| 23 | +## CC_FOR_BUILD | |
| 24 | +## LD | |
| 25 | + | |
| 26 | +use systPPFLAGS | |
| 27 | +## LINKFLAGSmodule-options {} | |
| 28 | + | |
| 29 | +# Checks for the existence of the giveNote that the return code is not meaningful | |
| 30 | +proc cc-check-something {name code} { | |
| 31 | + uplevel 1 $codee given type/strunction {function} { | |
| 32 | + cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" | |
| 33 | +} | |
| 34 | + | |
| 35 | +# Checks for the existence of the given type by compiling | |
| 36 | +proc cctest_type {type} { | |
| 37 | + cctest -code "$type _x;" | |
| 38 | +} | |
| 39 | + | |
| 40 | +# Checks for the existence of the given type/structure member. | |
| 41 | +# e.g. "struct stat.st_mtime" | |
| 42 | +proc cctest_member {struct_member} { | |
| 43 | + # split at the first dot | |
| 44 | + regexp {^([^.]+)[.](.*)$} $lassign me;\n#endif" | |
| 45 | +} | |
| 46 | + | |
| 47 | +# @cc-ch | |
| 48 | +# e.g. "struct stypeses a variable with the 4 8 1 2 16 32} { | |
| 49 | + if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { | |
| 50 | + set size $i | |
| 51 | + break | |
| 52 | + } | |
| 53 | + } | |
| 54 | + msg-result $size | |
| 55 | + set define [feature-define-name $type SIZEOF_] | |
| 56 | + define $define $size | |
| 57 | + } | |
| 58 | + # Return the last result | |
| 59 | + get-define $define | |
| 60 | +} | |
| 61 | + | |
| 62 | +# Checks for each feature in $list by using the given script. | |
| 63 | +# | |
| 64 | +# When the script is evaluated, $each is set to the feature | |
| 65 | +# being checked, and $extra is set to any additional cctest args. | |
| 66 | +# | |
| 67 | +# Returns 1 if all features were found, or 0 otherwise. | |
| 68 | +proc cc-check-some-feature {list script} { | |
| 69 | + set ret 1 | |
| 70 | + foreach each $list { | |
| 71 | + if {![check-feature $each $script]} { | |
| 72 | + set ret 0 | |
| 73 | + } | |
| 74 | + } | |
| 75 | + return $ret | |
| 76 | +} | |
| 77 | + | |
| 78 | +# @cc-check-includes includes ... | |
| 79 | +# | |
| 80 | +# Checks that the given include files can be used. | |
| 81 | +proc cc-check-includes {args} { | |
| 82 | + c | |
| 83 | +procproc cctest_define {cc-check-some-xp {^([^.]+)[.](.*)$} $struct_member -> struct member | |
| 84 | + cctest -code "static $struct _s; return sizeof(_s.$member);" | |
| 85 | +} | |
| 86 | + | |
| 87 | +# Checks for the existence of the given define by compiling | |
| 88 | +# | |
| 89 | +proc cctest_define {name} { | |
| 90 | + cctest -code "#ifndef $name\n#error not defined\n#endif" | |
| 91 | +} | |
| 92 | + | |
| 93 | +# Checks forcks that the given include files can be used. | |
| 94 | +proc cc-check-includes {args} { | |
| 95 | + cc-check-some-feature $args { | |
| 96 | + set with {} | |
| 97 | + if {[dict exists $::autosetup(cc-include-deps) $each]} { | |
| 98 | + set deps! cc-check-include$exeecks tha]} { | |
| 99 | + cc-with [list -includes $w } | |
| 100 | + define $TOOL $exeed if set: | |
| 101 | +# | |
| 102 | +## CC | |
| 103 | +# @synopsis: | |
| 104 | +# | |
| 105 | +# The 'cc' module supports checking various 'features' of the C or C++ | |
| 106 | +# compiler/linker environment. Common commands are , | |
| 107 | +# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: | |
| 108 | +# | |
| 109 | +## CC - C compiler | |
| 110 | +## CXX - C++ compiler | |
| 111 | +## CPP - C preprocessor | |
| 112 | +##CACHE - Set to "none" to disable automatic use of ccache | |
| 113 | +## Ciler flags | |
| 114 | +## CXXFLAGS - Additional C++ compiler flags | |
| 115 | +## LDFLAGS - Additional compiler flags during linking | |
| 116 | +## LINKFLAGS - ?How is this diffes to use (for all tests) | |
| 117 | +## CROSS - Tool prefix for cross compilation | |
| 118 | +# | |
| 119 | +# The following variables are defined from the corresponding | |
| 120 | +# environment variables if set. | |
| 121 | +# | |
| 122 | +## CC_FOR_BUILD | |
| 123 | +## LD | |
| 124 | + | |
| 125 | +use systPPFLAGS | |
| 126 | +## LINKFLAGSmodule-options {} | |
| 127 | + | |
| 128 | +# Checks for the existence of the giveNote that the return code is not meaningful | |
| 129 | +proc cc-check-something {name code} { | |
| 130 | + uplevel 1 $codee given type/strunction {function} { | |
| 131 | + cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" | |
| 132 | +} | |
| 133 | + | |
| 134 | +# Checks for the existence of the given type by compiling | |
| 135 | +proc cctest_type {type} { | |
| 136 | + cctest -code "$type _x;" | |
| 137 | +} | |
| 138 | + | |
| 139 | +# Checks for the existence of the given type/structure member. | |
| 140 | +# e.g. "struct stat.st_mtime" | |
| 141 | +proc cctest_member {struct_member} { | |
| 142 | + # split at the first dot | |
| 143 | + regexp {^([^.]+)[.](.*)$} $lassign [split $struct_member .]rn sizeof(_s.$member);" | |
| 144 | +} | |
| 145 | + | |
| 146 | +# Checks for the existence of the given define by compiling | |
| 147 | +# | |
| 148 | +proc cctest_define {name} { | |
| 149 | + cctest -code "#ifndef $name\n#error not defined\n#endif" | |
| 150 | +} | |
| 151 | + | |
| 152 | +# Checks for the existence of the given name either as | |
| 153 | +# a macro (#define) or an rvalue (such as an enum) | |
| 154 | +# | |
| 155 | +proc cctest_decl {name} { | |
| 156 | + cctest -code "#ifndef $name\n(void)$name;\n#endif" | |
| 157 | +} | |
| 158 | + | |
| 159 | +# @cc-check-sizeof type ... | |
| 160 | +# | |
| 161 | +# Checks the size of the given types (between 1 and 32, inclusive). | |
| 162 | +# Defines a variable with the size determined, or 'unknown'"unknown"ng', defines 'SIZEOF_LSIZEOF_LONG_LONGe. | |
| 163 | +# | |
| 164 | +proc cc-check-sizeof {args} { | |
| 165 | + foreach type $args { | |
| 166 | + msg-checking "Checking for sizeof $type..." | |
| 167 | + set size unknown | |
| 168 | + # Try the most common sizes first | |
| 169 | + foreach i {4 8 1 2 16 32} { | |
| 170 | + if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { | |
| 171 | + set size $i | |
| 172 | + break | |
| 173 | + } | |
| 174 | + } | |
| 175 | + msg-result $size | |
| 176 | + set define [feature-define-name $type SIZEOF_] | |
| 177 | + define $define $size | |
| 178 | + } | |
| 179 | + # Return the last result | |
| 180 | + get-define $define | |
| 181 | +} | |
| 182 | + | |
| 183 | +# Checks for each feature in $list by using the given script. | |
| 184 | +# | |
| 185 | +# When the script is evaluated, $each is set to the feature | |
| 186 | +# being checked, and $extra is set to any additional cctest args. | |
| 187 | +# | |
| 188 | +# Returns 1 if all features were found, or 0 otherwise. | |
| 189 | +proc cc-check-some-feature {list script} { | |
| 190 | + set ret 1 | |
| 191 | + foreach each $list { | |
| 192 | + if {![check-feature $each $script]} { | |
| 193 | + set ret 0 | |
| 194 | + } | |
| 195 | + } | |
| 196 | + return $ret | |
| 197 | +} | |
| 198 | + | |
| 199 | +# @cc-check-includes includes ... | |
| 200 | +# | |
| 201 | +# Checks that the given include files can be used. | |
| 202 | +proc cc-check-includes {args} { | |
| 203 | + c | |
| 204 | +procproc cctest_define {cc-check-some-xp {^([^.]+)[.](.*)$} $struct_member -> struct member | |
| 205 | + cctest -code "static $struct _s; return sizeof(_s.$member);" | |
| 206 | +} | |
| 207 | + | |
| 208 | +# Checks for the existence of the given define by compiling | |
| 209 | +# | |
| 210 | +proc cctest_define {name} { | |
| 211 | + cctest -code "#ifndef $name\n#error not defined\n#endif" | |
| 212 | +} | |
| 213 | + | |
| 214 | +# Checks for the existence of the given name either as | |
| 215 | +# a macro (#define) or an rvalue (such as an enum) | |
| 216 | +# | |
| 217 | +proc cctest_decl {name} { | |
| 218 | + cctest -code "#ifndef $name\n(void)$name;\n#endif" | |
| 219 | +} | |
| 220 | + given types (bet#includeddetermined, or 'unknown' otherwise. | |
| 221 | +# e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'. | |
| 222 | +# Returns the size of the last type. | |
| 223 | +# | |
| 224 | +proc cc-check-sizeof {args} { | |
| 225 | + foreach type $adfirst dot | |
| 226 | + regexp {^([^.]+)[.](.*)$} $struct_member -> struct member | |
| 227 | + cctest -code "static $struct _s; return sizeof(_s.$member);" | |
| 228 | +} | |
| 229 | + | |
| 230 | +# Checks for the existence of the given define by compiling | |
| 231 | +# | |
| 232 | +proc cctest_define FLAGS - ?How is this di# @synopsis: | |
| 233 | +# | |
| 234 | +# The 'cc' module supports checking various 'features' of the C or C++ | |
| 235 | +# compiler/linker environment. Common commands are , | |
| 236 | +# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: | |
| 237 | +# | |
| 238 | +## CC - C compiler | |
| 239 | +## CXX - C++ compiler | |
| 240 | +## CPP - C preprocessor | |
| 241 | +##CACHE - Set to "none" to disfor a declsable automatic use of ccache | |
| 242 | +## Ciler flags | |
| 243 | +## C# Copyright (c) 2010 Work foreach type $args { | |
| 244 | + msg-checking "Checking for sizeof $type..." | |
| 245 | + set size unknown | |
| 246 | + # Try the most common sizes first | |
| 247 | + foreach i {4 8 1 2 16 32} { | |
| 248 | + if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { | |
| 249 | + set size $i | |
| 250 | + break | |
| 251 | + } | |
| 252 | + } | |
| 253 | + msg-result $size | |
| 254 | + set define [feature-define-name $type SIZEOF_] | |
| 255 | + define $define $size | |
| 256 | + } | |
| 257 | + # Return the last result | |
| 258 | + get-define $define | |
| 259 | +} | |
| 260 | + | |
| 261 | +# Checks for each feature in $list by using the given script. | |
| 262 | +# | |
| 263 | +# When the script is evaluated, $each is set to the feature | |
| 264 | +# being checked, and $extra is set to any additional cctest args. | |
| 265 | +# | |
| 266 | +# Returns 1 if all features were found, or 0 otherwise. | |
| 267 | +proc cc-check-some-feature {list script} { | |
| 268 | + set ret 1ch $script]} { | |
| 269 | + set ret 0 | |
| 270 | + } | |
| 271 | + } | |
| 272 | + return $ret | |
| 273 | +} | |
| 274 | + | |
| 275 | +# @cc-check-includes includes ... | |
| 276 | +# | |
| 277 | +# Checks that the given include files can be used. | |
| 278 | +proc cc-check-includes {args} { | |
| 279 | + cc-check-some-feature $args { | |
| 280 | + set with {} | |
| 281 | + if {[dict exists $::autosetup(cc-include-deps) $each]} { | |
| 282 | + set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] | |
| 283 | + msg-quiet cc-check-includes {*}$deps | |
| 284 | + foreach i $deps { | |
| 285 | + if {[have-feature $i]} { | |
| 286 | + lappend with $i | |
| 287 | +ure $each $scriptargs { | |
| 288 | + set new($name) $value | |
| 289 | + } $i]} { | |
| 290 | + lappend$newme\n(void)$name;\n#th]} { | |
| 291 | + cc-with [list -includes $with] { | |
| 292 | + cctest -includes $each | |
| 293 | + } | |
| 294 | + } else { | |
| 295 | + cctest -includes $each | |
| 296 | + } | |
| 297 | + } | |
| 298 | +} | |
| 299 | + | |
| 300 | +# @cc-include-needs include required ... | |
| 301 | +# | |
| 302 | +# Ensures that when checking for '$include', a check is first | |
| 303 | +# made for eachtk is first | |
| 304 | +# made for each '$required' file, and if found, it is included with '#include'. | |
| 305 | +proc cc-include-needs {file args} { | |
| 306 | + foreach depfile $args { | |
| 307 | + dict set ::autosetup(cc-include-deps) $file $depfile 1 | |
| 308 | + } | |
| 309 | +} | |
| 310 | + | |
| 311 | +# C *-*-darwin* { | |
| 312 | + # Don't-gstabs | |
| 313 | + } | |
| 314 | + }$value$valuecc-check-tools ld.o |
| --- a/autosetup/cc.tcl | |
| +++ b/autosetup/cc.tcl | |
| @@ -0,0 +1,314 @@ | |
| --- a/autosetup/cc.tcl | |
| +++ b/autosetup/cc.tcl | |
| @@ -0,0 +1,314 @@ | |
| 1 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 2 | # All rights reserved |
| 3 | |
| 4 | # @synopsis: |
| 5 | # |
| 6 | # The 'cc' module supports checking various 'features' of the C or C++ |
| 7 | # compiler/linker environment. Common commands are , |
| 8 | # cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: |
| 9 | # |
| 10 | ## CC - C compiler |
| 11 | ## CXX - C++ compiler |
| 12 | ## CPP - C preprocessor |
| 13 | ##CACHE - Set to "none" to disable automatic use of ccache |
| 14 | ## Ciler flags |
| 15 | ## CXXFLAGS - Additional C++ compiler flags |
| 16 | ## LDFLAGS - Additional compiler flags during linking |
| 17 | ## LINKFLAGS - ?How is this diffes to use (for all tests) |
| 18 | ## CROSS - Tool prefix for cross compilation |
| 19 | # |
| 20 | # The following variables are defined from the corresponding |
| 21 | # environment variables if set. |
| 22 | # |
| 23 | ## CC_FOR_BUILD |
| 24 | ## LD |
| 25 | |
| 26 | use systPPFLAGS |
| 27 | ## LINKFLAGSmodule-options {} |
| 28 | |
| 29 | # Checks for the existence of the giveNote that the return code is not meaningful |
| 30 | proc cc-check-something {name code} { |
| 31 | uplevel 1 $codee given type/strunction {function} { |
| 32 | cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" |
| 33 | } |
| 34 | |
| 35 | # Checks for the existence of the given type by compiling |
| 36 | proc cctest_type {type} { |
| 37 | cctest -code "$type _x;" |
| 38 | } |
| 39 | |
| 40 | # Checks for the existence of the given type/structure member. |
| 41 | # e.g. "struct stat.st_mtime" |
| 42 | proc cctest_member {struct_member} { |
| 43 | # split at the first dot |
| 44 | regexp {^([^.]+)[.](.*)$} $lassign me;\n#endif" |
| 45 | } |
| 46 | |
| 47 | # @cc-ch |
| 48 | # e.g. "struct stypeses a variable with the 4 8 1 2 16 32} { |
| 49 | if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { |
| 50 | set size $i |
| 51 | break |
| 52 | } |
| 53 | } |
| 54 | msg-result $size |
| 55 | set define [feature-define-name $type SIZEOF_] |
| 56 | define $define $size |
| 57 | } |
| 58 | # Return the last result |
| 59 | get-define $define |
| 60 | } |
| 61 | |
| 62 | # Checks for each feature in $list by using the given script. |
| 63 | # |
| 64 | # When the script is evaluated, $each is set to the feature |
| 65 | # being checked, and $extra is set to any additional cctest args. |
| 66 | # |
| 67 | # Returns 1 if all features were found, or 0 otherwise. |
| 68 | proc cc-check-some-feature {list script} { |
| 69 | set ret 1 |
| 70 | foreach each $list { |
| 71 | if {![check-feature $each $script]} { |
| 72 | set ret 0 |
| 73 | } |
| 74 | } |
| 75 | return $ret |
| 76 | } |
| 77 | |
| 78 | # @cc-check-includes includes ... |
| 79 | # |
| 80 | # Checks that the given include files can be used. |
| 81 | proc cc-check-includes {args} { |
| 82 | c |
| 83 | procproc cctest_define {cc-check-some-xp {^([^.]+)[.](.*)$} $struct_member -> struct member |
| 84 | cctest -code "static $struct _s; return sizeof(_s.$member);" |
| 85 | } |
| 86 | |
| 87 | # Checks for the existence of the given define by compiling |
| 88 | # |
| 89 | proc cctest_define {name} { |
| 90 | cctest -code "#ifndef $name\n#error not defined\n#endif" |
| 91 | } |
| 92 | |
| 93 | # Checks forcks that the given include files can be used. |
| 94 | proc cc-check-includes {args} { |
| 95 | cc-check-some-feature $args { |
| 96 | set with {} |
| 97 | if {[dict exists $::autosetup(cc-include-deps) $each]} { |
| 98 | set deps! cc-check-include$exeecks tha]} { |
| 99 | cc-with [list -includes $w } |
| 100 | define $TOOL $exeed if set: |
| 101 | # |
| 102 | ## CC |
| 103 | # @synopsis: |
| 104 | # |
| 105 | # The 'cc' module supports checking various 'features' of the C or C++ |
| 106 | # compiler/linker environment. Common commands are , |
| 107 | # cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: |
| 108 | # |
| 109 | ## CC - C compiler |
| 110 | ## CXX - C++ compiler |
| 111 | ## CPP - C preprocessor |
| 112 | ##CACHE - Set to "none" to disable automatic use of ccache |
| 113 | ## Ciler flags |
| 114 | ## CXXFLAGS - Additional C++ compiler flags |
| 115 | ## LDFLAGS - Additional compiler flags during linking |
| 116 | ## LINKFLAGS - ?How is this diffes to use (for all tests) |
| 117 | ## CROSS - Tool prefix for cross compilation |
| 118 | # |
| 119 | # The following variables are defined from the corresponding |
| 120 | # environment variables if set. |
| 121 | # |
| 122 | ## CC_FOR_BUILD |
| 123 | ## LD |
| 124 | |
| 125 | use systPPFLAGS |
| 126 | ## LINKFLAGSmodule-options {} |
| 127 | |
| 128 | # Checks for the existence of the giveNote that the return code is not meaningful |
| 129 | proc cc-check-something {name code} { |
| 130 | uplevel 1 $codee given type/strunction {function} { |
| 131 | cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" |
| 132 | } |
| 133 | |
| 134 | # Checks for the existence of the given type by compiling |
| 135 | proc cctest_type {type} { |
| 136 | cctest -code "$type _x;" |
| 137 | } |
| 138 | |
| 139 | # Checks for the existence of the given type/structure member. |
| 140 | # e.g. "struct stat.st_mtime" |
| 141 | proc cctest_member {struct_member} { |
| 142 | # split at the first dot |
| 143 | regexp {^([^.]+)[.](.*)$} $lassign [split $struct_member .]rn sizeof(_s.$member);" |
| 144 | } |
| 145 | |
| 146 | # Checks for the existence of the given define by compiling |
| 147 | # |
| 148 | proc cctest_define {name} { |
| 149 | cctest -code "#ifndef $name\n#error not defined\n#endif" |
| 150 | } |
| 151 | |
| 152 | # Checks for the existence of the given name either as |
| 153 | # a macro (#define) or an rvalue (such as an enum) |
| 154 | # |
| 155 | proc cctest_decl {name} { |
| 156 | cctest -code "#ifndef $name\n(void)$name;\n#endif" |
| 157 | } |
| 158 | |
| 159 | # @cc-check-sizeof type ... |
| 160 | # |
| 161 | # Checks the size of the given types (between 1 and 32, inclusive). |
| 162 | # Defines a variable with the size determined, or 'unknown'"unknown"ng', defines 'SIZEOF_LSIZEOF_LONG_LONGe. |
| 163 | # |
| 164 | proc cc-check-sizeof {args} { |
| 165 | foreach type $args { |
| 166 | msg-checking "Checking for sizeof $type..." |
| 167 | set size unknown |
| 168 | # Try the most common sizes first |
| 169 | foreach i {4 8 1 2 16 32} { |
| 170 | if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { |
| 171 | set size $i |
| 172 | break |
| 173 | } |
| 174 | } |
| 175 | msg-result $size |
| 176 | set define [feature-define-name $type SIZEOF_] |
| 177 | define $define $size |
| 178 | } |
| 179 | # Return the last result |
| 180 | get-define $define |
| 181 | } |
| 182 | |
| 183 | # Checks for each feature in $list by using the given script. |
| 184 | # |
| 185 | # When the script is evaluated, $each is set to the feature |
| 186 | # being checked, and $extra is set to any additional cctest args. |
| 187 | # |
| 188 | # Returns 1 if all features were found, or 0 otherwise. |
| 189 | proc cc-check-some-feature {list script} { |
| 190 | set ret 1 |
| 191 | foreach each $list { |
| 192 | if {![check-feature $each $script]} { |
| 193 | set ret 0 |
| 194 | } |
| 195 | } |
| 196 | return $ret |
| 197 | } |
| 198 | |
| 199 | # @cc-check-includes includes ... |
| 200 | # |
| 201 | # Checks that the given include files can be used. |
| 202 | proc cc-check-includes {args} { |
| 203 | c |
| 204 | procproc cctest_define {cc-check-some-xp {^([^.]+)[.](.*)$} $struct_member -> struct member |
| 205 | cctest -code "static $struct _s; return sizeof(_s.$member);" |
| 206 | } |
| 207 | |
| 208 | # Checks for the existence of the given define by compiling |
| 209 | # |
| 210 | proc cctest_define {name} { |
| 211 | cctest -code "#ifndef $name\n#error not defined\n#endif" |
| 212 | } |
| 213 | |
| 214 | # Checks for the existence of the given name either as |
| 215 | # a macro (#define) or an rvalue (such as an enum) |
| 216 | # |
| 217 | proc cctest_decl {name} { |
| 218 | cctest -code "#ifndef $name\n(void)$name;\n#endif" |
| 219 | } |
| 220 | given types (bet#includeddetermined, or 'unknown' otherwise. |
| 221 | # e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'. |
| 222 | # Returns the size of the last type. |
| 223 | # |
| 224 | proc cc-check-sizeof {args} { |
| 225 | foreach type $adfirst dot |
| 226 | regexp {^([^.]+)[.](.*)$} $struct_member -> struct member |
| 227 | cctest -code "static $struct _s; return sizeof(_s.$member);" |
| 228 | } |
| 229 | |
| 230 | # Checks for the existence of the given define by compiling |
| 231 | # |
| 232 | proc cctest_define FLAGS - ?How is this di# @synopsis: |
| 233 | # |
| 234 | # The 'cc' module supports checking various 'features' of the C or C++ |
| 235 | # compiler/linker environment. Common commands are , |
| 236 | # cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-templatement variables are used if set: |
| 237 | # |
| 238 | ## CC - C compiler |
| 239 | ## CXX - C++ compiler |
| 240 | ## CPP - C preprocessor |
| 241 | ##CACHE - Set to "none" to disfor a declsable automatic use of ccache |
| 242 | ## Ciler flags |
| 243 | ## C# Copyright (c) 2010 Work foreach type $args { |
| 244 | msg-checking "Checking for sizeof $type..." |
| 245 | set size unknown |
| 246 | # Try the most common sizes first |
| 247 | foreach i {4 8 1 2 16 32} { |
| 248 | if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { |
| 249 | set size $i |
| 250 | break |
| 251 | } |
| 252 | } |
| 253 | msg-result $size |
| 254 | set define [feature-define-name $type SIZEOF_] |
| 255 | define $define $size |
| 256 | } |
| 257 | # Return the last result |
| 258 | get-define $define |
| 259 | } |
| 260 | |
| 261 | # Checks for each feature in $list by using the given script. |
| 262 | # |
| 263 | # When the script is evaluated, $each is set to the feature |
| 264 | # being checked, and $extra is set to any additional cctest args. |
| 265 | # |
| 266 | # Returns 1 if all features were found, or 0 otherwise. |
| 267 | proc cc-check-some-feature {list script} { |
| 268 | set ret 1ch $script]} { |
| 269 | set ret 0 |
| 270 | } |
| 271 | } |
| 272 | return $ret |
| 273 | } |
| 274 | |
| 275 | # @cc-check-includes includes ... |
| 276 | # |
| 277 | # Checks that the given include files can be used. |
| 278 | proc cc-check-includes {args} { |
| 279 | cc-check-some-feature $args { |
| 280 | set with {} |
| 281 | if {[dict exists $::autosetup(cc-include-deps) $each]} { |
| 282 | set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] |
| 283 | msg-quiet cc-check-includes {*}$deps |
| 284 | foreach i $deps { |
| 285 | if {[have-feature $i]} { |
| 286 | lappend with $i |
| 287 | ure $each $scriptargs { |
| 288 | set new($name) $value |
| 289 | } $i]} { |
| 290 | lappend$newme\n(void)$name;\n#th]} { |
| 291 | cc-with [list -includes $with] { |
| 292 | cctest -includes $each |
| 293 | } |
| 294 | } else { |
| 295 | cctest -includes $each |
| 296 | } |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | # @cc-include-needs include required ... |
| 301 | # |
| 302 | # Ensures that when checking for '$include', a check is first |
| 303 | # made for eachtk is first |
| 304 | # made for each '$required' file, and if found, it is included with '#include'. |
| 305 | proc cc-include-needs {file args} { |
| 306 | foreach depfile $args { |
| 307 | dict set ::autosetup(cc-include-deps) $file $depfile 1 |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | # C *-*-darwin* { |
| 312 | # Don't-gstabs |
| 313 | } |
| 314 | }$value$valuecc-check-tools ld.o |
+307
| --- a/autosetup/config.guess | ||
| +++ b/autosetup/config.guess | ||
| @@ -0,0 +1,307 @@ | ||
| 1 | +03-23 the terms of the GNU General Public License as published by | |
| 2 | +# t(C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
| 3 | +# 2000, 2001, 2002, 2003, 2004, 2005, 2006,oftware Foundation, 0-09-24r | |
| 4 | +# (at your option) any later version. | |
| 5 | +# | |
| 6 | +# This program is distributed in the hope that it will be useful, but | |
| 7 | +# WITHOUT ANY WARRANTY; without even the implied w2 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 8 | +# General Public License for more details. | |
| 9 | +# | |
| 10 | +# You should have received a copy of the GNU General Public License | |
| 11 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 12 | +# | |
| 13 | +# As a special exceptionto the GNU General Public License, if you | |
| 14 | +# distribute this file as part of a program that contains a | |
| 15 | +# configuration script generated by Autoconwrite to the Free Software | |
| 16 | +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Bmay include it under | |
| 17 | +# the same distribution terms that you use for the rest of that | |
| 18 | +# program. This Exception is an additional permission under section 7 | |
| 19 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 20 | +# | |
| 21 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 22 | +# | |
| 23 | +# You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 24 | + | |
| 25 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 26 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh | |
| 27 | +# Attempt to guess a canonical system name. | |
| 28 | +# Copyright 1992-2014 Free Software Found4-11-04it and/or modify it | |
| 29 | +# under the terms of the GNU General Public License as published by | |
| 30 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 31 | +# (at your option) any later version. | |
| 32 | +# | |
| 33 | +# This program is distributed in the hope that it will be useful, but | |
| 34 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 35 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 36 | +# General Public License for more details. | |
| 37 | +# | |
| 38 | +# You should have received a copy of the GNU General Public License | |
| 39 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 40 | +# | |
| 41 | +# As a special exceptionto the GNU General Public License, if you | |
| 42 | +# distribute this file as part of a program that contains a | |
| 43 | +# configuration script generated by Autoconf, you may include it under | |
| 44 | +# the same distribution terms that you use for the rest of that | |
| 45 | +# program. This Exception is an additional permission under section 7 | |
| 46 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 47 | +# | |
| 48 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 49 | +# | |
| 50 | +# You can get the latest version of this script from: | |
| 51 | +# https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 52 | + | |
| 53 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 54 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl | |
| 55 | +# Attempt to guess a canoniAttempt to g! /bin/sh | |
| 56 | +# Attemp#*) machine=${! /bin/sh | |
| 57 | +# Attemp#! /bin/sh | |
| 58 | +# Attempt to guess a canonical system name. | |
| 59 | +# Copyright 1992-2018canonical system name. | |
| 60 | +# Copyrig! /bin/sh | |
| 61 | +# Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh | |
| 62 | +# Attemp#! /bin/sh | |
| 63 | +# Attempt to guess a ${! /bin/sh | |
| 64 | +# Attemp#! /bin/sh | |
| 65 | +# Attempt to guess a cekkoBSD:*:*) | |
| 66 | + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) | |
| 67 | + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh | |
| 68 | +# Attempt to guess a canonical system name. | |
| 69 | +# Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. | |
| 70 | +# Copyright 1992-2018 Free Software Foundation, Inc. | |
| 71 | + | |
| 72 | +timestamp='2018-03-08it and/or modify it | |
| 73 | +# under the terms of the GNU General Public License as published by | |
| 74 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 75 | +# (at your o program. | |
| 76 | + | |
| 77 | + | |
| 78 | +# neral Public License | |
| 79 | +# along with he GNU General Public03-23 the terms of the and include a ChangeLog | |
| 80 | +# entrhe GNU General Public License as published by | |
| 81 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 82 | +# (at your option) any later version. | |
| 83 | +# | |
| 84 | +# This program is distributed in the hope that it will be useful, but | |
| 85 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 86 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 87 | +# General Public License for more details. | |
| 88 | +# | |
| 89 | +# You should have received a copy of the GNU General Public License | |
| 90 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 91 | +# | |
| 92 | +# As a special exceptionto the GNU General Public License, if you | |
| 93 | +# distribute this file as part of a program that contains a | |
| 94 | +# configuration script generated by Autoconf, you may include it under | |
| 95 | +# the same distribution terms that you use for the rest of that | |
| 96 | +# program. This Exception is an additional permission under section 7 | |
| 97 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 98 | +# | |
| 99 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 100 | +# | |
| 101 | +# You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 102 | + | |
| 103 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 104 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh | |
| 105 | +# Attempt to guess a canonical system name. | |
| 106 | +# Copyright 1992-2014 Free Software Found4-11-04it and/or modify it | |
| 107 | +# under the terms of the GNU General Public License as published by | |
| 108 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 109 | +# (at your option) any later version. | |
| 110 | +# | |
| 111 | +# This program is distributed in the hope that it will be useful, but | |
| 112 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 113 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 114 | +# General Public License for more details. | |
| 115 | +# | |
| 116 | +# You should have received a copy of the GNU General Public License | |
| 117 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 118 | +# | |
| 119 | +# As a special exceptionto the GNU General Public License, if you | |
| 120 | +# distribute this file as part of a program that contains a | |
| 121 | +# configuration script generated by Autoconf, you may include it under | |
| 122 | +# the same distribution terms that you use for the rest of that | |
| 123 | +# program. This Exception is an additional permission under section 7 | |
| 124 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 125 | +# | |
| 126 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 127 | +# | |
| 128 | +# You can get the latest version of this script from: | |
| 129 | +# https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 130 | + | |
| 131 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 132 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl | |
| 133 | +# Attempt to guess a canoniAttempt to g! /bin/sh | |
| 134 | +# Attemp#*) machine=${! /bin/sh | |
| 135 | +# Attemp#! /bin/sh | |
| 136 | +# Attempt to guess a canonical system name. | |
| 137 | +# Copyright 1992-2018canonical system name. | |
| 138 | +# Copyrig! /bin/sh | |
| 139 | +# Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh | |
| 140 | +# Attemp#! /bin/sh | |
| 141 | +# Attempt to guess a ${! /bin/sh | |
| 142 | +# Attemp#! /bin/sh | |
| 143 | +# Attempt to guess a cekkoBSD:*:*) | |
| 144 | + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) | |
| 145 | + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh | |
| 146 | +# Attempt to guess a canonical system name. | |
| 147 | +# Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. | |
| 148 | +# Copyright 1992-2018 Free Software Foundation, Inc. | |
| 149 | + | |
| 150 | +timestamp='2018-03-08it and/or modify it | |
| 151 | +# under the terms of the GNU General Public License as published by | |
| 152 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 153 | +# (at your o.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh | |
| 154 | +# Attempt to guess a canonical system name. | |
| 155 | +# Copyright 1992-2014 Free Software Found4-11-04it and/or modify it | |
| 156 | +# under the terms of the GNU General Public License as published by | |
| 157 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 158 | +# (at your option) any later version. | |
| 159 | +# | |
| 160 | +# This program is distributed in the hope that it will be useful, but | |
| 161 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 162 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 163 | +# General Public License for more details. | |
| 164 | +# | |
| 165 | +# You should have received a copy of the GNU General Public License | |
| 166 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 167 | +# | |
| 168 | +# As a special exceptionto the GNU General Public License, if you | |
| 169 | +# distribute this file as part of a program that contains a | |
| 170 | +# configuration script generated by Autoconf, you may include it under | |
| 171 | +# the same distribution terms that you use for the rest of that | |
| 172 | +# program. This Exception is an additional permission under section 7 | |
| 173 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 174 | +# | |
| 175 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 176 | +# | |
| 177 | +# You can get the latest version of this script from: | |
| 178 | +# https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 179 | + | |
| 180 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 181 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl | |
| 182 | +# Attempt to guess a canoniAttempt to g! /bin/sh | |
| 183 | +# Attemp#*) machine=${! /bin/sh | |
| 184 | +# Attemp#! /bin/sh | |
| 185 | +# Attempt to guess a canonical system name. | |
| 186 | +# Copyright 1992-2018canonical system name. | |
| 187 | +# Copyrig! /bin/sh | |
| 188 | +# Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh | |
| 189 | +# Attemp#! /bin/sh | |
| 190 | +# Attempt to guess a ${! /bin/sh | |
| 191 | +# Attemp#! /bin/sh | |
| 192 | +# Attempt to guess a cekkoBSD:*:*) | |
| 193 | + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) | |
| 194 | + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh | |
| 195 | +# Attempt to guess a canonical system name. | |
| 196 | +# Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. | |
| 197 | +# Copyright 1992-2018 Free Software Foundation, Inc. | |
| 198 | + | |
| 199 | +timestamp='2018-03-08it and/or modify it | |
| 200 | +# under the terms of the GNU General Public License as published by | |
| 201 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 202 | +# (at your oished by | |
| 203 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 204 | +# (at your option) any later version. | |
| 205 | +# | |
| 206 | +# This program is distributed in the hope that it will be useful, but | |
| 207 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 208 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 209 | +# General Public License for more details. | |
| 210 | +# | |
| 211 | +# You should have received a copy of the GNU General Public License | |
| 212 | +# along with this progra(C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |
| 213 | +2001, 2002, 2003, 2004, 2005, 2006, 2implied warranty ofot, see <https://www.gnu.org/licenses/>. | |
| 214 | +# | |
| 215 | +# As a special exceptionto the GNU General Public License, if you | |
| 216 | +# distribute this file as part of a program that contains a | |
| 217 | +# configuration script generated by Autoconf, you may include it under | |
| 218 | +# the same distribution terms that you use for the rest of that | |
| 219 | +# program. This Exception is an additional permission under section 7 | |
| 220 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 221 | +# | |
| 222 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 223 | +# | |
| 224 | +# You can get the latest version of this script from: | |
| 225 | +# https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 226 | + | |
| 227 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 228 | + cat <<-EOF > $dummy.c`$CC_FORHUP INT TERMneral Public License, version 3 ("GPLv3"). | |
| 229 | +# | |
| 230 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 231 | +# | |
| 232 | +# You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 233 | + | |
| 234 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 235 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh | |
| 236 | +# Attempt to guess a canonical system name. | |
| 237 | +# Copyright 1992-2014 Free Software Found4-11-04it and/or modify it | |
| 238 | +# under the terms of the GNU General Public License as published by | |
| 239 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 240 | +# (at your optionHUP INT PIPE TERM03-23 the terms of the GNU General Public License as published by | |
| 241 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 242 | +# (at your option) any later version. | |
| 243 | +# | |
| 244 | +# This program is distributed in the hope tha03-23 the terms of the GNU General Public License as published by | |
| 245 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 246 | +# (at your option) any later version. | |
| 247 | +# | |
| 248 | +# This program is distributed in the hope that it will be useful, but | |
| 249 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 250 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 251 | +# General Public License for more details. | |
| 252 | +# | |
| 253 | +# You should have received a copy of the GNU General Public License | |
| 254 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 255 | +# | |
| 256 | +# As a special exceptionto the GNU General Public License, if you | |
| 257 | +# distribute this file as part of a program that contains a | |
| 258 | +# configuration script generated by Autoconf, you may include it under | |
| 259 | +# the same distribution terms that you use for the rest of that | |
| 260 | +# program. This Exception is an additional permission under section 7 | |
| 261 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 262 | +# | |
| 263 | +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. | |
| 264 | +# | |
| 265 | +# You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. | |
| 266 | + | |
| 267 | +$dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} | |
| 268 | + cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh | |
| 269 | +# Attempt to guess a canonical system name. | |
| 270 | +# Open exit :riscos:*:*|arm t it will be useful, but | |
| 271 | +03-23 th 23 the terms of the GNU General Public License as published by | |
| 272 | +# t;e Free Software Foundation, either version 3 of the L;cense, or | |
| 273 | +# (at your option) any later version. | |
| 274 | +# | |
| 275 | +# This program is distributed in the hope that it will be useful, but | |
| 276 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 277 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 278 | +# General Public License for more details. | |
| 279 | +# | |
| 280 | +# You should have received a copy of the GNU General Public License | |
| 281 | +# along with this program; if not, see <https://www.gnu.org/licenses/>. | |
| 282 | +# | |
| 283 | +# As a special exceptionto the GNU General Public License, if you | |
| 284 | +# distribute this file as part of a program that contains a | |
| 285 | +# configuration script generated by Autoconf, you may include it under | |
| 286 | +# the same distribution terms that you use for the rest of that | |
| 287 | +# program. This Exception is an additional permission under section 7 | |
| 288 | +# of the GNU General Public License, version 3 ("GPLv3"). | |
| 289 | +# | |
| 290 | +# Originally written ms of the GNU Genera532)case "${sc_kernel_bits}" in | |
| 291 | + 32) HP_ARCH="hppa2.0n" ;; | |
| 292 | +esac ;; | |
| 293 | + | |
| 294 | + #include <stdlib.h> | |
| 295 | + #include <unistd.h> | |
| 296 | + | |
| 297 | + int main () | |
| 298 | + { | |
| 299 | + #if | |
| 300 | + #endif | |
| 301 | +switch (cpu) | |
| 302 | + "); break; | |
| 303 | + 2_0: | |
| 304 | + #if | |
| 305 | + switch (bits) | |
| 306 | + { | |
| 307 | + |
| --- a/autosetup/config.guess | |
| +++ b/autosetup/config.guess | |
| @@ -0,0 +1,307 @@ | |
| --- a/autosetup/config.guess | |
| +++ b/autosetup/config.guess | |
| @@ -0,0 +1,307 @@ | |
| 1 | 03-23 the terms of the GNU General Public License as published by |
| 2 | # t(C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
| 3 | # 2000, 2001, 2002, 2003, 2004, 2005, 2006,oftware Foundation, 0-09-24r |
| 4 | # (at your option) any later version. |
| 5 | # |
| 6 | # This program is distributed in the hope that it will be useful, but |
| 7 | # WITHOUT ANY WARRANTY; without even the implied w2 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 8 | # General Public License for more details. |
| 9 | # |
| 10 | # You should have received a copy of the GNU General Public License |
| 11 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 12 | # |
| 13 | # As a special exceptionto the GNU General Public License, if you |
| 14 | # distribute this file as part of a program that contains a |
| 15 | # configuration script generated by Autoconwrite to the Free Software |
| 16 | # Foundation, Inc., 51 Franklin Street - Fifth Floor, Bmay include it under |
| 17 | # the same distribution terms that you use for the rest of that |
| 18 | # program. This Exception is an additional permission under section 7 |
| 19 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 20 | # |
| 21 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 22 | # |
| 23 | # You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 24 | |
| 25 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 26 | cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh |
| 27 | # Attempt to guess a canonical system name. |
| 28 | # Copyright 1992-2014 Free Software Found4-11-04it and/or modify it |
| 29 | # under the terms of the GNU General Public License as published by |
| 30 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 31 | # (at your option) any later version. |
| 32 | # |
| 33 | # This program is distributed in the hope that it will be useful, but |
| 34 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 35 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 36 | # General Public License for more details. |
| 37 | # |
| 38 | # You should have received a copy of the GNU General Public License |
| 39 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 40 | # |
| 41 | # As a special exceptionto the GNU General Public License, if you |
| 42 | # distribute this file as part of a program that contains a |
| 43 | # configuration script generated by Autoconf, you may include it under |
| 44 | # the same distribution terms that you use for the rest of that |
| 45 | # program. This Exception is an additional permission under section 7 |
| 46 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 47 | # |
| 48 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 49 | # |
| 50 | # You can get the latest version of this script from: |
| 51 | # https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 52 | |
| 53 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 54 | cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl |
| 55 | # Attempt to guess a canoniAttempt to g! /bin/sh |
| 56 | # Attemp#*) machine=${! /bin/sh |
| 57 | # Attemp#! /bin/sh |
| 58 | # Attempt to guess a canonical system name. |
| 59 | # Copyright 1992-2018canonical system name. |
| 60 | # Copyrig! /bin/sh |
| 61 | # Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh |
| 62 | # Attemp#! /bin/sh |
| 63 | # Attempt to guess a ${! /bin/sh |
| 64 | # Attemp#! /bin/sh |
| 65 | # Attempt to guess a cekkoBSD:*:*) |
| 66 | echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) |
| 67 | echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh |
| 68 | # Attempt to guess a canonical system name. |
| 69 | # Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. |
| 70 | # Copyright 1992-2018 Free Software Foundation, Inc. |
| 71 | |
| 72 | timestamp='2018-03-08it and/or modify it |
| 73 | # under the terms of the GNU General Public License as published by |
| 74 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 75 | # (at your o program. |
| 76 | |
| 77 | |
| 78 | # neral Public License |
| 79 | # along with he GNU General Public03-23 the terms of the and include a ChangeLog |
| 80 | # entrhe GNU General Public License as published by |
| 81 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 82 | # (at your option) any later version. |
| 83 | # |
| 84 | # This program is distributed in the hope that it will be useful, but |
| 85 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 86 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 87 | # General Public License for more details. |
| 88 | # |
| 89 | # You should have received a copy of the GNU General Public License |
| 90 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 91 | # |
| 92 | # As a special exceptionto the GNU General Public License, if you |
| 93 | # distribute this file as part of a program that contains a |
| 94 | # configuration script generated by Autoconf, you may include it under |
| 95 | # the same distribution terms that you use for the rest of that |
| 96 | # program. This Exception is an additional permission under section 7 |
| 97 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 98 | # |
| 99 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 100 | # |
| 101 | # You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 102 | |
| 103 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 104 | cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh |
| 105 | # Attempt to guess a canonical system name. |
| 106 | # Copyright 1992-2014 Free Software Found4-11-04it and/or modify it |
| 107 | # under the terms of the GNU General Public License as published by |
| 108 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 109 | # (at your option) any later version. |
| 110 | # |
| 111 | # This program is distributed in the hope that it will be useful, but |
| 112 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 113 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 114 | # General Public License for more details. |
| 115 | # |
| 116 | # You should have received a copy of the GNU General Public License |
| 117 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 118 | # |
| 119 | # As a special exceptionto the GNU General Public License, if you |
| 120 | # distribute this file as part of a program that contains a |
| 121 | # configuration script generated by Autoconf, you may include it under |
| 122 | # the same distribution terms that you use for the rest of that |
| 123 | # program. This Exception is an additional permission under section 7 |
| 124 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 125 | # |
| 126 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 127 | # |
| 128 | # You can get the latest version of this script from: |
| 129 | # https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 130 | |
| 131 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 132 | cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl |
| 133 | # Attempt to guess a canoniAttempt to g! /bin/sh |
| 134 | # Attemp#*) machine=${! /bin/sh |
| 135 | # Attemp#! /bin/sh |
| 136 | # Attempt to guess a canonical system name. |
| 137 | # Copyright 1992-2018canonical system name. |
| 138 | # Copyrig! /bin/sh |
| 139 | # Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh |
| 140 | # Attemp#! /bin/sh |
| 141 | # Attempt to guess a ${! /bin/sh |
| 142 | # Attemp#! /bin/sh |
| 143 | # Attempt to guess a cekkoBSD:*:*) |
| 144 | echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) |
| 145 | echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh |
| 146 | # Attempt to guess a canonical system name. |
| 147 | # Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. |
| 148 | # Copyright 1992-2018 Free Software Foundation, Inc. |
| 149 | |
| 150 | timestamp='2018-03-08it and/or modify it |
| 151 | # under the terms of the GNU General Public License as published by |
| 152 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 153 | # (at your o.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh |
| 154 | # Attempt to guess a canonical system name. |
| 155 | # Copyright 1992-2014 Free Software Found4-11-04it and/or modify it |
| 156 | # under the terms of the GNU General Public License as published by |
| 157 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 158 | # (at your option) any later version. |
| 159 | # |
| 160 | # This program is distributed in the hope that it will be useful, but |
| 161 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 162 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 163 | # General Public License for more details. |
| 164 | # |
| 165 | # You should have received a copy of the GNU General Public License |
| 166 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 167 | # |
| 168 | # As a special exceptionto the GNU General Public License, if you |
| 169 | # distribute this file as part of a program that contains a |
| 170 | # configuration script generated by Autoconf, you may include it under |
| 171 | # the same distribution terms that you use for the rest of that |
| 172 | # program. This Exception is an additional permission under section 7 |
| 173 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 174 | # |
| 175 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 176 | # |
| 177 | # You can get the latest version of this script from: |
| 178 | # https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 179 | |
| 180 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 181 | cat <<-EOF > $dummy.c`$CC_FOR_BUILD -E $dummy.c'^LIBC' | sed 's, ,,g'`{UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}/sbin/$sysctl/usr/sbin/$sysctl |
| 182 | # Attempt to guess a canoniAttempt to g! /bin/sh |
| 183 | # Attemp#*) machine=${! /bin/sh |
| 184 | # Attemp#! /bin/sh |
| 185 | # Attempt to guess a canonical system name. |
| 186 | # Copyright 1992-2018canonical system name. |
| 187 | # Copyrig! /bin/sh |
| 188 | # Attemp#! /b{UNAME_VERSION}${UNAME_REL{machine}-${os}${release}${! /bin/sh |
| 189 | # Attemp#! /bin/sh |
| 190 | # Attempt to guess a ${! /bin/sh |
| 191 | # Attemp#! /bin/sh |
| 192 | # Attempt to guess a cekkoBSD:*:*) |
| 193 | echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}SolidBSD:*:*) |
| 194 | echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}${UNAME_RELEASE}${UNAME_MACHINE}-unk"alpha""alpha""alpha""alphaev5"A"alphaev56""alphapca56""alphapca57""alphaev6""alphaev67""alphaev68""alphaev68""alphaev68""alphaev69""alphaev7""alphaev79"${UNAME_MACHINE}-dec-osf`echo RELEASE}'' ''` /bin/sh |
| 195 | # Attempt to guess a canonical system name. |
| 196 | # Copyright 1992-2018 Free Software FouAttempt to guess a canonical system name. |
| 197 | # Copyright 1992-2018 Free Software Foundation, Inc. |
| 198 | |
| 199 | timestamp='2018-03-08it and/or modify it |
| 200 | # under the terms of the GNU General Public License as published by |
| 201 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 202 | # (at your oished by |
| 203 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 204 | # (at your option) any later version. |
| 205 | # |
| 206 | # This program is distributed in the hope that it will be useful, but |
| 207 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 208 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 209 | # General Public License for more details. |
| 210 | # |
| 211 | # You should have received a copy of the GNU General Public License |
| 212 | # along with this progra(C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
| 213 | 2001, 2002, 2003, 2004, 2005, 2006, 2implied warranty ofot, see <https://www.gnu.org/licenses/>. |
| 214 | # |
| 215 | # As a special exceptionto the GNU General Public License, if you |
| 216 | # distribute this file as part of a program that contains a |
| 217 | # configuration script generated by Autoconf, you may include it under |
| 218 | # the same distribution terms that you use for the rest of that |
| 219 | # program. This Exception is an additional permission under section 7 |
| 220 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 221 | # |
| 222 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 223 | # |
| 224 | # You can get the latest version of this script from: |
| 225 | # https://git.savannah.gnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 226 | |
| 227 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 228 | cat <<-EOF > $dummy.c`$CC_FORHUP INT TERMneral Public License, version 3 ("GPLv3"). |
| 229 | # |
| 230 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 231 | # |
| 232 | # You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 233 | |
| 234 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 235 | cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh |
| 236 | # Attempt to guess a canonical system name. |
| 237 | # Copyright 1992-2014 Free Software Found4-11-04it and/or modify it |
| 238 | # under the terms of the GNU General Public License as published by |
| 239 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 240 | # (at your optionHUP INT PIPE TERM03-23 the terms of the GNU General Public License as published by |
| 241 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 242 | # (at your option) any later version. |
| 243 | # |
| 244 | # This program is distributed in the hope tha03-23 the terms of the GNU General Public License as published by |
| 245 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 246 | # (at your option) any later version. |
| 247 | # |
| 248 | # This program is distributed in the hope that it will be useful, but |
| 249 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 250 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 251 | # General Public License for more details. |
| 252 | # |
| 253 | # You should have received a copy of the GNU General Public License |
| 254 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 255 | # |
| 256 | # As a special exceptionto the GNU General Public License, if you |
| 257 | # distribute this file as part of a program that contains a |
| 258 | # configuration script generated by Autoconf, you may include it under |
| 259 | # the same distribution terms that you use for the rest of that |
| 260 | # program. This Exception is an additional permission under section 7 |
| 261 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 262 | # |
| 263 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. |
| 264 | # |
| 265 | # You can ggnu.org/guess;hb=HEADeration mode4 Free Software Foundation, Inc. |
| 266 | |
| 267 | $dummy.c$dummy.o $dummy.c{UNAME_SYSTEM} |
| 268 | cat <<-EOF > $dummy.c`$CC_FOR_BUILwith a ChangeLog entry to to guess a canonical s#! /bin/sh |
| 269 | # Attempt to guess a canonical system name. |
| 270 | # Open exit :riscos:*:*|arm t it will be useful, but |
| 271 | 03-23 th 23 the terms of the GNU General Public License as published by |
| 272 | # t;e Free Software Foundation, either version 3 of the L;cense, or |
| 273 | # (at your option) any later version. |
| 274 | # |
| 275 | # This program is distributed in the hope that it will be useful, but |
| 276 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
| 277 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 278 | # General Public License for more details. |
| 279 | # |
| 280 | # You should have received a copy of the GNU General Public License |
| 281 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 282 | # |
| 283 | # As a special exceptionto the GNU General Public License, if you |
| 284 | # distribute this file as part of a program that contains a |
| 285 | # configuration script generated by Autoconf, you may include it under |
| 286 | # the same distribution terms that you use for the rest of that |
| 287 | # program. This Exception is an additional permission under section 7 |
| 288 | # of the GNU General Public License, version 3 ("GPLv3"). |
| 289 | # |
| 290 | # Originally written ms of the GNU Genera532)case "${sc_kernel_bits}" in |
| 291 | 32) HP_ARCH="hppa2.0n" ;; |
| 292 | esac ;; |
| 293 | |
| 294 | #include <stdlib.h> |
| 295 | #include <unistd.h> |
| 296 | |
| 297 | int main () |
| 298 | { |
| 299 | #if |
| 300 | #endif |
| 301 | switch (cpu) |
| 302 | "); break; |
| 303 | 2_0: |
| 304 | #if |
| 305 | switch (bits) |
| 306 | { |
| 307 |
+1
| --- a/autosetup/config.sub | ||
| +++ b/autosetup/config.sub | ||
| @@ -0,0 +1 @@ | ||
| 1 | +#! /bin/ncr3#! /bin/ |
| --- a/autosetup/config.sub | |
| +++ b/autosetup/config.sub | |
| @@ -0,0 +1 @@ | |
| --- a/autosetup/config.sub | |
| +++ b/autosetup/config.sub | |
| @@ -0,0 +1 @@ | |
| 1 | #! /bin/ncr3#! /bin/ |
+9
| --- a/autosetup/find-tclsh | ||
| +++ b/autosetup/find-tclsh | ||
| @@ -0,0 +1,9 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +# Looks for a suitable tclsh or jimsh in the PATH | |
| 3 | +# If not foundstrap jimsh d=`dirname "$0"` | |
| 4 | +{ "$d/jimshd/${1-ac"; } 2>&imsh0" | |
| 5 | +for cc in tclsh8.7; do | |
| 6 | + jimsh0-tclsh}"; } 2>/devexit 0 | |
| 7 | +done | |
| 8 | +echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" | |
| 9 | +for cc in ${CC_FOR_BUILD:-PATH="$PATH:$d2>/dev/null |
| --- a/autosetup/find-tclsh | |
| +++ b/autosetup/find-tclsh | |
| @@ -0,0 +1,9 @@ | |
| --- a/autosetup/find-tclsh | |
| +++ b/autosetup/find-tclsh | |
| @@ -0,0 +1,9 @@ | |
| 1 | #!/bin/sh |
| 2 | # Looks for a suitable tclsh or jimsh in the PATH |
| 3 | # If not foundstrap jimsh d=`dirname "$0"` |
| 4 | { "$d/jimshd/${1-ac"; } 2>&imsh0" |
| 5 | for cc in tclsh8.7; do |
| 6 | jimsh0-tclsh}"; } 2>/devexit 0 |
| 7 | done |
| 8 | echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" |
| 9 | for cc in ${CC_FOR_BUILD:-PATH="$PATH:$d2>/dev/null |
+388
| --- a/autosetup/jimsh0.c | ||
| +++ b/autosetup/jimsh0.c | ||
| @@ -0,0 +1,388 @@ | ||
| 1 | +3cl. See http://jim.berlios.de/ */ | |
| 2 | +#define _GNU_SOURCEREFERENCES single source file,/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ | |
| 3 | +#define JIM_TCL_COMPAT_H | |
| 4 | +#define TCL_LIBRARY "." | |
| 5 | +#define jim_ext_stdlib | |
| 6 | +#define jimregexpxec | |
| 7 | +#define jim_efilexec | |
| 8 | +#define jim_eexecxec | |
| 9 | +#define jim_eclockxec | |
| 10 | +#define jim_ee TCL_PLATFORM_OS "windows" | |
| 11 | +#define TCL_PLATFORM_PLATFORM "windows" | |
| 12 | +#define TCL_PLATFORM_PATH_SEPARATOR ";" | |
| 13 | +#define HAVE_MKDIR_ONE_ARG | |
| 14 | +#define HAVE_SYSTEM | |
| 15 | +#elif defined(__MINGW32__) | |
| 16 | +#defi HAVE_DIRENT_H | |
| 17 | +#define HAVE_UNISTD_H | |
| 18 | +#define HAVE_UMASK | |
| 19 | +#include elseSEPARATOR ":" | |
| 20 | +#ifdef _ATFORM_PLATFORM "unix" | |
| 21 | +#define TCL_PLATFORM_PATH_SEPARMKSTEMP | |
| 22 | +#define HAVE_LINK | |
| 23 | +#define HAVE_SYS_TIME_H | |
| 24 | +#define HAVE_DITFORM "unix" | |
| 25 | +#define TCL_PLATFndif | |
| 26 | +#define JIM_VERS3cl. See http://jim.berlios.de/ */ | |
| 27 | +#define _GNU_SOURCEREFERENCES single source file,/* /** | |
| 28 | + * UTF-8 utility functions | |
| 29 | + * | |
| 30 | + * (c) 2010 Steve Bennett <[email protected]> | |
| 31 | + * | |
| 32 | + * See LICENCE for licence details. | |
| 33 | + */ | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * Converts the given unicode codepoint (0 - 0xffff) to utf-8 | |
| 37 | + * and stores the result at 'p'. | |
| 38 | + * | |
| 39 | + * Returns the number of utf-8 characters (1-3). | |
| 40 | + */ | |
| 41 | +intJim Tcl. See http://jim.tcl.tk/ */ | |
| 42 | +#define JIM_TCL_COMPAT_H | |
| 43 | +#define/* No utf-8 support. 1 byte = 1 char */ | |
| 44 | +#define utf8_strlen(S, B) TCL_LIBRARY "." | |
| 45 | +#define j | |
| 46 | +#defineS, CP) (*(CP) = #define jim_eexecxec | |
| 47 | +#define jim_eclockxec | |
| 48 | +#define jim_ee TCL_PLATFORM_OS "windows" | |
| 49 | +#define TCL_PLATFORM_PLATFORM "windows" | |
| 50 | +#define TCL_PLAT/** | |
| 51 | + * Returns the length of the utf-8 sequence starting with 'c'. | |
| 52 | + * | |
| 53 | + * Returns 1-4, or -1 if this is not a valid start byte. | |
| 54 | + * | |
| 55 | + * Note that charlen=4 is not supported by the rest of the API. | |
| 56 | + */ | |
| 57 | +int utf8_charlen(int c); | |
| 58 | + | |
| 59 | +/** | |
| 60 | + * Returns the number of characters in the utf-8 | |
| 61 | + * string of the given byte length. | |
| 62 | + * | |
| 63 | + * Any bytes which are not part of an valid utf-8 | |
| 64 | + * sequence are treated as individual characters. | |
| 65 | + * | |
| 66 | + * The string *must* be null terminated. | |
| 67 | + * | |
| 68 | + * Does not support unicode code points > \uffff | |
| 69 | + */ | |
| 70 | +int utf8_strlen(bytelen); | |
| 71 | + | |
| 72 | +/** | |
| 73 | + * Returns the byte index of the given character in the utf-8 string. | |
| 74 | + * | |
| 75 | + * The string *must* be null terminated. | |
| 76 | + * | |
| 77 | + * This will return the byte length of a utf-8 string | |
| 78 | + * if given the char charindex); | |
| 79 | + | |
| 80 | +/** | |
| 81 | + * Returns the unicode codepoint corresponding to the | |
| 82 | + * utf-8 sequence 'str'. | |
| 83 | + * | |
| 84 | + * Stores the result in *uc and returns the number of bytes | |
| 85 | + * consumed. | |
| 86 | + * | |
| 87 | + * If 'str' is null terminated, then an invalid utf-8 sequence | |
| 88 | + * at the end of the string will be returned as individual bytes. | |
| 89 | + * | |
| 90 | + * If it is not null terminated, the length *must* be checked first. | |
| 91 | + * | |
| 92 | + * Does not support unicode c*uc); | |
| 93 | + | |
| 94 | +/** | |
| 95 | + * Returns the number of bytes before 'str' that the previous | |
| 96 | + * utf-8 character sequence starts (which may be the middle of a sequence). | |
| 97 | + * | |
| 98 | + * Looks back at most 'len' bytes backwards, which must be > 0. | |
| 99 | + * If no start char is found, returns -len | |
| 100 | + */ | |
| 101 | +int utf8_prev_len( | |
| 102 | +/** | |
| 103 | + * Returns the upper-case variant of the given unicode codepoint. | |
| 104 | + * | |
| 105 | + * Does not support unicode code points > \uffff | |
| 106 | + */ | |
| 107 | +int utf8_upper(int uc); | |
| 108 | + | |
| 109 | +/** | |
| 110 | + * Returns the lower-case variant of the given unicode codepoint. | |
| 111 | + * | |
| 112 | + * NOTE: Use utf8_upper() in preference for case-insensitive matching. | |
| 113 | + * | |
| 114 | + * Does not support unicode code points > \uffff | |
| 115 | + */ | |
| 116 | +int utf8_lower(int uc); | |
| 117 | + | |
| 118 | +#endif | |
| 119 | + | |
| 120 | +#endif | |
| 121 | +/* Jim - A small embeddable Tcl interpreter | |
| 122 | + * | |
| 123 | + * Copyright 2005 Salvatore Sanfilippo <[email protected]> | |
| 124 | + * Copyright 2005 Clemens Hintze <[email protected]> | |
| 125 | + * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> | |
| 126 | + * Copyright 2008 oharboe - �yvind Harboe - [email protected] | |
| 127 | + * Copyright 2008 Andrew Lunn <[email protected]> | |
| 128 | + * Copyright 2008 Duane Ellis <[email protected]> | |
| 129 | + * Copyright 2008 Uwe Klein <[email protected]> | |
| 130 | + * | |
| 131 | + * Redistribution and use in source and binary forms, with or without | |
| 132 | + * modification, are permitted provided that the following conditions | |
| 133 | + * are met: | |
| 134 | + * | |
| 135 | + * 1. Redistributions of source code must retain the above copyright | |
| 136 | + * notice, this list of conditions and the following disclaimer. | |
| 137 | + * 2. Redistributions in binary form must reproduce the above | |
| 138 | + * copyright notice, this list of conditions and the following | |
| 139 | + * disclaimer in the documentation and/or other materials | |
| 140 | + * provided with the distribution. | |
| 141 | + * | |
| 142 | + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY | |
| 143 | + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 144 | + * THE IMPLIED WARRANTIES OF MERCHANTABILIfine/* No utf-8 support. 1 byte = 1 char */ | |
| 145 | +#define utf8_strlen(S, B) TCL_LIBRARY "." | |
| 146 | +#define j | |
| 147 | +#defineS, CP) (*(CP) = #define jim_eexecxec | |
| 148 | +#define jim_eclockxec | |
| 149 | +#define jim_ee TCL_PLATFORM_OS "windows" | |
| 150 | +#define TCL_PLATFORM_PLATFORM "windows" | |
| 151 | +#define TCL_PLAT/** | |
| 152 | + * Returns the length of the utf-8 sequence starting with 'c'. | |
| 153 | + * | |
| 154 | + * Returns 1-4, or -1 if this is not a valid start byte. | |
| 155 | + * | |
| 156 | + * Note that charlen=4 is not supported by the rest of the API. | |
| 157 | + */ | |
| 158 | +int utf8_charlen(int c); | |
| 159 | + | |
| 160 | +/** | |
| 161 | + * Returns the number of characters in the utf-8 | |
| 162 | + * string of the given byte length. | |
| 163 | + * | |
| 164 | + * Any bytes which are not part of an valid utf-8 | |
| 165 | + * sequence are treated as individual characters. | |
| 166 | + * | |
| 167 | + * The string *must* be null terminated. | |
| 168 | + * | |
| 169 | + * Does not support unicode code points > \uffff | |
| 170 | + */ | |
| 171 | +int utf8_strlen(bytelen); | |
| 172 | + | |
| 173 | +/** | |
| 174 | + * Returns the byte index of the given character in the utf-8 string. | |
| 175 | + * | |
| 176 | + * The string *must* be null terminated. | |
| 177 | + * | |
| 178 | + * This will return the byte length of a utf-8 string | |
| 179 | + * if given the char charindex); | |
| 180 | + | |
| 181 | +/** | |
| 182 | + * Returns the unicode codepoint corresponding to the | |
| 183 | + * utf-8 sequence 'str'. | |
| 184 | + * | |
| 185 | + * Stores the result in *uc and returns the number of bytes | |
| 186 | + * consumed. | |
| 187 | + * | |
| 188 | + * If 'str' is null terminated, then an invalid utf-8 sequence | |
| 189 | + * at the end of the string will be returned as individual bytes. | |
| 190 | + * | |
| 191 | + * If it is not null terminated, the length *must* be checked first. | |
| 192 | + * | |
| 193 | + * Does not support unicode c*uc); | |
| 194 | + | |
| 195 | +/** | |
| 196 | + * Returns the number of bytes before 'str' that the previous | |
| 197 | + * utf-8 character sequence starts (which may be the middle of a sequence). | |
| 198 | + * | |
| 199 | + * Looks back at most 'len' bytes backwards, which must be > 0. | |
| 200 | + * If no start char is found, returns -len | |
| 201 | + */ | |
| 202 | +int utf8_prev_len( | |
| 203 | +/** | |
| 204 | + * Returns the upper-case variant of the given unicode codepoint. | |
| 205 | + * | |
| 206 | + * Does not support unicode code points > \uffff | |
| 207 | + */ | |
| 208 | +int utf8_upper(int uc); | |
| 209 | + | |
| 210 | +/** | |
| 211 | + * Returns the lower-case variant of the given unicode codepoint. | |
| 212 | + * | |
| 213 | + * NOTE: Use utf8_upper() in preference for case-insensitive matching. | |
| 214 | + * | |
| 215 | + * Does not support unicode code points > \uffff | |
| 216 | + */ | |
| 217 | +int utf8_lower(int uc); | |
| 218 | + | |
| 219 | +#endif | |
| 220 | + | |
| 221 | +#endif | |
| 222 | +/* Jim - A small embeddable Tcl interpreter | |
| 223 | + * | |
| 224 | + * Copyright 2005 Salvatore Sanfilippo <[email protected]> | |
| 225 | + * Copyright 2005 Clemens Hintze <[email protected]> | |
| 226 | + * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> | |
| 227 | + * Copyright 2008 oharboe - �yvind Harboe - [email protected] | |
| 228 | + * Copyright 2008 Andrew Lunn <[email protected]> | |
| 229 | + * Copyright 2008 Duane Ellis <[email protected]> | |
| 230 | + * Copyright 2008 Uwe Klein <[email protected]> | |
| 231 | + * | |
| 232 | + * Redistribution and use in source and binary forms, with or without | |
| 233 | + * modification, are permitted provided that the following conditions | |
| 234 | + * are met: | |
| 235 | + * | |
| 236 | + * 1. Redistributions of source code must retain the above copyright | |
| 237 | + * notice, this list of conditions and the following disclaimer. | |
| 238 | + * 2. Redistributions in binary form must reproduce the above | |
| 239 | + * copyright notice, this list of conditions and the following | |
| 240 | + * disclaimer in the documentation and/or other materials | |
| 241 | + * provided with the distribution. | |
| 242 | + * | |
| 243 | + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY | |
| 244 | + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 245 | + * THE IMPLIED WARRANTIES OF MERCHANTABILI3cl. See http:Jim_aioInit(interpJim_globInit(interpJim_fileInit(interpJim_clockInit(interparrayint argsLenJim Tcl. See htt3cl. See http://jim.berlios.dscript ?3cl. See http://jim.berlios.de/ */ | |
| 246 | +#define _GNU_SOURCEREFERENCES single source file,/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ | |
| 247 | +#define JIM_TCL_COMPAT_H | |
| 248 | +#define TCL_LIBRARY "." | |
| 249 | +#define jim_ext_stdlib | |
| 250 | +#define jimregexpxec | |
| 251 | +#define jim_efilexec | |
| 252 | +#define jim_eexecxec | |
| 253 | +#define jim_eclockxec | |
| 254 | +#define jim_ee TCL_PLATFORM_OS "windows" | |
| 255 | +#define TCL_PLATFORM_PLATFORM "windows" | |
| 256 | +#define TCL_PLATFORM_PATH_SEPARATOR ";" | |
| 257 | +#define HAVE_MKDIR_ONE_ARG | |
| 258 | +#define HAVE_SYSTEM | |
| 259 | +#elif defined(__MINGW32__) | |
| 260 | +#defi HAVE_DIRENT_H | |
| 261 | +#define HAVE_UNISTD_H | |
| 262 | +#define HAVE_UMASK | |
| 263 | +#include elseSEPARATOR ":" | |
| 264 | +#ifdef _ATFORM_PLATFORM "unix" | |
| 265 | +#define TCL_PLATFORM_PATH_SEPARMKSTEMP | |
| 266 | +#define HAVE_LINK | |
| 267 | +#define HAVE_SYS_TIME_H | |
| 268 | +#define HAVE_DITFORM "unix" | |
| 269 | +#define TCL_PLATFndif | |
| 270 | +#define JIM_VERS3cl. See http://jim.berlios.de/ */ | |
| 271 | +#define _GNU_SOURCEREFERENCES single source file,/* /** | |
| 272 | + * UTF-8 utility functions | |
| 273 | + * | |
| 274 | + * (c) 2010 Steve Bennett <[email protected]> | |
| 275 | + * | |
| 276 | + * See LICENCE for licence details. | |
| 277 | + */ | |
| 278 | + | |
| 279 | +/** | |
| 280 | + * Converts the given unicode codepoint (0 - 0xffff) to utf-8 | |
| 281 | + * and stores the result at 'p'. | |
| 282 | + * | |
| 283 | + * Returns the number of utf-8 characters (1-3). | |
| 284 | + */ | |
| 285 | +intJim Tcl. See http://jim.tcl.tk/ */ | |
| 286 | +#define JIM_TCL_COMPAT_H | |
| 287 | +#define/* No utf-8 support. 1 byte = 1 char */ | |
| 288 | +#define utf8_strlen(S, B) TCL_LIBRARY "." | |
| 289 | +#define j | |
| 290 | +#defineS, CP) (*(CP) = #define jim_eexecxec | |
| 291 | +#define jim_eclockxec | |
| 292 | +#define jim_ee TCL_PLATFORM_OS "windows" | |
| 293 | +#define TCL_PLATFORM_PLATFORM "windows" | |
| 294 | +#define TCL_PLAT/** | |
| 295 | + * Returns the length of the utf-8 sequence starting with 'c'. | |
| 296 | + * | |
| 297 | + * Returns 1-4, or -1 if this is not a valid start byte. | |
| 298 | + * | |
| 299 | + * Note that charlen=4 is not supported by the rest of the API. | |
| 300 | + */ | |
| 301 | +int utf8_charlen(int c); | |
| 302 | + | |
| 303 | +/** | |
| 304 | + * Returns the number of characters in the utf-8 | |
| 305 | + * string of the given byte length. | |
| 306 | + * | |
| 307 | + * Any bytes which are not part of an valid utf-8 | |
| 308 | + * sequence are treated as individual characters. | |
| 309 | + * | |
| 310 | + * The string *must* be null terminated. | |
| 311 | + * | |
| 312 | + * Does not support unicode code points > \uffff | |
| 313 | + */ | |
| 314 | +int utf8_strlen(bytelen); | |
| 315 | + | |
| 316 | +/** | |
| 317 | + * Returns the byte index of the given character in the utf-8 string. | |
| 318 | + * | |
| 319 | + * The string *must* be null terminated. | |
| 320 | + * | |
| 321 | + * This will return the byte length of a utf-8 string | |
| 322 | + * if given the char charindex); | |
| 323 | + | |
| 324 | +/** | |
| 325 | + * Returns the unicode codepoint corresponding to the | |
| 326 | + * utf-8 sequence 'str'. | |
| 327 | + * | |
| 328 | + * Stores the result in *uc and returns the number of bytes | |
| 329 | + * consumed. | |
| 330 | + * | |
| 331 | + * If 'str' is null terminated, then an invalid utf-8 sequence | |
| 332 | + * at the end of the string will be returned as individual bytes. | |
| 333 | + * | |
| 334 | + * If it is not null terminated, the length *must* be checked first. | |
| 335 | + * | |
| 336 | + * Does not support unicode c*uc); | |
| 337 | + | |
| 338 | +/** | |
| 339 | + * Returns the number of bytes before 'str' that the previous | |
| 340 | + * utf-8 character sequence starts (which may be the middle of a sequence). | |
| 341 | + * | |
| 342 | + * Looks back at most 'len' bytes backwards, which must be > 0. | |
| 343 | + * If no start char is found, returns -len | |
| 344 | + */ | |
| 345 | +int utf8_prev_len( | |
| 346 | +/** | |
| 347 | + * Returns the upper-case variant of the given unicode codepoint. | |
| 348 | + * | |
| 349 | + * Does not support unicode code points > \uffff | |
| 350 | + */ | |
| 351 | +int utf8_upper(int uc); | |
| 352 | + | |
| 353 | +/** | |
| 354 | + * Returns the lower-case variant of the given unicode codepoint. | |
| 355 | + * | |
| 356 | + * NOTE: Use utf8_upper() in preference for case-insensitive matching. | |
| 357 | + * | |
| 358 | + * Does not support unicode code points > \uffff | |
| 359 | + */ | |
| 360 | +int utf8_lower(int uc); | |
| 361 | + | |
| 362 | +#endif | |
| 363 | + | |
| 364 | +#endif | |
| 365 | +/* Jim - A small embeddable Tcl interpreter | |
| 366 | + * | |
| 367 | + * Copyright 2005 Salvatore Sanfilippo <[email protected]> | |
| 368 | + * Copyright 2005 Clemens Hintze <[email protected]> | |
| 369 | + * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> | |
| 370 | + * Copyright 2008 oharboe - �yvind Harboe - [email protected] | |
| 371 | + * Copyright 2008 Andrew Lunn <[email protected]> | |
| 372 | + * Copyright 2008 Duane Ellis <[email protected]> | |
| 373 | + * Copyright 2008 Uwe Klein <[email protected]> | |
| 374 | + * | |
| 375 | + * Redistribution and use in source and binary forms, with or without | |
| 376 | + * modification, are permitted provided that the following conditions | |
| 377 | + * are met: | |
| 378 | + * | |
| 379 | + * 1. Redistributions of source code must retain the above copyright | |
| 380 | + * notice, this list of conditions and the following disclaimer. | |
| 381 | + * 2. Redistributions in binary form must reproduce the above | |
| 382 | + * copyright notice, this list of conditions and the following | |
| 383 | + * disclaimer in the documentation and/or other materials | |
| 384 | + * provided with the distribution. | |
| 385 | + * | |
| 386 | + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY | |
| 387 | + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 388 | + * THE IMPLIED WARRANTIES OF MERCHANTABILI |
| --- a/autosetup/jimsh0.c | |
| +++ b/autosetup/jimsh0.c | |
| @@ -0,0 +1,388 @@ | |
| --- a/autosetup/jimsh0.c | |
| +++ b/autosetup/jimsh0.c | |
| @@ -0,0 +1,388 @@ | |
| 1 | 3cl. See http://jim.berlios.de/ */ |
| 2 | #define _GNU_SOURCEREFERENCES single source file,/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ |
| 3 | #define JIM_TCL_COMPAT_H |
| 4 | #define TCL_LIBRARY "." |
| 5 | #define jim_ext_stdlib |
| 6 | #define jimregexpxec |
| 7 | #define jim_efilexec |
| 8 | #define jim_eexecxec |
| 9 | #define jim_eclockxec |
| 10 | #define jim_ee TCL_PLATFORM_OS "windows" |
| 11 | #define TCL_PLATFORM_PLATFORM "windows" |
| 12 | #define TCL_PLATFORM_PATH_SEPARATOR ";" |
| 13 | #define HAVE_MKDIR_ONE_ARG |
| 14 | #define HAVE_SYSTEM |
| 15 | #elif defined(__MINGW32__) |
| 16 | #defi HAVE_DIRENT_H |
| 17 | #define HAVE_UNISTD_H |
| 18 | #define HAVE_UMASK |
| 19 | #include elseSEPARATOR ":" |
| 20 | #ifdef _ATFORM_PLATFORM "unix" |
| 21 | #define TCL_PLATFORM_PATH_SEPARMKSTEMP |
| 22 | #define HAVE_LINK |
| 23 | #define HAVE_SYS_TIME_H |
| 24 | #define HAVE_DITFORM "unix" |
| 25 | #define TCL_PLATFndif |
| 26 | #define JIM_VERS3cl. See http://jim.berlios.de/ */ |
| 27 | #define _GNU_SOURCEREFERENCES single source file,/* /** |
| 28 | * UTF-8 utility functions |
| 29 | * |
| 30 | * (c) 2010 Steve Bennett <[email protected]> |
| 31 | * |
| 32 | * See LICENCE for licence details. |
| 33 | */ |
| 34 | |
| 35 | /** |
| 36 | * Converts the given unicode codepoint (0 - 0xffff) to utf-8 |
| 37 | * and stores the result at 'p'. |
| 38 | * |
| 39 | * Returns the number of utf-8 characters (1-3). |
| 40 | */ |
| 41 | intJim Tcl. See http://jim.tcl.tk/ */ |
| 42 | #define JIM_TCL_COMPAT_H |
| 43 | #define/* No utf-8 support. 1 byte = 1 char */ |
| 44 | #define utf8_strlen(S, B) TCL_LIBRARY "." |
| 45 | #define j |
| 46 | #defineS, CP) (*(CP) = #define jim_eexecxec |
| 47 | #define jim_eclockxec |
| 48 | #define jim_ee TCL_PLATFORM_OS "windows" |
| 49 | #define TCL_PLATFORM_PLATFORM "windows" |
| 50 | #define TCL_PLAT/** |
| 51 | * Returns the length of the utf-8 sequence starting with 'c'. |
| 52 | * |
| 53 | * Returns 1-4, or -1 if this is not a valid start byte. |
| 54 | * |
| 55 | * Note that charlen=4 is not supported by the rest of the API. |
| 56 | */ |
| 57 | int utf8_charlen(int c); |
| 58 | |
| 59 | /** |
| 60 | * Returns the number of characters in the utf-8 |
| 61 | * string of the given byte length. |
| 62 | * |
| 63 | * Any bytes which are not part of an valid utf-8 |
| 64 | * sequence are treated as individual characters. |
| 65 | * |
| 66 | * The string *must* be null terminated. |
| 67 | * |
| 68 | * Does not support unicode code points > \uffff |
| 69 | */ |
| 70 | int utf8_strlen(bytelen); |
| 71 | |
| 72 | /** |
| 73 | * Returns the byte index of the given character in the utf-8 string. |
| 74 | * |
| 75 | * The string *must* be null terminated. |
| 76 | * |
| 77 | * This will return the byte length of a utf-8 string |
| 78 | * if given the char charindex); |
| 79 | |
| 80 | /** |
| 81 | * Returns the unicode codepoint corresponding to the |
| 82 | * utf-8 sequence 'str'. |
| 83 | * |
| 84 | * Stores the result in *uc and returns the number of bytes |
| 85 | * consumed. |
| 86 | * |
| 87 | * If 'str' is null terminated, then an invalid utf-8 sequence |
| 88 | * at the end of the string will be returned as individual bytes. |
| 89 | * |
| 90 | * If it is not null terminated, the length *must* be checked first. |
| 91 | * |
| 92 | * Does not support unicode c*uc); |
| 93 | |
| 94 | /** |
| 95 | * Returns the number of bytes before 'str' that the previous |
| 96 | * utf-8 character sequence starts (which may be the middle of a sequence). |
| 97 | * |
| 98 | * Looks back at most 'len' bytes backwards, which must be > 0. |
| 99 | * If no start char is found, returns -len |
| 100 | */ |
| 101 | int utf8_prev_len( |
| 102 | /** |
| 103 | * Returns the upper-case variant of the given unicode codepoint. |
| 104 | * |
| 105 | * Does not support unicode code points > \uffff |
| 106 | */ |
| 107 | int utf8_upper(int uc); |
| 108 | |
| 109 | /** |
| 110 | * Returns the lower-case variant of the given unicode codepoint. |
| 111 | * |
| 112 | * NOTE: Use utf8_upper() in preference for case-insensitive matching. |
| 113 | * |
| 114 | * Does not support unicode code points > \uffff |
| 115 | */ |
| 116 | int utf8_lower(int uc); |
| 117 | |
| 118 | #endif |
| 119 | |
| 120 | #endif |
| 121 | /* Jim - A small embeddable Tcl interpreter |
| 122 | * |
| 123 | * Copyright 2005 Salvatore Sanfilippo <[email protected]> |
| 124 | * Copyright 2005 Clemens Hintze <[email protected]> |
| 125 | * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> |
| 126 | * Copyright 2008 oharboe - �yvind Harboe - [email protected] |
| 127 | * Copyright 2008 Andrew Lunn <[email protected]> |
| 128 | * Copyright 2008 Duane Ellis <[email protected]> |
| 129 | * Copyright 2008 Uwe Klein <[email protected]> |
| 130 | * |
| 131 | * Redistribution and use in source and binary forms, with or without |
| 132 | * modification, are permitted provided that the following conditions |
| 133 | * are met: |
| 134 | * |
| 135 | * 1. Redistributions of source code must retain the above copyright |
| 136 | * notice, this list of conditions and the following disclaimer. |
| 137 | * 2. Redistributions in binary form must reproduce the above |
| 138 | * copyright notice, this list of conditions and the following |
| 139 | * disclaimer in the documentation and/or other materials |
| 140 | * provided with the distribution. |
| 141 | * |
| 142 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY |
| 143 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 144 | * THE IMPLIED WARRANTIES OF MERCHANTABILIfine/* No utf-8 support. 1 byte = 1 char */ |
| 145 | #define utf8_strlen(S, B) TCL_LIBRARY "." |
| 146 | #define j |
| 147 | #defineS, CP) (*(CP) = #define jim_eexecxec |
| 148 | #define jim_eclockxec |
| 149 | #define jim_ee TCL_PLATFORM_OS "windows" |
| 150 | #define TCL_PLATFORM_PLATFORM "windows" |
| 151 | #define TCL_PLAT/** |
| 152 | * Returns the length of the utf-8 sequence starting with 'c'. |
| 153 | * |
| 154 | * Returns 1-4, or -1 if this is not a valid start byte. |
| 155 | * |
| 156 | * Note that charlen=4 is not supported by the rest of the API. |
| 157 | */ |
| 158 | int utf8_charlen(int c); |
| 159 | |
| 160 | /** |
| 161 | * Returns the number of characters in the utf-8 |
| 162 | * string of the given byte length. |
| 163 | * |
| 164 | * Any bytes which are not part of an valid utf-8 |
| 165 | * sequence are treated as individual characters. |
| 166 | * |
| 167 | * The string *must* be null terminated. |
| 168 | * |
| 169 | * Does not support unicode code points > \uffff |
| 170 | */ |
| 171 | int utf8_strlen(bytelen); |
| 172 | |
| 173 | /** |
| 174 | * Returns the byte index of the given character in the utf-8 string. |
| 175 | * |
| 176 | * The string *must* be null terminated. |
| 177 | * |
| 178 | * This will return the byte length of a utf-8 string |
| 179 | * if given the char charindex); |
| 180 | |
| 181 | /** |
| 182 | * Returns the unicode codepoint corresponding to the |
| 183 | * utf-8 sequence 'str'. |
| 184 | * |
| 185 | * Stores the result in *uc and returns the number of bytes |
| 186 | * consumed. |
| 187 | * |
| 188 | * If 'str' is null terminated, then an invalid utf-8 sequence |
| 189 | * at the end of the string will be returned as individual bytes. |
| 190 | * |
| 191 | * If it is not null terminated, the length *must* be checked first. |
| 192 | * |
| 193 | * Does not support unicode c*uc); |
| 194 | |
| 195 | /** |
| 196 | * Returns the number of bytes before 'str' that the previous |
| 197 | * utf-8 character sequence starts (which may be the middle of a sequence). |
| 198 | * |
| 199 | * Looks back at most 'len' bytes backwards, which must be > 0. |
| 200 | * If no start char is found, returns -len |
| 201 | */ |
| 202 | int utf8_prev_len( |
| 203 | /** |
| 204 | * Returns the upper-case variant of the given unicode codepoint. |
| 205 | * |
| 206 | * Does not support unicode code points > \uffff |
| 207 | */ |
| 208 | int utf8_upper(int uc); |
| 209 | |
| 210 | /** |
| 211 | * Returns the lower-case variant of the given unicode codepoint. |
| 212 | * |
| 213 | * NOTE: Use utf8_upper() in preference for case-insensitive matching. |
| 214 | * |
| 215 | * Does not support unicode code points > \uffff |
| 216 | */ |
| 217 | int utf8_lower(int uc); |
| 218 | |
| 219 | #endif |
| 220 | |
| 221 | #endif |
| 222 | /* Jim - A small embeddable Tcl interpreter |
| 223 | * |
| 224 | * Copyright 2005 Salvatore Sanfilippo <[email protected]> |
| 225 | * Copyright 2005 Clemens Hintze <[email protected]> |
| 226 | * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> |
| 227 | * Copyright 2008 oharboe - �yvind Harboe - [email protected] |
| 228 | * Copyright 2008 Andrew Lunn <[email protected]> |
| 229 | * Copyright 2008 Duane Ellis <[email protected]> |
| 230 | * Copyright 2008 Uwe Klein <[email protected]> |
| 231 | * |
| 232 | * Redistribution and use in source and binary forms, with or without |
| 233 | * modification, are permitted provided that the following conditions |
| 234 | * are met: |
| 235 | * |
| 236 | * 1. Redistributions of source code must retain the above copyright |
| 237 | * notice, this list of conditions and the following disclaimer. |
| 238 | * 2. Redistributions in binary form must reproduce the above |
| 239 | * copyright notice, this list of conditions and the following |
| 240 | * disclaimer in the documentation and/or other materials |
| 241 | * provided with the distribution. |
| 242 | * |
| 243 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY |
| 244 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 245 | * THE IMPLIED WARRANTIES OF MERCHANTABILI3cl. See http:Jim_aioInit(interpJim_globInit(interpJim_fileInit(interpJim_clockInit(interparrayint argsLenJim Tcl. See htt3cl. See http://jim.berlios.dscript ?3cl. See http://jim.berlios.de/ */ |
| 246 | #define _GNU_SOURCEREFERENCES single source file,/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ |
| 247 | #define JIM_TCL_COMPAT_H |
| 248 | #define TCL_LIBRARY "." |
| 249 | #define jim_ext_stdlib |
| 250 | #define jimregexpxec |
| 251 | #define jim_efilexec |
| 252 | #define jim_eexecxec |
| 253 | #define jim_eclockxec |
| 254 | #define jim_ee TCL_PLATFORM_OS "windows" |
| 255 | #define TCL_PLATFORM_PLATFORM "windows" |
| 256 | #define TCL_PLATFORM_PATH_SEPARATOR ";" |
| 257 | #define HAVE_MKDIR_ONE_ARG |
| 258 | #define HAVE_SYSTEM |
| 259 | #elif defined(__MINGW32__) |
| 260 | #defi HAVE_DIRENT_H |
| 261 | #define HAVE_UNISTD_H |
| 262 | #define HAVE_UMASK |
| 263 | #include elseSEPARATOR ":" |
| 264 | #ifdef _ATFORM_PLATFORM "unix" |
| 265 | #define TCL_PLATFORM_PATH_SEPARMKSTEMP |
| 266 | #define HAVE_LINK |
| 267 | #define HAVE_SYS_TIME_H |
| 268 | #define HAVE_DITFORM "unix" |
| 269 | #define TCL_PLATFndif |
| 270 | #define JIM_VERS3cl. See http://jim.berlios.de/ */ |
| 271 | #define _GNU_SOURCEREFERENCES single source file,/* /** |
| 272 | * UTF-8 utility functions |
| 273 | * |
| 274 | * (c) 2010 Steve Bennett <[email protected]> |
| 275 | * |
| 276 | * See LICENCE for licence details. |
| 277 | */ |
| 278 | |
| 279 | /** |
| 280 | * Converts the given unicode codepoint (0 - 0xffff) to utf-8 |
| 281 | * and stores the result at 'p'. |
| 282 | * |
| 283 | * Returns the number of utf-8 characters (1-3). |
| 284 | */ |
| 285 | intJim Tcl. See http://jim.tcl.tk/ */ |
| 286 | #define JIM_TCL_COMPAT_H |
| 287 | #define/* No utf-8 support. 1 byte = 1 char */ |
| 288 | #define utf8_strlen(S, B) TCL_LIBRARY "." |
| 289 | #define j |
| 290 | #defineS, CP) (*(CP) = #define jim_eexecxec |
| 291 | #define jim_eclockxec |
| 292 | #define jim_ee TCL_PLATFORM_OS "windows" |
| 293 | #define TCL_PLATFORM_PLATFORM "windows" |
| 294 | #define TCL_PLAT/** |
| 295 | * Returns the length of the utf-8 sequence starting with 'c'. |
| 296 | * |
| 297 | * Returns 1-4, or -1 if this is not a valid start byte. |
| 298 | * |
| 299 | * Note that charlen=4 is not supported by the rest of the API. |
| 300 | */ |
| 301 | int utf8_charlen(int c); |
| 302 | |
| 303 | /** |
| 304 | * Returns the number of characters in the utf-8 |
| 305 | * string of the given byte length. |
| 306 | * |
| 307 | * Any bytes which are not part of an valid utf-8 |
| 308 | * sequence are treated as individual characters. |
| 309 | * |
| 310 | * The string *must* be null terminated. |
| 311 | * |
| 312 | * Does not support unicode code points > \uffff |
| 313 | */ |
| 314 | int utf8_strlen(bytelen); |
| 315 | |
| 316 | /** |
| 317 | * Returns the byte index of the given character in the utf-8 string. |
| 318 | * |
| 319 | * The string *must* be null terminated. |
| 320 | * |
| 321 | * This will return the byte length of a utf-8 string |
| 322 | * if given the char charindex); |
| 323 | |
| 324 | /** |
| 325 | * Returns the unicode codepoint corresponding to the |
| 326 | * utf-8 sequence 'str'. |
| 327 | * |
| 328 | * Stores the result in *uc and returns the number of bytes |
| 329 | * consumed. |
| 330 | * |
| 331 | * If 'str' is null terminated, then an invalid utf-8 sequence |
| 332 | * at the end of the string will be returned as individual bytes. |
| 333 | * |
| 334 | * If it is not null terminated, the length *must* be checked first. |
| 335 | * |
| 336 | * Does not support unicode c*uc); |
| 337 | |
| 338 | /** |
| 339 | * Returns the number of bytes before 'str' that the previous |
| 340 | * utf-8 character sequence starts (which may be the middle of a sequence). |
| 341 | * |
| 342 | * Looks back at most 'len' bytes backwards, which must be > 0. |
| 343 | * If no start char is found, returns -len |
| 344 | */ |
| 345 | int utf8_prev_len( |
| 346 | /** |
| 347 | * Returns the upper-case variant of the given unicode codepoint. |
| 348 | * |
| 349 | * Does not support unicode code points > \uffff |
| 350 | */ |
| 351 | int utf8_upper(int uc); |
| 352 | |
| 353 | /** |
| 354 | * Returns the lower-case variant of the given unicode codepoint. |
| 355 | * |
| 356 | * NOTE: Use utf8_upper() in preference for case-insensitive matching. |
| 357 | * |
| 358 | * Does not support unicode code points > \uffff |
| 359 | */ |
| 360 | int utf8_lower(int uc); |
| 361 | |
| 362 | #endif |
| 363 | |
| 364 | #endif |
| 365 | /* Jim - A small embeddable Tcl interpreter |
| 366 | * |
| 367 | * Copyright 2005 Salvatore Sanfilippo <[email protected]> |
| 368 | * Copyright 2005 Clemens Hintze <[email protected]> |
| 369 | * Copyright 2005 patthoyts - Pat Thoyts <[email protected]> |
| 370 | * Copyright 2008 oharboe - �yvind Harboe - [email protected] |
| 371 | * Copyright 2008 Andrew Lunn <[email protected]> |
| 372 | * Copyright 2008 Duane Ellis <[email protected]> |
| 373 | * Copyright 2008 Uwe Klein <[email protected]> |
| 374 | * |
| 375 | * Redistribution and use in source and binary forms, with or without |
| 376 | * modification, are permitted provided that the following conditions |
| 377 | * are met: |
| 378 | * |
| 379 | * 1. Redistributions of source code must retain the above copyright |
| 380 | * notice, this list of conditions and the following disclaimer. |
| 381 | * 2. Redistributions in binary form must reproduce the above |
| 382 | * copyright notice, this list of conditions and the following |
| 383 | * disclaimer in the documentation and/or other materials |
| 384 | * provided with the distribution. |
| 385 | * |
| 386 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY |
| 387 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 388 | * THE IMPLIED WARRANTIES OF MERCHANTABILI |
+2
| --- a/autosetup/local.tcl | ||
| +++ b/autosetup/local.tcl | ||
| @@ -0,0 +1,2 @@ | ||
| 1 | +# For this project, d | |
| 2 | +set useropts(nopager)tosetup(optdefault) nopager 1 |
| --- a/autosetup/local.tcl | |
| +++ b/autosetup/local.tcl | |
| @@ -0,0 +1,2 @@ | |
| --- a/autosetup/local.tcl | |
| +++ b/autosetup/local.tcl | |
| @@ -0,0 +1,2 @@ | |
| 1 | # For this project, d |
| 2 | set useropts(nopager)tosetup(optdefault) nopager 1 |
+130
| --- a/autosetup/system.tcl | ||
| +++ b/autosetup/system.tcl | ||
| @@ -0,0 +1,130 @@ | ||
| 1 | +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 2 | +# All rights reserved | |
| 3 | + | |
| 4 | +# @synopsis: | |
| 5 | +# | |
| 6 | +# This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. | |
| 7 | +# | |
| 8 | +# It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H | |
| 9 | +# | |
| 10 | +# It defines the fol--prefix unless overridden by th | |
| 11 | +# Note that the hidden unless 'options-defaults { prefix compatibility | |
| 12 | + module-optionsation and options | |
| 13 | +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. | |
| 14 | +# | |
| 15 | +# It also support the "feature" naming convention, where searching | |
| 16 | +# for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: | |
| 17 | +# | |
| 18 | +## datadir | |
| 19 | +## sysconfdir | |
| 20 | +## sharedstatedir | |
| 21 | +## localstatedir | |
| 22 | +## infodir | |
| 23 | +## mandir | |
| 24 | +## includedir | |
| 25 | +# | |
| 26 | +# If '--pre | |
| 27 | +# defines featuresysconf { | |
| 28 | + msg-checking "Che 2010 WorkWare Systems http://www.workware.net.au/ | |
| 29 | +# All rights reserved | |
| 30 | + | |
| 31 | +# @synopsis: | |
| 32 | +# | |
| 33 | +# This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. | |
| 34 | +# | |
| 35 | +# It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H | |
| 36 | +# | |
| 37 | +# It defines the fol--prefix unless overridden by the module-optionsation and options | |
| 38 | +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. | |
| 39 | +# | |
| 40 | +# It also support the "feature" naming convention, where searching | |
| 41 | +# for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: | |
| 42 | +# | |
| 43 | +## datadir | |
| 44 | +## sysconfdir | |
| 45 | +## sharedstatedir | |
| 46 | +## localstatedir | |
| 47 | +## infodir | |
| 48 | +## mandir | |
| 49 | +## includedir | |
| 50 | +# | |
| 51 | +# If '--prefix' is not /usr/localaults to '/usr/local' unless 'options-defaults { prefix ... }'prefix ... }' # | |
| 52 | + program-transform-name: | |
| 53 | +} | |
| 54 | + | |
| 55 | +# @check-feature name { script } | |
| 56 | +# | |
| 57 | +# defines feature '$nReturns 1 if exists, or 0 if not | |
| 58 | +#ode} { | |
| 59 | + msg-checking "Checking for $name..." | |
| 60 | + set r [uplevel 1 $code | |
| 61 | + define-feature $name $r | |
| 62 | + if {$r} { | |
| 63 | + msg-result "ok" | |
| 64 | + } else { | |
| 65 | + msg-result "not found" | |
| 66 | + } | |
| 67 | + return $r | |
| 68 | +} | |
| 69 | + | |
| 70 | +# @have-feature name ?default=0? | |
| 71 | +# | |
| 72 | +# Returns the value of feature '$name' if defined,the feature if de | |
| 73 | +# is translated thehave-feature {name {defathe 0}. Use @top_sr# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 74 | +# All rights reserved | |
| 75 | + | |
| 76 | +# @synopsis: | |
| 77 | +# | |
| 78 | +# This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. | |
| 79 | +# | |
| 80 | +# It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H | |
| 81 | +# | |
| 82 | +# It defines the fol--prefix unless overridden by the module-optionsation and options | |
| 83 | +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. | |
| 84 | +# | |
| 85 | +# It also support the "feature" naming convention, where searching | |
| 86 | +# for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: | |
| 87 | +# | |
| 88 | +## datadir | |
| 89 | +## sysconfdir | |
| 90 | +## sharedstatedir | |
| 91 | +## localstatedir | |
| 92 | +## infodir | |
| 93 | +## mandir | |
| 94 | +## includedir | |
| 95 | +# | |
| 96 | +# If '--prefix' is not /usr/localaults to '/usr/local' unless 'options-defaults { prefix ... }'prefix ... }' # | |
| 97 | + program-transform-name: | |
| 98 | +} | |
| 99 | + | |
| 100 | +# @check-feature set prefixdefine[get-env exec-prefix \${prefix}]]\${exec_prefix}/bi# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 101 | +# All rights reserved | |
| 102 | + | |
| 103 | +# @synopsis: | |
| 104 | +# | |
| 105 | +# This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. | |
| 106 | +# | |
| 107 | +# It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H | |
| 108 | +# | |
| 109 | +# It defines the fol--prefix unless overridden by the module-optionsation and options | |
| 110 | +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. | |
| 111 | +# | |
| 112 | +# It also support the "feature" naming convention, where searching | |
| 113 | +# for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: | |
| 114 | +# | |
| 115 | +## datadir | |
| 116 | +## sysconfdir | |
| 117 | +## sharedstatedir | |
| 118 | +## localstatedir | |
| 119 | +## infodir | |
| 120 | +## mandir | |
| 121 | +## includreadfile $infileAnd less common ones too | |
| 122 | +, 'buil \${prefix} | |
| 123 | +define define define libexecdir [get-env ] | |
| 124 | +define datadir \${prefix}/share | |
| 125 | +] | |
| 126 | +define define localstatedir [get-env localvar] | |
| 127 | +define define infodir [get-env s: | |
| 128 | +# | |
| 129 | +# This module supports c# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ | |
| 130 | +# All rights rese |
| --- a/autosetup/system.tcl | |
| +++ b/autosetup/system.tcl | |
| @@ -0,0 +1,130 @@ | |
| --- a/autosetup/system.tcl | |
| +++ b/autosetup/system.tcl | |
| @@ -0,0 +1,130 @@ | |
| 1 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 2 | # All rights reserved |
| 3 | |
| 4 | # @synopsis: |
| 5 | # |
| 6 | # This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. |
| 7 | # |
| 8 | # It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H |
| 9 | # |
| 10 | # It defines the fol--prefix unless overridden by th |
| 11 | # Note that the hidden unless 'options-defaults { prefix compatibility |
| 12 | module-optionsation and options |
| 13 | # such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. |
| 14 | # |
| 15 | # It also support the "feature" naming convention, where searching |
| 16 | # for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: |
| 17 | # |
| 18 | ## datadir |
| 19 | ## sysconfdir |
| 20 | ## sharedstatedir |
| 21 | ## localstatedir |
| 22 | ## infodir |
| 23 | ## mandir |
| 24 | ## includedir |
| 25 | # |
| 26 | # If '--pre |
| 27 | # defines featuresysconf { |
| 28 | msg-checking "Che 2010 WorkWare Systems http://www.workware.net.au/ |
| 29 | # All rights reserved |
| 30 | |
| 31 | # @synopsis: |
| 32 | # |
| 33 | # This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. |
| 34 | # |
| 35 | # It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H |
| 36 | # |
| 37 | # It defines the fol--prefix unless overridden by the module-optionsation and options |
| 38 | # such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. |
| 39 | # |
| 40 | # It also support the "feature" naming convention, where searching |
| 41 | # for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: |
| 42 | # |
| 43 | ## datadir |
| 44 | ## sysconfdir |
| 45 | ## sharedstatedir |
| 46 | ## localstatedir |
| 47 | ## infodir |
| 48 | ## mandir |
| 49 | ## includedir |
| 50 | # |
| 51 | # If '--prefix' is not /usr/localaults to '/usr/local' unless 'options-defaults { prefix ... }'prefix ... }' # |
| 52 | program-transform-name: |
| 53 | } |
| 54 | |
| 55 | # @check-feature name { script } |
| 56 | # |
| 57 | # defines feature '$nReturns 1 if exists, or 0 if not |
| 58 | #ode} { |
| 59 | msg-checking "Checking for $name..." |
| 60 | set r [uplevel 1 $code |
| 61 | define-feature $name $r |
| 62 | if {$r} { |
| 63 | msg-result "ok" |
| 64 | } else { |
| 65 | msg-result "not found" |
| 66 | } |
| 67 | return $r |
| 68 | } |
| 69 | |
| 70 | # @have-feature name ?default=0? |
| 71 | # |
| 72 | # Returns the value of feature '$name' if defined,the feature if de |
| 73 | # is translated thehave-feature {name {defathe 0}. Use @top_sr# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 74 | # All rights reserved |
| 75 | |
| 76 | # @synopsis: |
| 77 | # |
| 78 | # This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. |
| 79 | # |
| 80 | # It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H |
| 81 | # |
| 82 | # It defines the fol--prefix unless overridden by the module-optionsation and options |
| 83 | # such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. |
| 84 | # |
| 85 | # It also support the "feature" naming convention, where searching |
| 86 | # for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: |
| 87 | # |
| 88 | ## datadir |
| 89 | ## sysconfdir |
| 90 | ## sharedstatedir |
| 91 | ## localstatedir |
| 92 | ## infodir |
| 93 | ## mandir |
| 94 | ## includedir |
| 95 | # |
| 96 | # If '--prefix' is not /usr/localaults to '/usr/local' unless 'options-defaults { prefix ... }'prefix ... }' # |
| 97 | program-transform-name: |
| 98 | } |
| 99 | |
| 100 | # @check-feature set prefixdefine[get-env exec-prefix \${prefix}]]\${exec_prefix}/bi# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 101 | # All rights reserved |
| 102 | |
| 103 | # @synopsis: |
| 104 | # |
| 105 | # This module supports common system interroga--host, --build, --prefix, and setting srcdir, builddir, and EXEXT. |
| 106 | # |
| 107 | # It naming convention, where searchisys/type.h defines HAVE_SYS_TYPES_H |
| 108 | # |
| 109 | # It defines the fol--prefix unless overridden by the module-optionsation and options |
| 110 | # such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. |
| 111 | # |
| 112 | # It also support the "feature" naming convention, where searching |
| 113 | # for a feature such as 'sys/type => ines the followins to '$defaultprefix overridden by the user: |
| 114 | # |
| 115 | ## datadir |
| 116 | ## sysconfdir |
| 117 | ## sharedstatedir |
| 118 | ## localstatedir |
| 119 | ## infodir |
| 120 | ## mandir |
| 121 | ## includreadfile $infileAnd less common ones too |
| 122 | , 'buil \${prefix} |
| 123 | define define define libexecdir [get-env ] |
| 124 | define datadir \${prefix}/share |
| 125 | ] |
| 126 | define define localstatedir [get-env localvar] |
| 127 | define define infodir [get-env s: |
| 128 | # |
| 129 | # This module supports c# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ |
| 130 | # All rights rese |
+21
| --- a/autosetup/test-tclsh | ||
| +++ b/autosetup/test-tclsh | ||
| @@ -0,0 +1,21 @@ | ||
| 1 | +# A small Tcl script to verify that the chosen | |
| 2 | +# interpreter works. Sometimes we might e.g. pick up | |
| 3 | +# an interpreter for a different arch. | |
| 4 | +# Outputs the full path to the interpreter | |
| 5 | + | |
| 6 | +if {[catch {info version} version] == 0} { | |
| 7 | + # This is Jim Tcl | |
| 8 | + if {$version >= 0.70} { | |
| 9 | + # Ensure that rege | |
| 10 | + # Older versions of jimsh mayinfo patchlevel]]} { | |
| 11 | + puts [info nameofexecutable] | |
| 12 | + exit 0 | |
| 13 | + } | |
| 14 | +} | |
| 15 | +exit 1 | |
| 16 | +puts [file join [p] | |
| 17 | + exit 0 | |
| 18 | + } | |
| 19 | +} elseif {[catch {info tclversion} version] == 0} { | |
| 20 | + if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { | |
| 21 | + puts [info nameofexecut |
| --- a/autosetup/test-tclsh | |
| +++ b/autosetup/test-tclsh | |
| @@ -0,0 +1,21 @@ | |
| --- a/autosetup/test-tclsh | |
| +++ b/autosetup/test-tclsh | |
| @@ -0,0 +1,21 @@ | |
| 1 | # A small Tcl script to verify that the chosen |
| 2 | # interpreter works. Sometimes we might e.g. pick up |
| 3 | # an interpreter for a different arch. |
| 4 | # Outputs the full path to the interpreter |
| 5 | |
| 6 | if {[catch {info version} version] == 0} { |
| 7 | # This is Jim Tcl |
| 8 | if {$version >= 0.70} { |
| 9 | # Ensure that rege |
| 10 | # Older versions of jimsh mayinfo patchlevel]]} { |
| 11 | puts [info nameofexecutable] |
| 12 | exit 0 |
| 13 | } |
| 14 | } |
| 15 | exit 1 |
| 16 | puts [file join [p] |
| 17 | exit 0 |
| 18 | } |
| 19 | } elseif {[catch {info tclversion} version] == 0} { |
| 20 | if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { |
| 21 | puts [info nameofexecut |
+3
| --- a/configure | ||
| +++ b/configure | ||
| @@ -0,0 +1,3 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +dir=autosetup" | |
| 3 | +# exec `"$dir/find-tcl" || echo false` |
| --- a/configure | |
| +++ b/configure | |
| @@ -0,0 +1,3 @@ | |
| --- a/configure | |
| +++ b/configure | |
| @@ -0,0 +1,3 @@ | |
| 1 | #!/bin/sh |
| 2 | dir=autosetup" |
| 3 | # exec `"$dir/find-tcl" || echo false` |
+51
-32
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -176,10 +176,47 @@ | ||
| 176 | 176 | db_end_transaction(0); |
| 177 | 177 | |
| 178 | 178 | /* Do an autosync push, if requested */ |
| 179 | 179 | autosync(AUTOSYNC_PUSH); |
| 180 | 180 | } |
| 181 | + | |
| 182 | +/* | |
| 183 | +** Prepare a query that will list all branches. | |
| 184 | +*/ | |
| 185 | +static void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){ | |
| 186 | + if( showClosed ){ | |
| 187 | + db_prepare(pQuery, | |
| 188 | + "SELECT value FROM tagxref" | |
| 189 | + " WHERE tagid=%d AND value NOT NULL " | |
| 190 | + "EXCEPT " | |
| 191 | + "SELECT value FROM tagxref" | |
| 192 | + " WHERE tagid=%d" | |
| 193 | + " AND rid IN leaf" | |
| 194 | + " AND NOT %z" | |
| 195 | + " ORDER BY value COLLATE nocase /*sort*/", | |
| 196 | + TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") | |
| 197 | + ); | |
| 198 | + }else if( showAll ){ | |
| 199 | + db_prepare(pQuery, | |
| 200 | + "SELECT DISTINCT value FROM tagxref" | |
| 201 | + " WHERE tagid=%d AND value NOT NULL" | |
| 202 | + " AND rid IN leaf" | |
| 203 | + " ORDER BY value COLLATE nocase /*sort*/", | |
| 204 | + TAG_BRANCH | |
| 205 | + ); | |
| 206 | + }else{ | |
| 207 | + db_prepare(pQuery, | |
| 208 | + "SELECT DISTINCT value FROM tagxref" | |
| 209 | + " WHERE tagid=%d AND value NOT NULL" | |
| 210 | + " AND rid IN leaf" | |
| 211 | + " AND NOT %z" | |
| 212 | + " ORDER BY value COLLATE nocase /*sort*/", | |
| 213 | + TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") | |
| 214 | + ); | |
| 215 | + } | |
| 216 | +} | |
| 217 | + | |
| 181 | 218 | |
| 182 | 219 | /* |
| 183 | 220 | ** COMMAND: branch |
| 184 | 221 | ** |
| 185 | 222 | ** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE? |
| @@ -194,11 +231,12 @@ | ||
| 194 | 231 | ** --private option makes the branch private. |
| 195 | 232 | ** |
| 196 | 233 | ** %fossil branch list |
| 197 | 234 | ** %fossil branch ls |
| 198 | 235 | ** |
| 199 | -** List all branches | |
| 236 | +** List all branches. Use --all or --closed to list all branches | |
| 237 | +** or closed branches. The default is to show only open branches. | |
| 200 | 238 | ** |
| 201 | 239 | */ |
| 202 | 240 | void branch_cmd(void){ |
| 203 | 241 | int n; |
| 204 | 242 | const char *zCmd = "list"; |
| @@ -212,24 +250,19 @@ | ||
| 212 | 250 | branch_new(); |
| 213 | 251 | }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){ |
| 214 | 252 | Stmt q; |
| 215 | 253 | int vid; |
| 216 | 254 | char *zCurrent = 0; |
| 255 | + int showAll = find_option("all",0,0)!=0; | |
| 256 | + int showClosed = find_option("closed",0,0)!=0; | |
| 217 | 257 | |
| 218 | 258 | if( g.localOpen ){ |
| 219 | 259 | vid = db_lget_int("checkout", 0); |
| 220 | 260 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 221 | 261 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 222 | 262 | } |
| 223 | - db_prepare(&q, | |
| 224 | - "SELECT DISTINCT value FROM tagxref" | |
| 225 | - " WHERE tagid=%d AND value NOT NULL" | |
| 226 | - " AND rid IN leaf" | |
| 227 | - " AND NOT %z" | |
| 228 | - " ORDER BY value /*sort*/", | |
| 229 | - TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") | |
| 230 | - ); | |
| 263 | + prepareBranchQuery(&q, showAll, showClosed); | |
| 231 | 264 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | 265 | const char *zBr = db_column_text(&q, 0); |
| 233 | 266 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 234 | 267 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 235 | 268 | } |
| @@ -247,19 +280,26 @@ | ||
| 247 | 280 | */ |
| 248 | 281 | void brlist_page(void){ |
| 249 | 282 | Stmt q; |
| 250 | 283 | int cnt; |
| 251 | 284 | int showClosed = P("closed")!=0; |
| 285 | + int showAll = P("all")!=0; | |
| 252 | 286 | |
| 253 | 287 | login_check_credentials(); |
| 254 | 288 | if( !g.okRead ){ login_needed(); return; } |
| 255 | 289 | |
| 256 | - style_header(showClosed ? "Closed Branches" : "Open Branches"); | |
| 290 | + style_header(showClosed ? "Closed Branches" : | |
| 291 | + showAll ? "All Branches" : "Open Branches"); | |
| 257 | 292 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 258 | 293 | if( showClosed ){ |
| 294 | + style_submenu_element("All", "All", "brlist?all"); | |
| 295 | + style_submenu_element("Open","Open","brlist"); | |
| 296 | + }else if( showAll ){ | |
| 297 | + style_submenu_element("Closed", "Closed", "brlist?closed"); | |
| 259 | 298 | style_submenu_element("Open","Open","brlist"); |
| 260 | 299 | }else{ |
| 300 | + style_submenu_element("All", "All", "brlist?all"); | |
| 261 | 301 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 262 | 302 | } |
| 263 | 303 | login_anonymous_available(); |
| 264 | 304 | style_sidebox_begin("Nomenclature:", "33%"); |
| 265 | 305 | @ <ol> |
| @@ -275,33 +315,12 @@ | ||
| 275 | 315 | @ Closed branches are fixed and do not change (unless they are first |
| 276 | 316 | @ reopened)</li> |
| 277 | 317 | @ </ol> |
| 278 | 318 | style_sidebox_end(); |
| 279 | 319 | |
| 320 | + prepareBranchQuery(&q, showAll, showClosed); | |
| 280 | 321 | cnt = 0; |
| 281 | - if( showClosed ){ | |
| 282 | - db_prepare(&q, | |
| 283 | - "SELECT value FROM tagxref" | |
| 284 | - " WHERE tagid=%d AND value NOT NULL " | |
| 285 | - "EXCEPT " | |
| 286 | - "SELECT value FROM tagxref" | |
| 287 | - " WHERE tagid=%d" | |
| 288 | - " AND rid IN leaf" | |
| 289 | - " AND NOT %z" | |
| 290 | - " ORDER BY value /*sort*/", | |
| 291 | - TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") | |
| 292 | - ); | |
| 293 | - }else{ | |
| 294 | - db_prepare(&q, | |
| 295 | - "SELECT DISTINCT value FROM tagxref" | |
| 296 | - " WHERE tagid=%d AND value NOT NULL" | |
| 297 | - " AND rid IN leaf" | |
| 298 | - " AND NOT %z" | |
| 299 | - " ORDER BY value /*sort*/", | |
| 300 | - TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") | |
| 301 | - ); | |
| 302 | - } | |
| 303 | 322 | while( db_step(&q)==SQLITE_ROW ){ |
| 304 | 323 | const char *zBr = db_column_text(&q, 0); |
| 305 | 324 | if( cnt==0 ){ |
| 306 | 325 | if( showClosed ){ |
| 307 | 326 | @ <h2>Closed Branches:</h2> |
| 308 | 327 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,10 +176,47 @@ | |
| 176 | db_end_transaction(0); |
| 177 | |
| 178 | /* Do an autosync push, if requested */ |
| 179 | autosync(AUTOSYNC_PUSH); |
| 180 | } |
| 181 | |
| 182 | /* |
| 183 | ** COMMAND: branch |
| 184 | ** |
| 185 | ** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE? |
| @@ -194,11 +231,12 @@ | |
| 194 | ** --private option makes the branch private. |
| 195 | ** |
| 196 | ** %fossil branch list |
| 197 | ** %fossil branch ls |
| 198 | ** |
| 199 | ** List all branches |
| 200 | ** |
| 201 | */ |
| 202 | void branch_cmd(void){ |
| 203 | int n; |
| 204 | const char *zCmd = "list"; |
| @@ -212,24 +250,19 @@ | |
| 212 | branch_new(); |
| 213 | }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){ |
| 214 | Stmt q; |
| 215 | int vid; |
| 216 | char *zCurrent = 0; |
| 217 | |
| 218 | if( g.localOpen ){ |
| 219 | vid = db_lget_int("checkout", 0); |
| 220 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 221 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 222 | } |
| 223 | db_prepare(&q, |
| 224 | "SELECT DISTINCT value FROM tagxref" |
| 225 | " WHERE tagid=%d AND value NOT NULL" |
| 226 | " AND rid IN leaf" |
| 227 | " AND NOT %z" |
| 228 | " ORDER BY value /*sort*/", |
| 229 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 230 | ); |
| 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | const char *zBr = db_column_text(&q, 0); |
| 233 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 234 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 235 | } |
| @@ -247,19 +280,26 @@ | |
| 247 | */ |
| 248 | void brlist_page(void){ |
| 249 | Stmt q; |
| 250 | int cnt; |
| 251 | int showClosed = P("closed")!=0; |
| 252 | |
| 253 | login_check_credentials(); |
| 254 | if( !g.okRead ){ login_needed(); return; } |
| 255 | |
| 256 | style_header(showClosed ? "Closed Branches" : "Open Branches"); |
| 257 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 258 | if( showClosed ){ |
| 259 | style_submenu_element("Open","Open","brlist"); |
| 260 | }else{ |
| 261 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 262 | } |
| 263 | login_anonymous_available(); |
| 264 | style_sidebox_begin("Nomenclature:", "33%"); |
| 265 | @ <ol> |
| @@ -275,33 +315,12 @@ | |
| 275 | @ Closed branches are fixed and do not change (unless they are first |
| 276 | @ reopened)</li> |
| 277 | @ </ol> |
| 278 | style_sidebox_end(); |
| 279 | |
| 280 | cnt = 0; |
| 281 | if( showClosed ){ |
| 282 | db_prepare(&q, |
| 283 | "SELECT value FROM tagxref" |
| 284 | " WHERE tagid=%d AND value NOT NULL " |
| 285 | "EXCEPT " |
| 286 | "SELECT value FROM tagxref" |
| 287 | " WHERE tagid=%d" |
| 288 | " AND rid IN leaf" |
| 289 | " AND NOT %z" |
| 290 | " ORDER BY value /*sort*/", |
| 291 | TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 292 | ); |
| 293 | }else{ |
| 294 | db_prepare(&q, |
| 295 | "SELECT DISTINCT value FROM tagxref" |
| 296 | " WHERE tagid=%d AND value NOT NULL" |
| 297 | " AND rid IN leaf" |
| 298 | " AND NOT %z" |
| 299 | " ORDER BY value /*sort*/", |
| 300 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 301 | ); |
| 302 | } |
| 303 | while( db_step(&q)==SQLITE_ROW ){ |
| 304 | const char *zBr = db_column_text(&q, 0); |
| 305 | if( cnt==0 ){ |
| 306 | if( showClosed ){ |
| 307 | @ <h2>Closed Branches:</h2> |
| 308 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,10 +176,47 @@ | |
| 176 | db_end_transaction(0); |
| 177 | |
| 178 | /* Do an autosync push, if requested */ |
| 179 | autosync(AUTOSYNC_PUSH); |
| 180 | } |
| 181 | |
| 182 | /* |
| 183 | ** Prepare a query that will list all branches. |
| 184 | */ |
| 185 | static void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){ |
| 186 | if( showClosed ){ |
| 187 | db_prepare(pQuery, |
| 188 | "SELECT value FROM tagxref" |
| 189 | " WHERE tagid=%d AND value NOT NULL " |
| 190 | "EXCEPT " |
| 191 | "SELECT value FROM tagxref" |
| 192 | " WHERE tagid=%d" |
| 193 | " AND rid IN leaf" |
| 194 | " AND NOT %z" |
| 195 | " ORDER BY value COLLATE nocase /*sort*/", |
| 196 | TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 197 | ); |
| 198 | }else if( showAll ){ |
| 199 | db_prepare(pQuery, |
| 200 | "SELECT DISTINCT value FROM tagxref" |
| 201 | " WHERE tagid=%d AND value NOT NULL" |
| 202 | " AND rid IN leaf" |
| 203 | " ORDER BY value COLLATE nocase /*sort*/", |
| 204 | TAG_BRANCH |
| 205 | ); |
| 206 | }else{ |
| 207 | db_prepare(pQuery, |
| 208 | "SELECT DISTINCT value FROM tagxref" |
| 209 | " WHERE tagid=%d AND value NOT NULL" |
| 210 | " AND rid IN leaf" |
| 211 | " AND NOT %z" |
| 212 | " ORDER BY value COLLATE nocase /*sort*/", |
| 213 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 214 | ); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | |
| 219 | /* |
| 220 | ** COMMAND: branch |
| 221 | ** |
| 222 | ** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE? |
| @@ -194,11 +231,12 @@ | |
| 231 | ** --private option makes the branch private. |
| 232 | ** |
| 233 | ** %fossil branch list |
| 234 | ** %fossil branch ls |
| 235 | ** |
| 236 | ** List all branches. Use --all or --closed to list all branches |
| 237 | ** or closed branches. The default is to show only open branches. |
| 238 | ** |
| 239 | */ |
| 240 | void branch_cmd(void){ |
| 241 | int n; |
| 242 | const char *zCmd = "list"; |
| @@ -212,24 +250,19 @@ | |
| 250 | branch_new(); |
| 251 | }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){ |
| 252 | Stmt q; |
| 253 | int vid; |
| 254 | char *zCurrent = 0; |
| 255 | int showAll = find_option("all",0,0)!=0; |
| 256 | int showClosed = find_option("closed",0,0)!=0; |
| 257 | |
| 258 | if( g.localOpen ){ |
| 259 | vid = db_lget_int("checkout", 0); |
| 260 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 261 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 262 | } |
| 263 | prepareBranchQuery(&q, showAll, showClosed); |
| 264 | while( db_step(&q)==SQLITE_ROW ){ |
| 265 | const char *zBr = db_column_text(&q, 0); |
| 266 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 267 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 268 | } |
| @@ -247,19 +280,26 @@ | |
| 280 | */ |
| 281 | void brlist_page(void){ |
| 282 | Stmt q; |
| 283 | int cnt; |
| 284 | int showClosed = P("closed")!=0; |
| 285 | int showAll = P("all")!=0; |
| 286 | |
| 287 | login_check_credentials(); |
| 288 | if( !g.okRead ){ login_needed(); return; } |
| 289 | |
| 290 | style_header(showClosed ? "Closed Branches" : |
| 291 | showAll ? "All Branches" : "Open Branches"); |
| 292 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 293 | if( showClosed ){ |
| 294 | style_submenu_element("All", "All", "brlist?all"); |
| 295 | style_submenu_element("Open","Open","brlist"); |
| 296 | }else if( showAll ){ |
| 297 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 298 | style_submenu_element("Open","Open","brlist"); |
| 299 | }else{ |
| 300 | style_submenu_element("All", "All", "brlist?all"); |
| 301 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 302 | } |
| 303 | login_anonymous_available(); |
| 304 | style_sidebox_begin("Nomenclature:", "33%"); |
| 305 | @ <ol> |
| @@ -275,33 +315,12 @@ | |
| 315 | @ Closed branches are fixed and do not change (unless they are first |
| 316 | @ reopened)</li> |
| 317 | @ </ol> |
| 318 | style_sidebox_end(); |
| 319 | |
| 320 | prepareBranchQuery(&q, showAll, showClosed); |
| 321 | cnt = 0; |
| 322 | while( db_step(&q)==SQLITE_ROW ){ |
| 323 | const char *zBr = db_column_text(&q, 0); |
| 324 | if( cnt==0 ){ |
| 325 | if( showClosed ){ |
| 326 | @ <h2>Closed Branches:</h2> |
| 327 |
+1
-1
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -267,11 +267,11 @@ | ||
| 267 | 267 | if( zFN[0]=='/' ){ |
| 268 | 268 | zFN++; |
| 269 | 269 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 270 | 270 | }else if( zCI ){ |
| 271 | 271 | const char *zUuid = db_column_text(&q, 1); |
| 272 | - @ <li><a href="%s(g.zTop)/artifact?name=%s(zUuid)">%h(zFN)</a></li> | |
| 272 | + @ <li><a href="%s(g.zTop)/artifact/%s(zUuid)">%h(zFN)</a></li> | |
| 273 | 273 | }else{ |
| 274 | 274 | @ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) |
| 275 | 275 | @ </a></li> |
| 276 | 276 | } |
| 277 | 277 | } |
| 278 | 278 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -267,11 +267,11 @@ | |
| 267 | if( zFN[0]=='/' ){ |
| 268 | zFN++; |
| 269 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 270 | }else if( zCI ){ |
| 271 | const char *zUuid = db_column_text(&q, 1); |
| 272 | @ <li><a href="%s(g.zTop)/artifact?name=%s(zUuid)">%h(zFN)</a></li> |
| 273 | }else{ |
| 274 | @ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) |
| 275 | @ </a></li> |
| 276 | } |
| 277 | } |
| 278 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -267,11 +267,11 @@ | |
| 267 | if( zFN[0]=='/' ){ |
| 268 | zFN++; |
| 269 | @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li> |
| 270 | }else if( zCI ){ |
| 271 | const char *zUuid = db_column_text(&q, 1); |
| 272 | @ <li><a href="%s(g.zTop)/artifact/%s(zUuid)">%h(zFN)</a></li> |
| 273 | }else{ |
| 274 | @ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN) |
| 275 | @ </a></li> |
| 276 | } |
| 277 | } |
| 278 |
+12
-2
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -353,10 +353,11 @@ | ||
| 353 | 353 | if( size>0 ){ |
| 354 | 354 | fwrite(blob_buffer(&cgiContent[i]), 1, size, g.httpOut); |
| 355 | 355 | } |
| 356 | 356 | } |
| 357 | 357 | } |
| 358 | + fflush(g.httpOut); | |
| 358 | 359 | CGIDEBUG(("DONE\n")); |
| 359 | 360 | } |
| 360 | 361 | |
| 361 | 362 | /* |
| 362 | 363 | ** Do a redirect request to the URL given in the argument. |
| @@ -887,17 +888,26 @@ | ||
| 887 | 888 | } |
| 888 | 889 | |
| 889 | 890 | /* |
| 890 | 891 | ** Print all query parameters on standard output. Format the |
| 891 | 892 | ** parameters as HTML. This is used for testing and debugging. |
| 893 | +** Release builds omit the values of the cookies to avoid defeating | |
| 894 | +** the purpose of setting HttpOnly cookies. | |
| 892 | 895 | */ |
| 893 | 896 | void cgi_print_all(void){ |
| 894 | 897 | int i; |
| 898 | + int showAll = 0; | |
| 899 | +#ifdef FOSSIL_DEBUG | |
| 900 | + /* Show the values of cookies in debug mode. */ | |
| 901 | + showAll = 1; | |
| 902 | +#endif | |
| 895 | 903 | cgi_parameter("",""); /* Force the parameters into sorted order */ |
| 896 | 904 | for(i=0; i<nUsedQP; i++){ |
| 897 | - cgi_printf("%s = %s <br />\n", | |
| 898 | - htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1)); | |
| 905 | + if( showAll || (fossil_stricmp("HTTP_COOKIE",aParamQP[i].zName)!=0 && fossil_strnicmp("fossil-",aParamQP[i].zName,7)!=0) ){ | |
| 906 | + cgi_printf("%s = %s <br />\n", | |
| 907 | + htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1)); | |
| 908 | + } | |
| 899 | 909 | } |
| 900 | 910 | } |
| 901 | 911 | |
| 902 | 912 | /* |
| 903 | 913 | ** This routine works like "printf" except that it has the |
| 904 | 914 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -353,10 +353,11 @@ | |
| 353 | if( size>0 ){ |
| 354 | fwrite(blob_buffer(&cgiContent[i]), 1, size, g.httpOut); |
| 355 | } |
| 356 | } |
| 357 | } |
| 358 | CGIDEBUG(("DONE\n")); |
| 359 | } |
| 360 | |
| 361 | /* |
| 362 | ** Do a redirect request to the URL given in the argument. |
| @@ -887,17 +888,26 @@ | |
| 887 | } |
| 888 | |
| 889 | /* |
| 890 | ** Print all query parameters on standard output. Format the |
| 891 | ** parameters as HTML. This is used for testing and debugging. |
| 892 | */ |
| 893 | void cgi_print_all(void){ |
| 894 | int i; |
| 895 | cgi_parameter("",""); /* Force the parameters into sorted order */ |
| 896 | for(i=0; i<nUsedQP; i++){ |
| 897 | cgi_printf("%s = %s <br />\n", |
| 898 | htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1)); |
| 899 | } |
| 900 | } |
| 901 | |
| 902 | /* |
| 903 | ** This routine works like "printf" except that it has the |
| 904 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -353,10 +353,11 @@ | |
| 353 | if( size>0 ){ |
| 354 | fwrite(blob_buffer(&cgiContent[i]), 1, size, g.httpOut); |
| 355 | } |
| 356 | } |
| 357 | } |
| 358 | fflush(g.httpOut); |
| 359 | CGIDEBUG(("DONE\n")); |
| 360 | } |
| 361 | |
| 362 | /* |
| 363 | ** Do a redirect request to the URL given in the argument. |
| @@ -887,17 +888,26 @@ | |
| 888 | } |
| 889 | |
| 890 | /* |
| 891 | ** Print all query parameters on standard output. Format the |
| 892 | ** parameters as HTML. This is used for testing and debugging. |
| 893 | ** Release builds omit the values of the cookies to avoid defeating |
| 894 | ** the purpose of setting HttpOnly cookies. |
| 895 | */ |
| 896 | void cgi_print_all(void){ |
| 897 | int i; |
| 898 | int showAll = 0; |
| 899 | #ifdef FOSSIL_DEBUG |
| 900 | /* Show the values of cookies in debug mode. */ |
| 901 | showAll = 1; |
| 902 | #endif |
| 903 | cgi_parameter("",""); /* Force the parameters into sorted order */ |
| 904 | for(i=0; i<nUsedQP; i++){ |
| 905 | if( showAll || (fossil_stricmp("HTTP_COOKIE",aParamQP[i].zName)!=0 && fossil_strnicmp("fossil-",aParamQP[i].zName,7)!=0) ){ |
| 906 | cgi_printf("%s = %s <br />\n", |
| 907 | htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1)); |
| 908 | } |
| 909 | } |
| 910 | } |
| 911 | |
| 912 | /* |
| 913 | ** This routine works like "printf" except that it has the |
| 914 |
+8
-3
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -43,10 +43,11 @@ | ||
| 43 | 43 | ** |
| 44 | 44 | */ |
| 45 | 45 | void clone_cmd(void){ |
| 46 | 46 | char *zPassword; |
| 47 | 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | + const char *zPw; /* The user clone password */ | |
| 48 | 49 | int nErr = 0; |
| 49 | 50 | int bPrivate; /* Also clone private branches */ |
| 50 | 51 | |
| 51 | 52 | bPrivate = find_option("private",0,0)!=0; |
| 52 | 53 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | ||
| 77 | 78 | "DELETE FROM blob WHERE rid IN private;" |
| 78 | 79 | "DELETE FROM delta wHERE rid IN private;" |
| 79 | 80 | "DELETE FROM private;" |
| 80 | 81 | ); |
| 81 | 82 | shun_artifacts(); |
| 82 | - g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); | |
| 83 | - if( g.zLogin==0 ){ | |
| 84 | - db_create_default_users(1,zDefaultUser); | |
| 83 | + db_create_default_users(1, zDefaultUser); | |
| 84 | + if( zDefaultUser ){ | |
| 85 | + g.zLogin = zDefaultUser; | |
| 86 | + }else{ | |
| 87 | + g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); | |
| 85 | 88 | } |
| 86 | 89 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 87 | 90 | }else{ |
| 88 | 91 | db_create_repository(g.argv[3]); |
| 89 | 92 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | ||
| 125 | 128 | rebuild_db(0, 1, 0); |
| 126 | 129 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 127 | 130 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 128 | 131 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 129 | 132 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 133 | + zPw = g.urlPasswd; | |
| 134 | + if( !g.dontKeepUrl && zPw) db_set("last-sync-pw", obscure(zPw), 0); | |
| 130 | 135 | db_end_transaction(0); |
| 131 | 136 | } |
| 132 | 137 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -43,10 +43,11 @@ | |
| 43 | ** |
| 44 | */ |
| 45 | void clone_cmd(void){ |
| 46 | char *zPassword; |
| 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | int nErr = 0; |
| 49 | int bPrivate; /* Also clone private branches */ |
| 50 | |
| 51 | bPrivate = find_option("private",0,0)!=0; |
| 52 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | |
| 77 | "DELETE FROM blob WHERE rid IN private;" |
| 78 | "DELETE FROM delta wHERE rid IN private;" |
| 79 | "DELETE FROM private;" |
| 80 | ); |
| 81 | shun_artifacts(); |
| 82 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 83 | if( g.zLogin==0 ){ |
| 84 | db_create_default_users(1,zDefaultUser); |
| 85 | } |
| 86 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 87 | }else{ |
| 88 | db_create_repository(g.argv[3]); |
| 89 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | |
| 125 | rebuild_db(0, 1, 0); |
| 126 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 127 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 128 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 129 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 130 | db_end_transaction(0); |
| 131 | } |
| 132 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -43,10 +43,11 @@ | |
| 43 | ** |
| 44 | */ |
| 45 | void clone_cmd(void){ |
| 46 | char *zPassword; |
| 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | const char *zPw; /* The user clone password */ |
| 49 | int nErr = 0; |
| 50 | int bPrivate; /* Also clone private branches */ |
| 51 | |
| 52 | bPrivate = find_option("private",0,0)!=0; |
| 53 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | |
| 78 | "DELETE FROM blob WHERE rid IN private;" |
| 79 | "DELETE FROM delta wHERE rid IN private;" |
| 80 | "DELETE FROM private;" |
| 81 | ); |
| 82 | shun_artifacts(); |
| 83 | db_create_default_users(1, zDefaultUser); |
| 84 | if( zDefaultUser ){ |
| 85 | g.zLogin = zDefaultUser; |
| 86 | }else{ |
| 87 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 88 | } |
| 89 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 90 | }else{ |
| 91 | db_create_repository(g.argv[3]); |
| 92 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | |
| 128 | rebuild_db(0, 1, 0); |
| 129 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 130 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 131 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 132 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 133 | zPw = g.urlPasswd; |
| 134 | if( !g.dontKeepUrl && zPw) db_set("last-sync-pw", obscure(zPw), 0); |
| 135 | db_end_transaction(0); |
| 136 | } |
| 137 |
+8
-3
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -43,10 +43,11 @@ | ||
| 43 | 43 | ** |
| 44 | 44 | */ |
| 45 | 45 | void clone_cmd(void){ |
| 46 | 46 | char *zPassword; |
| 47 | 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | + const char *zPw; /* The user clone password */ | |
| 48 | 49 | int nErr = 0; |
| 49 | 50 | int bPrivate; /* Also clone private branches */ |
| 50 | 51 | |
| 51 | 52 | bPrivate = find_option("private",0,0)!=0; |
| 52 | 53 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | ||
| 77 | 78 | "DELETE FROM blob WHERE rid IN private;" |
| 78 | 79 | "DELETE FROM delta wHERE rid IN private;" |
| 79 | 80 | "DELETE FROM private;" |
| 80 | 81 | ); |
| 81 | 82 | shun_artifacts(); |
| 82 | - g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); | |
| 83 | - if( g.zLogin==0 ){ | |
| 84 | - db_create_default_users(1,zDefaultUser); | |
| 83 | + db_create_default_users(1, zDefaultUser); | |
| 84 | + if( zDefaultUser ){ | |
| 85 | + g.zLogin = zDefaultUser; | |
| 86 | + }else{ | |
| 87 | + g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); | |
| 85 | 88 | } |
| 86 | 89 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 87 | 90 | }else{ |
| 88 | 91 | db_create_repository(g.argv[3]); |
| 89 | 92 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | ||
| 125 | 128 | rebuild_db(0, 1, 0); |
| 126 | 129 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 127 | 130 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 128 | 131 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 129 | 132 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 133 | + zPw = g.urlPasswd; | |
| 134 | + if( !g.dontKeepUrl && zPw) db_set("last-sync-pw", obscure(zPw), 0); | |
| 130 | 135 | db_end_transaction(0); |
| 131 | 136 | } |
| 132 | 137 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -43,10 +43,11 @@ | |
| 43 | ** |
| 44 | */ |
| 45 | void clone_cmd(void){ |
| 46 | char *zPassword; |
| 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | int nErr = 0; |
| 49 | int bPrivate; /* Also clone private branches */ |
| 50 | |
| 51 | bPrivate = find_option("private",0,0)!=0; |
| 52 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | |
| 77 | "DELETE FROM blob WHERE rid IN private;" |
| 78 | "DELETE FROM delta wHERE rid IN private;" |
| 79 | "DELETE FROM private;" |
| 80 | ); |
| 81 | shun_artifacts(); |
| 82 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 83 | if( g.zLogin==0 ){ |
| 84 | db_create_default_users(1,zDefaultUser); |
| 85 | } |
| 86 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 87 | }else{ |
| 88 | db_create_repository(g.argv[3]); |
| 89 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | |
| 125 | rebuild_db(0, 1, 0); |
| 126 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 127 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 128 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 129 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 130 | db_end_transaction(0); |
| 131 | } |
| 132 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -43,10 +43,11 @@ | |
| 43 | ** |
| 44 | */ |
| 45 | void clone_cmd(void){ |
| 46 | char *zPassword; |
| 47 | const char *zDefaultUser; /* Optional name of the default user */ |
| 48 | const char *zPw; /* The user clone password */ |
| 49 | int nErr = 0; |
| 50 | int bPrivate; /* Also clone private branches */ |
| 51 | |
| 52 | bPrivate = find_option("private",0,0)!=0; |
| 53 | url_proxy_options(); |
| @@ -77,13 +78,15 @@ | |
| 78 | "DELETE FROM blob WHERE rid IN private;" |
| 79 | "DELETE FROM delta wHERE rid IN private;" |
| 80 | "DELETE FROM private;" |
| 81 | ); |
| 82 | shun_artifacts(); |
| 83 | db_create_default_users(1, zDefaultUser); |
| 84 | if( zDefaultUser ){ |
| 85 | g.zLogin = zDefaultUser; |
| 86 | }else{ |
| 87 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 88 | } |
| 89 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 90 | }else{ |
| 91 | db_create_repository(g.argv[3]); |
| 92 | db_open_repository(g.argv[3]); |
| @@ -125,7 +128,9 @@ | |
| 128 | rebuild_db(0, 1, 0); |
| 129 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 130 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 131 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 132 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 133 | zPw = g.urlPasswd; |
| 134 | if( !g.dontKeepUrl && zPw) db_set("last-sync-pw", obscure(zPw), 0); |
| 135 | db_end_transaction(0); |
| 136 | } |
| 137 |
+5
-1
| --- src/config.h | ||
| +++ src/config.h | ||
| @@ -24,10 +24,14 @@ | ||
| 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 | +#ifdef HAVE_AUTOCONFIG_H | |
| 31 | +#include "autoconfig.h" | |
| 32 | +#endif | |
| 29 | 33 | |
| 30 | 34 | #ifndef _RC_COMPILE_ |
| 31 | 35 | |
| 32 | 36 | /* |
| 33 | 37 | ** System header files used by all modules |
| @@ -85,11 +89,11 @@ | ||
| 85 | 89 | #include "sqlite3.h" |
| 86 | 90 | |
| 87 | 91 | /* |
| 88 | 92 | ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. |
| 89 | 93 | */ |
| 90 | -#if defined(__sun__) || defined(sun) | |
| 94 | +#if HAVE_GETPASSPHRASE | |
| 91 | 95 | #define getpass getpassphrase |
| 92 | 96 | #endif |
| 93 | 97 | |
| 94 | 98 | /* |
| 95 | 99 | ** Typedef for a 64-bit integer |
| 96 | 100 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -24,10 +24,14 @@ | |
| 24 | #define _LARGE_FILE 1 |
| 25 | #ifndef _FILE_OFFSET_BITS |
| 26 | # define _FILE_OFFSET_BITS 64 |
| 27 | #endif |
| 28 | #define _LARGEFILE_SOURCE 1 |
| 29 | |
| 30 | #ifndef _RC_COMPILE_ |
| 31 | |
| 32 | /* |
| 33 | ** System header files used by all modules |
| @@ -85,11 +89,11 @@ | |
| 85 | #include "sqlite3.h" |
| 86 | |
| 87 | /* |
| 88 | ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. |
| 89 | */ |
| 90 | #if defined(__sun__) || defined(sun) |
| 91 | #define getpass getpassphrase |
| 92 | #endif |
| 93 | |
| 94 | /* |
| 95 | ** Typedef for a 64-bit integer |
| 96 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -24,10 +24,14 @@ | |
| 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 | #ifdef HAVE_AUTOCONFIG_H |
| 31 | #include "autoconfig.h" |
| 32 | #endif |
| 33 | |
| 34 | #ifndef _RC_COMPILE_ |
| 35 | |
| 36 | /* |
| 37 | ** System header files used by all modules |
| @@ -85,11 +89,11 @@ | |
| 89 | #include "sqlite3.h" |
| 90 | |
| 91 | /* |
| 92 | ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. |
| 93 | */ |
| 94 | #if HAVE_GETPASSPHRASE |
| 95 | #define getpass getpassphrase |
| 96 | #endif |
| 97 | |
| 98 | /* |
| 99 | ** Typedef for a 64-bit integer |
| 100 |
M
src/db.c
+9
-6
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -809,10 +809,11 @@ | ||
| 809 | 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | 810 | |
| 811 | 811 | if( g.localOpen) return 1; |
| 812 | 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | 813 | n = strlen(zPwd); |
| 814 | + if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; | |
| 814 | 815 | while( n>0 ){ |
| 815 | 816 | if( file_access(zPwd, W_OK) ) break; |
| 816 | 817 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 817 | 818 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 818 | 819 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | ||
| 1058 | 1059 | |
| 1059 | 1060 | /* |
| 1060 | 1061 | ** Create the default user accounts in the USER table. |
| 1061 | 1062 | */ |
| 1062 | 1063 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1063 | - const char *zUser; | |
| 1064 | - zUser = db_get("default-user", 0); | |
| 1064 | + const char *zUser = zDefaultUser; | |
| 1065 | 1065 | if( zUser==0 ){ |
| 1066 | - zUser = zDefaultUser; | |
| 1066 | + zUser = db_get("default-user", 0); | |
| 1067 | 1067 | } |
| 1068 | 1068 | if( zUser==0 ){ |
| 1069 | 1069 | #if defined(_WIN32) |
| 1070 | 1070 | zUser = getenv("USERNAME"); |
| 1071 | 1071 | #else |
| @@ -1074,12 +1074,15 @@ | ||
| 1074 | 1074 | } |
| 1075 | 1075 | if( zUser==0 ){ |
| 1076 | 1076 | zUser = "root"; |
| 1077 | 1077 | } |
| 1078 | 1078 | db_multi_exec( |
| 1079 | - "INSERT INTO user(login, pw, cap, info)" | |
| 1080 | - "VALUES(%Q,lower(hex(randomblob(3))),'s','')", zUser | |
| 1079 | + "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser | |
| 1080 | + ); | |
| 1081 | + db_multi_exec( | |
| 1082 | + "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))" | |
| 1083 | + " WHERE login=%Q", zUser | |
| 1081 | 1084 | ); |
| 1082 | 1085 | if( !setupUserOnly ){ |
| 1083 | 1086 | db_multi_exec( |
| 1084 | 1087 | "INSERT INTO user(login,pw,cap,info)" |
| 1085 | 1088 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | ||
| 1928 | 1931 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1929 | 1932 | }else{ |
| 1930 | 1933 | isManifest = 0; |
| 1931 | 1934 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1932 | 1935 | } |
| 1933 | - if( isManifest ){ | |
| 1936 | + if( isManifest && g.localOpen ){ | |
| 1934 | 1937 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1935 | 1938 | } |
| 1936 | 1939 | }else{ |
| 1937 | 1940 | usage("?PROPERTY? ?VALUE?"); |
| 1938 | 1941 | } |
| 1939 | 1942 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -809,10 +809,11 @@ | |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | n = strlen(zPwd); |
| 814 | while( n>0 ){ |
| 815 | if( file_access(zPwd, W_OK) ) break; |
| 816 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 817 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 818 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | |
| 1058 | |
| 1059 | /* |
| 1060 | ** Create the default user accounts in the USER table. |
| 1061 | */ |
| 1062 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1063 | const char *zUser; |
| 1064 | zUser = db_get("default-user", 0); |
| 1065 | if( zUser==0 ){ |
| 1066 | zUser = zDefaultUser; |
| 1067 | } |
| 1068 | if( zUser==0 ){ |
| 1069 | #if defined(_WIN32) |
| 1070 | zUser = getenv("USERNAME"); |
| 1071 | #else |
| @@ -1074,12 +1074,15 @@ | |
| 1074 | } |
| 1075 | if( zUser==0 ){ |
| 1076 | zUser = "root"; |
| 1077 | } |
| 1078 | db_multi_exec( |
| 1079 | "INSERT INTO user(login, pw, cap, info)" |
| 1080 | "VALUES(%Q,lower(hex(randomblob(3))),'s','')", zUser |
| 1081 | ); |
| 1082 | if( !setupUserOnly ){ |
| 1083 | db_multi_exec( |
| 1084 | "INSERT INTO user(login,pw,cap,info)" |
| 1085 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | |
| 1928 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1929 | }else{ |
| 1930 | isManifest = 0; |
| 1931 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1932 | } |
| 1933 | if( isManifest ){ |
| 1934 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1935 | } |
| 1936 | }else{ |
| 1937 | usage("?PROPERTY? ?VALUE?"); |
| 1938 | } |
| 1939 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -809,10 +809,11 @@ | |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | n = strlen(zPwd); |
| 814 | if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; |
| 815 | while( n>0 ){ |
| 816 | if( file_access(zPwd, W_OK) ) break; |
| 817 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 818 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 819 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | |
| 1059 | |
| 1060 | /* |
| 1061 | ** Create the default user accounts in the USER table. |
| 1062 | */ |
| 1063 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1064 | const char *zUser = zDefaultUser; |
| 1065 | if( zUser==0 ){ |
| 1066 | zUser = db_get("default-user", 0); |
| 1067 | } |
| 1068 | if( zUser==0 ){ |
| 1069 | #if defined(_WIN32) |
| 1070 | zUser = getenv("USERNAME"); |
| 1071 | #else |
| @@ -1074,12 +1074,15 @@ | |
| 1074 | } |
| 1075 | if( zUser==0 ){ |
| 1076 | zUser = "root"; |
| 1077 | } |
| 1078 | db_multi_exec( |
| 1079 | "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser |
| 1080 | ); |
| 1081 | db_multi_exec( |
| 1082 | "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))" |
| 1083 | " WHERE login=%Q", zUser |
| 1084 | ); |
| 1085 | if( !setupUserOnly ){ |
| 1086 | db_multi_exec( |
| 1087 | "INSERT INTO user(login,pw,cap,info)" |
| 1088 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | |
| 1931 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1932 | }else{ |
| 1933 | isManifest = 0; |
| 1934 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1935 | } |
| 1936 | if( isManifest && g.localOpen ){ |
| 1937 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1938 | } |
| 1939 | }else{ |
| 1940 | usage("?PROPERTY? ?VALUE?"); |
| 1941 | } |
| 1942 |
M
src/db.c
+9
-6
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -809,10 +809,11 @@ | ||
| 809 | 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | 810 | |
| 811 | 811 | if( g.localOpen) return 1; |
| 812 | 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | 813 | n = strlen(zPwd); |
| 814 | + if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; | |
| 814 | 815 | while( n>0 ){ |
| 815 | 816 | if( file_access(zPwd, W_OK) ) break; |
| 816 | 817 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 817 | 818 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 818 | 819 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | ||
| 1058 | 1059 | |
| 1059 | 1060 | /* |
| 1060 | 1061 | ** Create the default user accounts in the USER table. |
| 1061 | 1062 | */ |
| 1062 | 1063 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1063 | - const char *zUser; | |
| 1064 | - zUser = db_get("default-user", 0); | |
| 1064 | + const char *zUser = zDefaultUser; | |
| 1065 | 1065 | if( zUser==0 ){ |
| 1066 | - zUser = zDefaultUser; | |
| 1066 | + zUser = db_get("default-user", 0); | |
| 1067 | 1067 | } |
| 1068 | 1068 | if( zUser==0 ){ |
| 1069 | 1069 | #if defined(_WIN32) |
| 1070 | 1070 | zUser = getenv("USERNAME"); |
| 1071 | 1071 | #else |
| @@ -1074,12 +1074,15 @@ | ||
| 1074 | 1074 | } |
| 1075 | 1075 | if( zUser==0 ){ |
| 1076 | 1076 | zUser = "root"; |
| 1077 | 1077 | } |
| 1078 | 1078 | db_multi_exec( |
| 1079 | - "INSERT INTO user(login, pw, cap, info)" | |
| 1080 | - "VALUES(%Q,lower(hex(randomblob(3))),'s','')", zUser | |
| 1079 | + "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser | |
| 1080 | + ); | |
| 1081 | + db_multi_exec( | |
| 1082 | + "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))" | |
| 1083 | + " WHERE login=%Q", zUser | |
| 1081 | 1084 | ); |
| 1082 | 1085 | if( !setupUserOnly ){ |
| 1083 | 1086 | db_multi_exec( |
| 1084 | 1087 | "INSERT INTO user(login,pw,cap,info)" |
| 1085 | 1088 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | ||
| 1928 | 1931 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1929 | 1932 | }else{ |
| 1930 | 1933 | isManifest = 0; |
| 1931 | 1934 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1932 | 1935 | } |
| 1933 | - if( isManifest ){ | |
| 1936 | + if( isManifest && g.localOpen ){ | |
| 1934 | 1937 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1935 | 1938 | } |
| 1936 | 1939 | }else{ |
| 1937 | 1940 | usage("?PROPERTY? ?VALUE?"); |
| 1938 | 1941 | } |
| 1939 | 1942 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -809,10 +809,11 @@ | |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | n = strlen(zPwd); |
| 814 | while( n>0 ){ |
| 815 | if( file_access(zPwd, W_OK) ) break; |
| 816 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 817 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 818 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | |
| 1058 | |
| 1059 | /* |
| 1060 | ** Create the default user accounts in the USER table. |
| 1061 | */ |
| 1062 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1063 | const char *zUser; |
| 1064 | zUser = db_get("default-user", 0); |
| 1065 | if( zUser==0 ){ |
| 1066 | zUser = zDefaultUser; |
| 1067 | } |
| 1068 | if( zUser==0 ){ |
| 1069 | #if defined(_WIN32) |
| 1070 | zUser = getenv("USERNAME"); |
| 1071 | #else |
| @@ -1074,12 +1074,15 @@ | |
| 1074 | } |
| 1075 | if( zUser==0 ){ |
| 1076 | zUser = "root"; |
| 1077 | } |
| 1078 | db_multi_exec( |
| 1079 | "INSERT INTO user(login, pw, cap, info)" |
| 1080 | "VALUES(%Q,lower(hex(randomblob(3))),'s','')", zUser |
| 1081 | ); |
| 1082 | if( !setupUserOnly ){ |
| 1083 | db_multi_exec( |
| 1084 | "INSERT INTO user(login,pw,cap,info)" |
| 1085 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | |
| 1928 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1929 | }else{ |
| 1930 | isManifest = 0; |
| 1931 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1932 | } |
| 1933 | if( isManifest ){ |
| 1934 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1935 | } |
| 1936 | }else{ |
| 1937 | usage("?PROPERTY? ?VALUE?"); |
| 1938 | } |
| 1939 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -809,10 +809,11 @@ | |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | n = strlen(zPwd); |
| 814 | if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; |
| 815 | while( n>0 ){ |
| 816 | if( file_access(zPwd, W_OK) ) break; |
| 817 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 818 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 819 | if( isValidLocalDb(zPwd) ){ |
| @@ -1058,14 +1059,13 @@ | |
| 1059 | |
| 1060 | /* |
| 1061 | ** Create the default user accounts in the USER table. |
| 1062 | */ |
| 1063 | void db_create_default_users(int setupUserOnly, const char *zDefaultUser){ |
| 1064 | const char *zUser = zDefaultUser; |
| 1065 | if( zUser==0 ){ |
| 1066 | zUser = db_get("default-user", 0); |
| 1067 | } |
| 1068 | if( zUser==0 ){ |
| 1069 | #if defined(_WIN32) |
| 1070 | zUser = getenv("USERNAME"); |
| 1071 | #else |
| @@ -1074,12 +1074,15 @@ | |
| 1074 | } |
| 1075 | if( zUser==0 ){ |
| 1076 | zUser = "root"; |
| 1077 | } |
| 1078 | db_multi_exec( |
| 1079 | "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser |
| 1080 | ); |
| 1081 | db_multi_exec( |
| 1082 | "UPDATE user SET cap='s', pw=lower(hex(randomblob(3)))" |
| 1083 | " WHERE login=%Q", zUser |
| 1084 | ); |
| 1085 | if( !setupUserOnly ){ |
| 1086 | db_multi_exec( |
| 1087 | "INSERT INTO user(login,pw,cap,info)" |
| 1088 | " VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');" |
| @@ -1928,11 +1931,11 @@ | |
| 1931 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1932 | }else{ |
| 1933 | isManifest = 0; |
| 1934 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1935 | } |
| 1936 | if( isManifest && g.localOpen ){ |
| 1937 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1938 | } |
| 1939 | }else{ |
| 1940 | usage("?PROPERTY? ?VALUE?"); |
| 1941 | } |
| 1942 |
+11
-5
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -1213,12 +1213,18 @@ | ||
| 1213 | 1213 | } |
| 1214 | 1214 | |
| 1215 | 1215 | |
| 1216 | 1216 | /* |
| 1217 | 1217 | ** WEBPAGE: artifact |
| 1218 | -** URL: /artifact?name=ARTIFACTID | |
| 1218 | +** URL: /artifact/ARTIFACTID | |
| 1219 | 1219 | ** URL: /artifact?ci=CHECKIN&filename=PATH |
| 1220 | +** | |
| 1221 | +** Additional query parameters: | |
| 1222 | +** | |
| 1223 | +** ln - show line numbers | |
| 1224 | +** ln=N - highlight line number N | |
| 1225 | +** ln=M-N - highlight lines M through N inclusive | |
| 1220 | 1226 | ** |
| 1221 | 1227 | ** Show the complete content of a file identified by ARTIFACTID |
| 1222 | 1228 | ** as preformatted text. |
| 1223 | 1229 | */ |
| 1224 | 1230 | void artifact_page(void){ |
| @@ -1260,24 +1266,24 @@ | ||
| 1260 | 1266 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1261 | 1267 | if( zMime ){ |
| 1262 | 1268 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1263 | 1269 | if( P("txt") ){ |
| 1264 | 1270 | style_submenu_element("Html", "Html", |
| 1265 | - "%s/artifact?name=%s", g.zTop, zUuid); | |
| 1271 | + "%s/artifact/%s", g.zTop, zUuid); | |
| 1266 | 1272 | }else{ |
| 1267 | 1273 | renderAsHtml = 1; |
| 1268 | 1274 | style_submenu_element("Text", "Text", |
| 1269 | - "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1275 | + "%s/artifact/%s?txt=1", g.zTop, zUuid); | |
| 1270 | 1276 | } |
| 1271 | 1277 | }else if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1272 | 1278 | if( P("txt") ){ |
| 1273 | 1279 | style_submenu_element("Wiki", "Wiki", |
| 1274 | - "%s/artifact?name=%s", g.zTop, zUuid); | |
| 1280 | + "%s/artifact/%s", g.zTop, zUuid); | |
| 1275 | 1281 | }else{ |
| 1276 | 1282 | renderAsWiki = 1; |
| 1277 | 1283 | style_submenu_element("Text", "Text", |
| 1278 | - "%s/artifact?name=%s&txt=1", g.zTop, zUuid); | |
| 1284 | + "%s/artifact/%s?txt=1", g.zTop, zUuid); | |
| 1279 | 1285 | } |
| 1280 | 1286 | } |
| 1281 | 1287 | } |
| 1282 | 1288 | @ </p></blockquote> |
| 1283 | 1289 | @ <hr /> |
| 1284 | 1290 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -1213,12 +1213,18 @@ | |
| 1213 | } |
| 1214 | |
| 1215 | |
| 1216 | /* |
| 1217 | ** WEBPAGE: artifact |
| 1218 | ** URL: /artifact?name=ARTIFACTID |
| 1219 | ** URL: /artifact?ci=CHECKIN&filename=PATH |
| 1220 | ** |
| 1221 | ** Show the complete content of a file identified by ARTIFACTID |
| 1222 | ** as preformatted text. |
| 1223 | */ |
| 1224 | void artifact_page(void){ |
| @@ -1260,24 +1266,24 @@ | |
| 1260 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1261 | if( zMime ){ |
| 1262 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1263 | if( P("txt") ){ |
| 1264 | style_submenu_element("Html", "Html", |
| 1265 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1266 | }else{ |
| 1267 | renderAsHtml = 1; |
| 1268 | style_submenu_element("Text", "Text", |
| 1269 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1270 | } |
| 1271 | }else if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1272 | if( P("txt") ){ |
| 1273 | style_submenu_element("Wiki", "Wiki", |
| 1274 | "%s/artifact?name=%s", g.zTop, zUuid); |
| 1275 | }else{ |
| 1276 | renderAsWiki = 1; |
| 1277 | style_submenu_element("Text", "Text", |
| 1278 | "%s/artifact?name=%s&txt=1", g.zTop, zUuid); |
| 1279 | } |
| 1280 | } |
| 1281 | } |
| 1282 | @ </p></blockquote> |
| 1283 | @ <hr /> |
| 1284 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -1213,12 +1213,18 @@ | |
| 1213 | } |
| 1214 | |
| 1215 | |
| 1216 | /* |
| 1217 | ** WEBPAGE: artifact |
| 1218 | ** URL: /artifact/ARTIFACTID |
| 1219 | ** URL: /artifact?ci=CHECKIN&filename=PATH |
| 1220 | ** |
| 1221 | ** Additional query parameters: |
| 1222 | ** |
| 1223 | ** ln - show line numbers |
| 1224 | ** ln=N - highlight line number N |
| 1225 | ** ln=M-N - highlight lines M through N inclusive |
| 1226 | ** |
| 1227 | ** Show the complete content of a file identified by ARTIFACTID |
| 1228 | ** as preformatted text. |
| 1229 | */ |
| 1230 | void artifact_page(void){ |
| @@ -1260,24 +1266,24 @@ | |
| 1266 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1267 | if( zMime ){ |
| 1268 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1269 | if( P("txt") ){ |
| 1270 | style_submenu_element("Html", "Html", |
| 1271 | "%s/artifact/%s", g.zTop, zUuid); |
| 1272 | }else{ |
| 1273 | renderAsHtml = 1; |
| 1274 | style_submenu_element("Text", "Text", |
| 1275 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1276 | } |
| 1277 | }else if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){ |
| 1278 | if( P("txt") ){ |
| 1279 | style_submenu_element("Wiki", "Wiki", |
| 1280 | "%s/artifact/%s", g.zTop, zUuid); |
| 1281 | }else{ |
| 1282 | renderAsWiki = 1; |
| 1283 | style_submenu_element("Text", "Text", |
| 1284 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1285 | } |
| 1286 | } |
| 1287 | } |
| 1288 | @ </p></blockquote> |
| 1289 | @ <hr /> |
| 1290 |
+6
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1104,11 +1104,12 @@ | ||
| 1104 | 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | 1106 | blob_reset(&value); |
| 1107 | 1107 | continue; |
| 1108 | 1108 | } |
| 1109 | - if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){ | |
| 1109 | + if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ | |
| 1110 | + blob_trim(&value); | |
| 1110 | 1111 | db_open_repository(blob_str(&value)); |
| 1111 | 1112 | blob_reset(&value); |
| 1112 | 1113 | continue; |
| 1113 | 1114 | } |
| 1114 | 1115 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | ||
| 1439 | 1440 | if( isUiCmd ){ |
| 1440 | 1441 | zBrowser = db_get("web-browser", "start"); |
| 1441 | 1442 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1442 | 1443 | } |
| 1443 | 1444 | db_close(1); |
| 1444 | - win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound, flags); | |
| 1445 | + if( win32_http_service(iPort, zNotFound, flags) ){ | |
| 1446 | + win32_http_server(iPort, mxPort, zBrowserCmd, | |
| 1447 | + zStopperFile, zNotFound, flags); | |
| 1448 | + } | |
| 1445 | 1449 | #endif |
| 1446 | 1450 | } |
| 1447 | 1451 | |
| 1448 | 1452 | /* |
| 1449 | 1453 | ** COMMAND: test-echo |
| 1450 | 1454 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1104,11 +1104,12 @@ | |
| 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | blob_reset(&value); |
| 1107 | continue; |
| 1108 | } |
| 1109 | if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){ |
| 1110 | db_open_repository(blob_str(&value)); |
| 1111 | blob_reset(&value); |
| 1112 | continue; |
| 1113 | } |
| 1114 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | |
| 1439 | if( isUiCmd ){ |
| 1440 | zBrowser = db_get("web-browser", "start"); |
| 1441 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1442 | } |
| 1443 | db_close(1); |
| 1444 | win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound, flags); |
| 1445 | #endif |
| 1446 | } |
| 1447 | |
| 1448 | /* |
| 1449 | ** COMMAND: test-echo |
| 1450 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1104,11 +1104,12 @@ | |
| 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | blob_reset(&value); |
| 1107 | continue; |
| 1108 | } |
| 1109 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| 1110 | blob_trim(&value); |
| 1111 | db_open_repository(blob_str(&value)); |
| 1112 | blob_reset(&value); |
| 1113 | continue; |
| 1114 | } |
| 1115 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | |
| 1440 | if( isUiCmd ){ |
| 1441 | zBrowser = db_get("web-browser", "start"); |
| 1442 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1443 | } |
| 1444 | db_close(1); |
| 1445 | if( win32_http_service(iPort, zNotFound, flags) ){ |
| 1446 | win32_http_server(iPort, mxPort, zBrowserCmd, |
| 1447 | zStopperFile, zNotFound, flags); |
| 1448 | } |
| 1449 | #endif |
| 1450 | } |
| 1451 | |
| 1452 | /* |
| 1453 | ** COMMAND: test-echo |
| 1454 |
+6
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1104,11 +1104,12 @@ | ||
| 1104 | 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | 1106 | blob_reset(&value); |
| 1107 | 1107 | continue; |
| 1108 | 1108 | } |
| 1109 | - if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){ | |
| 1109 | + if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ | |
| 1110 | + blob_trim(&value); | |
| 1110 | 1111 | db_open_repository(blob_str(&value)); |
| 1111 | 1112 | blob_reset(&value); |
| 1112 | 1113 | continue; |
| 1113 | 1114 | } |
| 1114 | 1115 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | ||
| 1439 | 1440 | if( isUiCmd ){ |
| 1440 | 1441 | zBrowser = db_get("web-browser", "start"); |
| 1441 | 1442 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1442 | 1443 | } |
| 1443 | 1444 | db_close(1); |
| 1444 | - win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound, flags); | |
| 1445 | + if( win32_http_service(iPort, zNotFound, flags) ){ | |
| 1446 | + win32_http_server(iPort, mxPort, zBrowserCmd, | |
| 1447 | + zStopperFile, zNotFound, flags); | |
| 1448 | + } | |
| 1445 | 1449 | #endif |
| 1446 | 1450 | } |
| 1447 | 1451 | |
| 1448 | 1452 | /* |
| 1449 | 1453 | ** COMMAND: test-echo |
| 1450 | 1454 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1104,11 +1104,12 @@ | |
| 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | blob_reset(&value); |
| 1107 | continue; |
| 1108 | } |
| 1109 | if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){ |
| 1110 | db_open_repository(blob_str(&value)); |
| 1111 | blob_reset(&value); |
| 1112 | continue; |
| 1113 | } |
| 1114 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | |
| 1439 | if( isUiCmd ){ |
| 1440 | zBrowser = db_get("web-browser", "start"); |
| 1441 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1442 | } |
| 1443 | db_close(1); |
| 1444 | win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, zNotFound, flags); |
| 1445 | #endif |
| 1446 | } |
| 1447 | |
| 1448 | /* |
| 1449 | ** COMMAND: test-echo |
| 1450 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1104,11 +1104,12 @@ | |
| 1104 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 1105 | cgi_setenv("HOME", blob_str(&value)); |
| 1106 | blob_reset(&value); |
| 1107 | continue; |
| 1108 | } |
| 1109 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| 1110 | blob_trim(&value); |
| 1111 | db_open_repository(blob_str(&value)); |
| 1112 | blob_reset(&value); |
| 1113 | continue; |
| 1114 | } |
| 1115 | if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){ |
| @@ -1439,11 +1440,14 @@ | |
| 1440 | if( isUiCmd ){ |
| 1441 | zBrowser = db_get("web-browser", "start"); |
| 1442 | zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); |
| 1443 | } |
| 1444 | db_close(1); |
| 1445 | if( win32_http_service(iPort, zNotFound, flags) ){ |
| 1446 | win32_http_server(iPort, mxPort, zBrowserCmd, |
| 1447 | zStopperFile, zNotFound, flags); |
| 1448 | } |
| 1449 | #endif |
| 1450 | } |
| 1451 | |
| 1452 | /* |
| 1453 | ** COMMAND: test-echo |
| 1454 |
+10
-2
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -293,11 +293,19 @@ | ||
| 293 | 293 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 294 | 294 | |
| 295 | 295 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 296 | 296 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 297 | 297 | |
| 298 | -EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o | |
| 298 | +# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set | |
| 299 | +# to 1. If it is set to 1, then there is no need to build or link | |
| 300 | +# the sqlite3.o object. Instead, the system sqlite will be linked | |
| 301 | +# using -lsqlite3. | |
| 302 | +SQLITE3_OBJ.1 = | |
| 303 | +SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o | |
| 304 | +SQLITE3_OBJ. = $(SQLITE3_OBJ.0) | |
| 305 | + | |
| 306 | +EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o | |
| 299 | 307 | |
| 300 | 308 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 301 | 309 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 302 | 310 | |
| 303 | 311 | # This rule prevents make from using its default rules to try build |
| @@ -892,14 +900,14 @@ | ||
| 892 | 900 | |
| 893 | 901 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 894 | 902 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 895 | 903 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 896 | 904 | |
| 897 | -$(OBJDIR)/shell.o: $(SRCDIR)/shell.c | |
| 905 | +$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h | |
| 898 | 906 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 899 | 907 | |
| 900 | 908 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 901 | 909 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 902 | 910 | |
| 903 | 911 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 904 | 912 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 905 | 913 | |
| 906 | 914 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -293,11 +293,19 @@ | |
| 293 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 294 | |
| 295 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 296 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 297 | |
| 298 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 299 | |
| 300 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 301 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 302 | |
| 303 | # This rule prevents make from using its default rules to try build |
| @@ -892,14 +900,14 @@ | |
| 892 | |
| 893 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 894 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 895 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 896 | |
| 897 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c |
| 898 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 899 | |
| 900 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 901 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 902 | |
| 903 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 904 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 905 | |
| 906 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -293,11 +293,19 @@ | |
| 293 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 294 | |
| 295 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 296 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 297 | |
| 298 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 299 | # to 1. If it is set to 1, then there is no need to build or link |
| 300 | # the sqlite3.o object. Instead, the system sqlite will be linked |
| 301 | # using -lsqlite3. |
| 302 | SQLITE3_OBJ.1 = |
| 303 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 304 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 305 | |
| 306 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 307 | |
| 308 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 309 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 310 | |
| 311 | # This rule prevents make from using its default rules to try build |
| @@ -892,14 +900,14 @@ | |
| 900 | |
| 901 | $(OBJDIR)/zip.h: $(OBJDIR)/headers |
| 902 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 903 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 904 | |
| 905 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h |
| 906 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 907 | |
| 908 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 909 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 910 | |
| 911 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 912 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 913 | |
| 914 |
+18
-10
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -190,12 +190,20 @@ | ||
| 190 | 190 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 191 | 191 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \ |
| 192 | 192 | $(SRCDIR)/../manifest \ |
| 193 | 193 | $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 194 | 194 | |
| 195 | +# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set | |
| 196 | +# to 1. If it is set to 1, then there is no need to build or link | |
| 197 | +# the sqlite3.o object. Instead, the system sqlite will be linked | |
| 198 | +# using -lsqlite3. | |
| 199 | +SQLITE3_OBJ.1 = | |
| 200 | +SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o | |
| 201 | +SQLITE3_OBJ. = $(SQLITE3_OBJ.0) | |
| 202 | + | |
| 195 | 203 | EXTRAOBJ = \ |
| 196 | - $(OBJDIR)/sqlite3.o \ | |
| 204 | + $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ | |
| 197 | 205 | $(OBJDIR)/shell.o \ |
| 198 | 206 | $(OBJDIR)/th.o \ |
| 199 | 207 | $(OBJDIR)/th_lang.o |
| 200 | 208 | |
| 201 | 209 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| @@ -246,11 +254,11 @@ | ||
| 246 | 254 | append opt " -Dlocaltime=fossil_localtime" |
| 247 | 255 | append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0" |
| 248 | 256 | set SQLITE_OPTIONS $opt |
| 249 | 257 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 250 | 258 | |
| 251 | -writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c" | |
| 259 | +writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" | |
| 252 | 260 | set opt {-Dmain=sqlite3_shell} |
| 253 | 261 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 254 | 262 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 255 | 263 | |
| 256 | 264 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -398,11 +406,11 @@ | ||
| 398 | 406 | # the repository after running the tests. |
| 399 | 407 | test: $(APPNAME) |
| 400 | 408 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 401 | 409 | |
| 402 | 410 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 403 | - $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest >$(OBJDIR)/VERSION.h | |
| 411 | + $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 404 | 412 | |
| 405 | 413 | EXTRAOBJ = \ |
| 406 | 414 | $(OBJDIR)/sqlite3.o \ |
| 407 | 415 | $(OBJDIR)/shell.o \ |
| 408 | 416 | $(OBJDIR)/th.o \ |
| @@ -458,11 +466,11 @@ | ||
| 458 | 466 | |
| 459 | 467 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 460 | 468 | set opt $SQLITE_OPTIONS |
| 461 | 469 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 462 | 470 | |
| 463 | -writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c" | |
| 471 | +writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" | |
| 464 | 472 | set opt {-Dmain=sqlite3_shell} |
| 465 | 473 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 466 | 474 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 467 | 475 | |
| 468 | 476 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -570,11 +578,11 @@ | ||
| 570 | 578 | $(TCC) -o$@ -c $** |
| 571 | 579 | |
| 572 | 580 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 573 | 581 | $(TCC) -o$@ -c $** |
| 574 | 582 | |
| 575 | -VERSION.h : version$E $B\manifest.uuid $B\manifest | |
| 583 | +VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 576 | 584 | +$** > $@ |
| 577 | 585 | |
| 578 | 586 | page_index.h: mkindex$E $(SRC) |
| 579 | 587 | +$** > $@ |
| 580 | 588 | |
| @@ -645,11 +653,11 @@ | ||
| 645 | 653 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 646 | 654 | |
| 647 | 655 | CFLAGS = -nologo -MT -O2 |
| 648 | 656 | BCC = $(CC) $(CFLAGS) |
| 649 | 657 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 650 | -LIBS = $(ZLIB) ws2_32.lib $(SSLLIB) | |
| 658 | +LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) | |
| 651 | 659 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 652 | 660 | } |
| 653 | 661 | regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS |
| 654 | 662 | writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n" |
| 655 | 663 | writeln -nonewline "SRC = " |
| @@ -692,11 +700,11 @@ | ||
| 692 | 700 | $(BCC) $** |
| 693 | 701 | |
| 694 | 702 | mkindex$E: $(SRCDIR)\mkindex.c |
| 695 | 703 | $(BCC) $** |
| 696 | 704 | |
| 697 | -version$E: $B\src\mkversion.c | |
| 705 | +mkversion$E: $B\src\mkversion.c | |
| 698 | 706 | $(BCC) $** |
| 699 | 707 | |
| 700 | 708 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 701 | 709 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 702 | 710 | |
| @@ -707,11 +715,11 @@ | ||
| 707 | 715 | $(TCC) /Fo$@ -c $** |
| 708 | 716 | |
| 709 | 717 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 710 | 718 | $(TCC) /Fo$@ -c $** |
| 711 | 719 | |
| 712 | -VERSION.h : version$E $B\manifest.uuid $B\manifest | |
| 720 | +VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 713 | 721 | $** > $@ |
| 714 | 722 | |
| 715 | 723 | page_index.h: mkindex$E $(SRC) |
| 716 | 724 | $** > $@ |
| 717 | 725 | |
| @@ -891,12 +899,12 @@ | ||
| 891 | 899 | # generate the index source, containing all web references,.. |
| 892 | 900 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 893 | 901 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 894 | 902 | |
| 895 | 903 | # extracting version info from manifest |
| 896 | -VERSION.h: version.exe ..\manifest.uuid ..\manifest | |
| 897 | - version.exe ..\manifest.uuid ..\manifest > $@ | |
| 904 | +VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION | |
| 905 | + version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ | |
| 898 | 906 | |
| 899 | 907 | # generate the simplified headers |
| 900 | 908 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 901 | 909 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 902 | 910 | echo Done >$@ |
| 903 | 911 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -190,12 +190,20 @@ | |
| 190 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 191 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \ |
| 192 | $(SRCDIR)/../manifest \ |
| 193 | $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 194 | |
| 195 | EXTRAOBJ = \ |
| 196 | $(OBJDIR)/sqlite3.o \ |
| 197 | $(OBJDIR)/shell.o \ |
| 198 | $(OBJDIR)/th.o \ |
| 199 | $(OBJDIR)/th_lang.o |
| 200 | |
| 201 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| @@ -246,11 +254,11 @@ | |
| 246 | append opt " -Dlocaltime=fossil_localtime" |
| 247 | append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0" |
| 248 | set SQLITE_OPTIONS $opt |
| 249 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 250 | |
| 251 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c" |
| 252 | set opt {-Dmain=sqlite3_shell} |
| 253 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 254 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 255 | |
| 256 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -398,11 +406,11 @@ | |
| 398 | # the repository after running the tests. |
| 399 | test: $(APPNAME) |
| 400 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 401 | |
| 402 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 403 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest >$(OBJDIR)/VERSION.h |
| 404 | |
| 405 | EXTRAOBJ = \ |
| 406 | $(OBJDIR)/sqlite3.o \ |
| 407 | $(OBJDIR)/shell.o \ |
| 408 | $(OBJDIR)/th.o \ |
| @@ -458,11 +466,11 @@ | |
| 458 | |
| 459 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 460 | set opt $SQLITE_OPTIONS |
| 461 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 462 | |
| 463 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c" |
| 464 | set opt {-Dmain=sqlite3_shell} |
| 465 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 466 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 467 | |
| 468 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -570,11 +578,11 @@ | |
| 570 | $(TCC) -o$@ -c $** |
| 571 | |
| 572 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 573 | $(TCC) -o$@ -c $** |
| 574 | |
| 575 | VERSION.h : version$E $B\manifest.uuid $B\manifest |
| 576 | +$** > $@ |
| 577 | |
| 578 | page_index.h: mkindex$E $(SRC) |
| 579 | +$** > $@ |
| 580 | |
| @@ -645,11 +653,11 @@ | |
| 645 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 646 | |
| 647 | CFLAGS = -nologo -MT -O2 |
| 648 | BCC = $(CC) $(CFLAGS) |
| 649 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 650 | LIBS = $(ZLIB) ws2_32.lib $(SSLLIB) |
| 651 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 652 | } |
| 653 | regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS |
| 654 | writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n" |
| 655 | writeln -nonewline "SRC = " |
| @@ -692,11 +700,11 @@ | |
| 692 | $(BCC) $** |
| 693 | |
| 694 | mkindex$E: $(SRCDIR)\mkindex.c |
| 695 | $(BCC) $** |
| 696 | |
| 697 | version$E: $B\src\mkversion.c |
| 698 | $(BCC) $** |
| 699 | |
| 700 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 701 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 702 | |
| @@ -707,11 +715,11 @@ | |
| 707 | $(TCC) /Fo$@ -c $** |
| 708 | |
| 709 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 710 | $(TCC) /Fo$@ -c $** |
| 711 | |
| 712 | VERSION.h : version$E $B\manifest.uuid $B\manifest |
| 713 | $** > $@ |
| 714 | |
| 715 | page_index.h: mkindex$E $(SRC) |
| 716 | $** > $@ |
| 717 | |
| @@ -891,12 +899,12 @@ | |
| 891 | # generate the index source, containing all web references,.. |
| 892 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 893 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 894 | |
| 895 | # extracting version info from manifest |
| 896 | VERSION.h: version.exe ..\manifest.uuid ..\manifest |
| 897 | version.exe ..\manifest.uuid ..\manifest > $@ |
| 898 | |
| 899 | # generate the simplified headers |
| 900 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 901 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 902 | echo Done >$@ |
| 903 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -190,12 +190,20 @@ | |
| 190 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion |
| 191 | $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \ |
| 192 | $(SRCDIR)/../manifest \ |
| 193 | $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 194 | |
| 195 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 196 | # to 1. If it is set to 1, then there is no need to build or link |
| 197 | # the sqlite3.o object. Instead, the system sqlite will be linked |
| 198 | # using -lsqlite3. |
| 199 | SQLITE3_OBJ.1 = |
| 200 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 201 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 202 | |
| 203 | EXTRAOBJ = \ |
| 204 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 205 | $(OBJDIR)/shell.o \ |
| 206 | $(OBJDIR)/th.o \ |
| 207 | $(OBJDIR)/th_lang.o |
| 208 | |
| 209 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| @@ -246,11 +254,11 @@ | |
| 254 | append opt " -Dlocaltime=fossil_localtime" |
| 255 | append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0" |
| 256 | set SQLITE_OPTIONS $opt |
| 257 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 258 | |
| 259 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 260 | set opt {-Dmain=sqlite3_shell} |
| 261 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 262 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 263 | |
| 264 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -398,11 +406,11 @@ | |
| 406 | # the repository after running the tests. |
| 407 | test: $(APPNAME) |
| 408 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 409 | |
| 410 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 411 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 412 | |
| 413 | EXTRAOBJ = \ |
| 414 | $(OBJDIR)/sqlite3.o \ |
| 415 | $(OBJDIR)/shell.o \ |
| 416 | $(OBJDIR)/th.o \ |
| @@ -458,11 +466,11 @@ | |
| 466 | |
| 467 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 468 | set opt $SQLITE_OPTIONS |
| 469 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 470 | |
| 471 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 472 | set opt {-Dmain=sqlite3_shell} |
| 473 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 474 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 475 | |
| 476 | writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c" |
| @@ -570,11 +578,11 @@ | |
| 578 | $(TCC) -o$@ -c $** |
| 579 | |
| 580 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 581 | $(TCC) -o$@ -c $** |
| 582 | |
| 583 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 584 | +$** > $@ |
| 585 | |
| 586 | page_index.h: mkindex$E $(SRC) |
| 587 | +$** > $@ |
| 588 | |
| @@ -645,11 +653,11 @@ | |
| 653 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 654 | |
| 655 | CFLAGS = -nologo -MT -O2 |
| 656 | BCC = $(CC) $(CFLAGS) |
| 657 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 658 | LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) |
| 659 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 660 | } |
| 661 | regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS |
| 662 | writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n" |
| 663 | writeln -nonewline "SRC = " |
| @@ -692,11 +700,11 @@ | |
| 700 | $(BCC) $** |
| 701 | |
| 702 | mkindex$E: $(SRCDIR)\mkindex.c |
| 703 | $(BCC) $** |
| 704 | |
| 705 | mkversion$E: $B\src\mkversion.c |
| 706 | $(BCC) $** |
| 707 | |
| 708 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 709 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 710 | |
| @@ -707,11 +715,11 @@ | |
| 715 | $(TCC) /Fo$@ -c $** |
| 716 | |
| 717 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 718 | $(TCC) /Fo$@ -c $** |
| 719 | |
| 720 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 721 | $** > $@ |
| 722 | |
| 723 | page_index.h: mkindex$E $(SRC) |
| 724 | $** > $@ |
| 725 | |
| @@ -891,12 +899,12 @@ | |
| 899 | # generate the index source, containing all web references,.. |
| 900 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 901 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 902 | |
| 903 | # extracting version info from manifest |
| 904 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 905 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 906 | |
| 907 | # generate the simplified headers |
| 908 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 909 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 910 | echo Done >$@ |
| 911 |
+1
-1
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -859,11 +859,11 @@ | ||
| 859 | 859 | int a, b; |
| 860 | 860 | do{ |
| 861 | 861 | a = *zA++; |
| 862 | 862 | b = *zB++; |
| 863 | 863 | }while( a==b && a!=0 ); |
| 864 | - return a - b; | |
| 864 | + return ((unsigned char)a) - (unsigned char)b; | |
| 865 | 865 | } |
| 866 | 866 | } |
| 867 | 867 | |
| 868 | 868 | /* |
| 869 | 869 | ** Case insensitive string comparison. |
| 870 | 870 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -859,11 +859,11 @@ | |
| 859 | int a, b; |
| 860 | do{ |
| 861 | a = *zA++; |
| 862 | b = *zB++; |
| 863 | }while( a==b && a!=0 ); |
| 864 | return a - b; |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** Case insensitive string comparison. |
| 870 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -859,11 +859,11 @@ | |
| 859 | int a, b; |
| 860 | do{ |
| 861 | a = *zA++; |
| 862 | b = *zB++; |
| 863 | }while( a==b && a!=0 ); |
| 864 | return ((unsigned char)a) - (unsigned char)b; |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** Case insensitive string comparison. |
| 870 |
+1
-1
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -882,11 +882,11 @@ | ||
| 882 | 882 | } |
| 883 | 883 | |
| 884 | 884 | /* |
| 885 | 885 | ** COMMAND: deconstruct |
| 886 | 886 | ** |
| 887 | -** Usage %fossil deconstruct ?OPTIONS? DESTIONATION | |
| 887 | +** Usage %fossil deconstruct ?OPTIONS? DESTINATION | |
| 888 | 888 | ** |
| 889 | 889 | ** Options: |
| 890 | 890 | ** -R|--repository REPOSITORY |
| 891 | 891 | ** -L|--prefixlength N |
| 892 | 892 | ** |
| 893 | 893 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -882,11 +882,11 @@ | |
| 882 | } |
| 883 | |
| 884 | /* |
| 885 | ** COMMAND: deconstruct |
| 886 | ** |
| 887 | ** Usage %fossil deconstruct ?OPTIONS? DESTIONATION |
| 888 | ** |
| 889 | ** Options: |
| 890 | ** -R|--repository REPOSITORY |
| 891 | ** -L|--prefixlength N |
| 892 | ** |
| 893 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -882,11 +882,11 @@ | |
| 882 | } |
| 883 | |
| 884 | /* |
| 885 | ** COMMAND: deconstruct |
| 886 | ** |
| 887 | ** Usage %fossil deconstruct ?OPTIONS? DESTINATION |
| 888 | ** |
| 889 | ** Options: |
| 890 | ** -R|--repository REPOSITORY |
| 891 | ** -L|--prefixlength N |
| 892 | ** |
| 893 |
+444
-269
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -650,11 +650,11 @@ | ||
| 650 | 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | 652 | */ |
| 653 | 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | -#define SQLITE_SOURCE_ID "2011-06-15 13:11:06 f9750870ee04935f338e4d808900fee5a8b2b389" | |
| 655 | +#define SQLITE_SOURCE_ID "2011-06-24 11:29:51 9b191bb4c7c1e1b12b188c0b3eee1f8f587887c8" | |
| 656 | 656 | |
| 657 | 657 | /* |
| 658 | 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | 660 | ** |
| @@ -851,11 +851,11 @@ | ||
| 851 | 851 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 852 | 852 | ** in the context of the [database connection] passed in as its 1st |
| 853 | 853 | ** argument. ^If the callback function of the 3rd argument to |
| 854 | 854 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 855 | 855 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 856 | -** to sqlite3_exec() is relayed through to the 1st argument of each | |
| 856 | +** sqlite3_exec() is relayed through to the 1st argument of each | |
| 857 | 857 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 858 | 858 | ** is NULL, then no callback is ever invoked and result rows are |
| 859 | 859 | ** ignored. |
| 860 | 860 | ** |
| 861 | 861 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -1443,11 +1443,11 @@ | ||
| 1443 | 1443 | ** The xSleep() method causes the calling thread to sleep for at |
| 1444 | 1444 | ** least the number of microseconds given. ^The xCurrentTime() |
| 1445 | 1445 | ** method returns a Julian Day Number for the current date and time as |
| 1446 | 1446 | ** a floating point value. |
| 1447 | 1447 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 1448 | -** Day Number multipled by 86400000 (the number of milliseconds in | |
| 1448 | +** Day Number multiplied by 86400000 (the number of milliseconds in | |
| 1449 | 1449 | ** a 24-hour day). |
| 1450 | 1450 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 1451 | 1451 | ** date and time if that method is available (if iVersion is 2 or |
| 1452 | 1452 | ** greater and the function pointer is not NULL) and will fall back |
| 1453 | 1453 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1881,11 +1881,11 @@ | ||
| 1881 | 1881 | ** scratch memory beyond what is provided by this configuration option, then |
| 1882 | 1882 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1883 | 1883 | ** |
| 1884 | 1884 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1885 | 1885 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1886 | -** the database page cache with the default page cache implemenation. | |
| 1886 | +** the database page cache with the default page cache implementation. | |
| 1887 | 1887 | ** This configuration should not be used if an application-define page |
| 1888 | 1888 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1889 | 1889 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1890 | 1890 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1891 | 1891 | ** The sz argument should be the size of the largest database page |
| @@ -2979,16 +2979,16 @@ | ||
| 2979 | 2979 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2980 | 2980 | ** |
| 2981 | 2981 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2982 | 2982 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2983 | 2983 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2984 | -** is set in the fourth argument to sqlite3_open_v2(), or if it has | |
| 2984 | +** set in the fourth argument to sqlite3_open_v2(), or if it has | |
| 2985 | 2985 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2986 | 2986 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2987 | 2987 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2988 | 2988 | ** by default, but future releases of SQLite might enable URI filename |
| 2989 | -** intepretation by default. See "[URI filenames]" for additional | |
| 2989 | +** interpretation by default. See "[URI filenames]" for additional | |
| 2990 | 2990 | ** information. |
| 2991 | 2991 | ** |
| 2992 | 2992 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2993 | 2993 | ** authority, then it must be either an empty string or the string |
| 2994 | 2994 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3803,11 +3803,11 @@ | ||
| 3803 | 3803 | ** [extended result codes] might be returned as well. |
| 3804 | 3804 | ** |
| 3805 | 3805 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3806 | 3806 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3807 | 3807 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3808 | -** statement. If the statement is not a [COMMIT] and occurs within a | |
| 3808 | +** statement. If the statement is not a [COMMIT] and occurs within an | |
| 3809 | 3809 | ** explicit transaction then you should rollback the transaction before |
| 3810 | 3810 | ** continuing. |
| 3811 | 3811 | ** |
| 3812 | 3812 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3813 | 3813 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -4082,11 +4082,11 @@ | ||
| 4082 | 4082 | |
| 4083 | 4083 | /* |
| 4084 | 4084 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 4085 | 4085 | ** |
| 4086 | 4086 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 4087 | -** ^If the most recent evaluation of the statement encountered no errors or | |
| 4087 | +** ^If the most recent evaluation of the statement encountered no errors | |
| 4088 | 4088 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 4089 | 4089 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 4090 | 4090 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 4091 | 4091 | ** [extended error code]. |
| 4092 | 4092 | ** |
| @@ -5996,11 +5996,11 @@ | ||
| 5996 | 5996 | ** versions of these routines, it should at least provide stubs that always |
| 5997 | 5997 | ** return true so that one does not get spurious assertion failures. |
| 5998 | 5998 | ** |
| 5999 | 5999 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 6000 | 6000 | ** the routine should return 1. This seems counter-intuitive since |
| 6001 | -** clearly the mutex cannot be held if it does not exist. But the | |
| 6001 | +** clearly the mutex cannot be held if it does not exist. But | |
| 6002 | 6002 | ** the reason the mutex does not exist is because the build is not |
| 6003 | 6003 | ** using mutexes. And we do not want the assert() containing the |
| 6004 | 6004 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 6005 | 6005 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 6006 | 6006 | ** interface should also return 1 when given a NULL pointer. |
| @@ -6119,11 +6119,12 @@ | ||
| 6119 | 6119 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 6120 | 6120 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 6121 | 6121 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 6122 | 6122 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 6123 | 6123 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 6124 | -#define SQLITE_TESTCTRL_LAST 18 | |
| 6124 | +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 | |
| 6125 | +#define SQLITE_TESTCTRL_LAST 19 | |
| 6125 | 6126 | |
| 6126 | 6127 | /* |
| 6127 | 6128 | ** CAPI3REF: SQLite Runtime Status |
| 6128 | 6129 | ** |
| 6129 | 6130 | ** ^This interface is used to retrieve runtime status information |
| @@ -6505,11 +6506,11 @@ | ||
| 6505 | 6506 | ** [[the xFetch() page cache methods]] |
| 6506 | 6507 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 6507 | 6508 | ** the page, or a NULL pointer. |
| 6508 | 6509 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 6509 | 6510 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 6510 | -** mimimum key value is 1. After it has been retrieved using xFetch, the page | |
| 6511 | +** minimum key value is 1. After it has been retrieved using xFetch, the page | |
| 6511 | 6512 | ** is considered to be "pinned". |
| 6512 | 6513 | ** |
| 6513 | 6514 | ** If the requested page is already in the page cache, then the page cache |
| 6514 | 6515 | ** implementation must return a pointer to the page buffer with its content |
| 6515 | 6516 | ** intact. If the requested page is not already in the cache, then the |
| @@ -9556,10 +9557,11 @@ | ||
| 9556 | 9557 | #define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ |
| 9557 | 9558 | #define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ |
| 9558 | 9559 | #define SQLITE_IndexCover 0x10 /* Disable index covering table */ |
| 9559 | 9560 | #define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ |
| 9560 | 9561 | #define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ |
| 9562 | +#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ | |
| 9561 | 9563 | #define SQLITE_OptMask 0xff /* Mask of all disablable opts */ |
| 9562 | 9564 | |
| 9563 | 9565 | /* |
| 9564 | 9566 | ** Possible values for the sqlite.magic field. |
| 9565 | 9567 | ** The numbers are obtained at random and have no special meaning, other |
| @@ -11053,10 +11055,11 @@ | ||
| 11053 | 11055 | int isPCacheInit; /* True after malloc is initialized */ |
| 11054 | 11056 | sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ |
| 11055 | 11057 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 11056 | 11058 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 11057 | 11059 | void *pLogArg; /* First argument to xLog() */ |
| 11060 | + int bLocaltimeFault; /* True to fail localtime() calls */ | |
| 11058 | 11061 | }; |
| 11059 | 11062 | |
| 11060 | 11063 | /* |
| 11061 | 11064 | ** Context pointer passed down through the tree-walk. |
| 11062 | 11065 | */ |
| @@ -12013,10 +12016,11 @@ | ||
| 12013 | 12016 | 0, /* isPCacheInit */ |
| 12014 | 12017 | 0, /* pInitMutex */ |
| 12015 | 12018 | 0, /* nRefInitMutex */ |
| 12016 | 12019 | 0, /* xLog */ |
| 12017 | 12020 | 0, /* pLogArg */ |
| 12021 | + 0, /* bLocaltimeFault */ | |
| 12018 | 12022 | }; |
| 12019 | 12023 | |
| 12020 | 12024 | |
| 12021 | 12025 | /* |
| 12022 | 12026 | ** Hash table for global functions - functions common to all |
| @@ -13163,26 +13167,10 @@ | ||
| 13163 | 13167 | */ |
| 13164 | 13168 | #include <time.h> |
| 13165 | 13169 | |
| 13166 | 13170 | #ifndef SQLITE_OMIT_DATETIME_FUNCS |
| 13167 | 13171 | |
| 13168 | -/* | |
| 13169 | -** On recent Windows platforms, the localtime_s() function is available | |
| 13170 | -** as part of the "Secure CRT". It is essentially equivalent to | |
| 13171 | -** localtime_r() available under most POSIX platforms, except that the | |
| 13172 | -** order of the parameters is reversed. | |
| 13173 | -** | |
| 13174 | -** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. | |
| 13175 | -** | |
| 13176 | -** If the user has not indicated to use localtime_r() or localtime_s() | |
| 13177 | -** already, check for an MSVC build environment that provides | |
| 13178 | -** localtime_s(). | |
| 13179 | -*/ | |
| 13180 | -#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ | |
| 13181 | - defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) | |
| 13182 | -#define HAVE_LOCALTIME_S 1 | |
| 13183 | -#endif | |
| 13184 | 13172 | |
| 13185 | 13173 | /* |
| 13186 | 13174 | ** A structure for holding a single date and time. |
| 13187 | 13175 | */ |
| 13188 | 13176 | typedef struct DateTime DateTime; |
| @@ -13523,20 +13511,90 @@ | ||
| 13523 | 13511 | static void clearYMD_HMS_TZ(DateTime *p){ |
| 13524 | 13512 | p->validYMD = 0; |
| 13525 | 13513 | p->validHMS = 0; |
| 13526 | 13514 | p->validTZ = 0; |
| 13527 | 13515 | } |
| 13516 | + | |
| 13517 | +/* | |
| 13518 | +** On recent Windows platforms, the localtime_s() function is available | |
| 13519 | +** as part of the "Secure CRT". It is essentially equivalent to | |
| 13520 | +** localtime_r() available under most POSIX platforms, except that the | |
| 13521 | +** order of the parameters is reversed. | |
| 13522 | +** | |
| 13523 | +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. | |
| 13524 | +** | |
| 13525 | +** If the user has not indicated to use localtime_r() or localtime_s() | |
| 13526 | +** already, check for an MSVC build environment that provides | |
| 13527 | +** localtime_s(). | |
| 13528 | +*/ | |
| 13529 | +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ | |
| 13530 | + defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) | |
| 13531 | +#define HAVE_LOCALTIME_S 1 | |
| 13532 | +#endif | |
| 13533 | + | |
| 13534 | +#ifndef SQLITE_OMIT_LOCALTIME | |
| 13535 | +/* | |
| 13536 | +** The following routine implements the rough equivalent of localtime_r() | |
| 13537 | +** using whatever operating-system specific localtime facility that | |
| 13538 | +** is available. This routine returns 0 on success and | |
| 13539 | +** non-zero on any kind of error. | |
| 13540 | +** | |
| 13541 | +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this | |
| 13542 | +** routine will always fail. | |
| 13543 | +*/ | |
| 13544 | +static int osLocaltime(time_t *t, struct tm *pTm){ | |
| 13545 | + int rc; | |
| 13546 | +#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ | |
| 13547 | + && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) | |
| 13548 | + struct tm *pX; | |
| 13549 | +#if SQLITE_THREADSAFE>0 | |
| 13550 | + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); | |
| 13551 | +#endif | |
| 13552 | + sqlite3_mutex_enter(mutex); | |
| 13553 | + pX = localtime(t); | |
| 13554 | +#ifndef SQLITE_OMIT_BUILTIN_TEST | |
| 13555 | + if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; | |
| 13556 | +#endif | |
| 13557 | + if( pX ) *pTm = *pX; | |
| 13558 | + sqlite3_mutex_leave(mutex); | |
| 13559 | + rc = pX==0; | |
| 13560 | +#else | |
| 13561 | +#ifndef SQLITE_OMIT_BUILTIN_TEST | |
| 13562 | + if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; | |
| 13563 | +#endif | |
| 13564 | +#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R | |
| 13565 | + rc = localtime_r(t, pTm)==0; | |
| 13566 | +#else | |
| 13567 | + rc = localtime_s(pTm, t); | |
| 13568 | +#endif /* HAVE_LOCALTIME_R */ | |
| 13569 | +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ | |
| 13570 | + return rc; | |
| 13571 | +} | |
| 13572 | +#endif /* SQLITE_OMIT_LOCALTIME */ | |
| 13573 | + | |
| 13528 | 13574 | |
| 13529 | 13575 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13530 | 13576 | /* |
| 13531 | -** Compute the difference (in milliseconds) | |
| 13532 | -** between localtime and UTC (a.k.a. GMT) | |
| 13533 | -** for the time value p where p is in UTC. | |
| 13577 | +** Compute the difference (in milliseconds) between localtime and UTC | |
| 13578 | +** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, | |
| 13579 | +** return this value and set *pRc to SQLITE_OK. | |
| 13580 | +** | |
| 13581 | +** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value | |
| 13582 | +** is undefined in this case. | |
| 13534 | 13583 | */ |
| 13535 | -static sqlite3_int64 localtimeOffset(DateTime *p){ | |
| 13584 | +static sqlite3_int64 localtimeOffset( | |
| 13585 | + DateTime *p, /* Date at which to calculate offset */ | |
| 13586 | + sqlite3_context *pCtx, /* Write error here if one occurs */ | |
| 13587 | + int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ | |
| 13588 | +){ | |
| 13536 | 13589 | DateTime x, y; |
| 13537 | 13590 | time_t t; |
| 13591 | + struct tm sLocal; | |
| 13592 | + | |
| 13593 | + /* Initialize the contents of sLocal to avoid a compiler warning. */ | |
| 13594 | + memset(&sLocal, 0, sizeof(sLocal)); | |
| 13595 | + | |
| 13538 | 13596 | x = *p; |
| 13539 | 13597 | computeYMD_HMS(&x); |
| 13540 | 13598 | if( x.Y<1971 || x.Y>=2038 ){ |
| 13541 | 13599 | x.Y = 2000; |
| 13542 | 13600 | x.M = 1; |
| @@ -13550,51 +13608,27 @@ | ||
| 13550 | 13608 | } |
| 13551 | 13609 | x.tz = 0; |
| 13552 | 13610 | x.validJD = 0; |
| 13553 | 13611 | computeJD(&x); |
| 13554 | 13612 | t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); |
| 13555 | -#ifdef HAVE_LOCALTIME_R | |
| 13556 | - { | |
| 13557 | - struct tm sLocal; | |
| 13558 | - localtime_r(&t, &sLocal); | |
| 13559 | - y.Y = sLocal.tm_year + 1900; | |
| 13560 | - y.M = sLocal.tm_mon + 1; | |
| 13561 | - y.D = sLocal.tm_mday; | |
| 13562 | - y.h = sLocal.tm_hour; | |
| 13563 | - y.m = sLocal.tm_min; | |
| 13564 | - y.s = sLocal.tm_sec; | |
| 13565 | - } | |
| 13566 | -#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S | |
| 13567 | - { | |
| 13568 | - struct tm sLocal; | |
| 13569 | - localtime_s(&sLocal, &t); | |
| 13570 | - y.Y = sLocal.tm_year + 1900; | |
| 13571 | - y.M = sLocal.tm_mon + 1; | |
| 13572 | - y.D = sLocal.tm_mday; | |
| 13573 | - y.h = sLocal.tm_hour; | |
| 13574 | - y.m = sLocal.tm_min; | |
| 13575 | - y.s = sLocal.tm_sec; | |
| 13576 | - } | |
| 13577 | -#else | |
| 13578 | - { | |
| 13579 | - struct tm *pTm; | |
| 13580 | - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); | |
| 13581 | - pTm = localtime(&t); | |
| 13582 | - y.Y = pTm->tm_year + 1900; | |
| 13583 | - y.M = pTm->tm_mon + 1; | |
| 13584 | - y.D = pTm->tm_mday; | |
| 13585 | - y.h = pTm->tm_hour; | |
| 13586 | - y.m = pTm->tm_min; | |
| 13587 | - y.s = pTm->tm_sec; | |
| 13588 | - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); | |
| 13589 | - } | |
| 13590 | -#endif | |
| 13613 | + if( osLocaltime(&t, &sLocal) ){ | |
| 13614 | + sqlite3_result_error(pCtx, "local time unavailable", -1); | |
| 13615 | + *pRc = SQLITE_ERROR; | |
| 13616 | + return 0; | |
| 13617 | + } | |
| 13618 | + y.Y = sLocal.tm_year + 1900; | |
| 13619 | + y.M = sLocal.tm_mon + 1; | |
| 13620 | + y.D = sLocal.tm_mday; | |
| 13621 | + y.h = sLocal.tm_hour; | |
| 13622 | + y.m = sLocal.tm_min; | |
| 13623 | + y.s = sLocal.tm_sec; | |
| 13591 | 13624 | y.validYMD = 1; |
| 13592 | 13625 | y.validHMS = 1; |
| 13593 | 13626 | y.validJD = 0; |
| 13594 | 13627 | y.validTZ = 0; |
| 13595 | 13628 | computeJD(&y); |
| 13629 | + *pRc = SQLITE_OK; | |
| 13596 | 13630 | return y.iJD - x.iJD; |
| 13597 | 13631 | } |
| 13598 | 13632 | #endif /* SQLITE_OMIT_LOCALTIME */ |
| 13599 | 13633 | |
| 13600 | 13634 | /* |
| @@ -13614,13 +13648,16 @@ | ||
| 13614 | 13648 | ** weekday N |
| 13615 | 13649 | ** unixepoch |
| 13616 | 13650 | ** localtime |
| 13617 | 13651 | ** utc |
| 13618 | 13652 | ** |
| 13619 | -** Return 0 on success and 1 if there is any kind of error. | |
| 13653 | +** Return 0 on success and 1 if there is any kind of error. If the error | |
| 13654 | +** is in a system call (i.e. localtime()), then an error message is written | |
| 13655 | +** to context pCtx. If the error is an unrecognized modifier, no error is | |
| 13656 | +** written to pCtx. | |
| 13620 | 13657 | */ |
| 13621 | -static int parseModifier(const char *zMod, DateTime *p){ | |
| 13658 | +static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | |
| 13622 | 13659 | int rc = 1; |
| 13623 | 13660 | int n; |
| 13624 | 13661 | double r; |
| 13625 | 13662 | char *z, zBuf[30]; |
| 13626 | 13663 | z = zBuf; |
| @@ -13636,13 +13673,12 @@ | ||
| 13636 | 13673 | ** Assuming the current time value is UTC (a.k.a. GMT), shift it to |
| 13637 | 13674 | ** show local time. |
| 13638 | 13675 | */ |
| 13639 | 13676 | if( strcmp(z, "localtime")==0 ){ |
| 13640 | 13677 | computeJD(p); |
| 13641 | - p->iJD += localtimeOffset(p); | |
| 13678 | + p->iJD += localtimeOffset(p, pCtx, &rc); | |
| 13642 | 13679 | clearYMD_HMS_TZ(p); |
| 13643 | - rc = 0; | |
| 13644 | 13680 | } |
| 13645 | 13681 | break; |
| 13646 | 13682 | } |
| 13647 | 13683 | #endif |
| 13648 | 13684 | case 'u': { |
| @@ -13659,15 +13695,16 @@ | ||
| 13659 | 13695 | } |
| 13660 | 13696 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13661 | 13697 | else if( strcmp(z, "utc")==0 ){ |
| 13662 | 13698 | sqlite3_int64 c1; |
| 13663 | 13699 | computeJD(p); |
| 13664 | - c1 = localtimeOffset(p); | |
| 13665 | - p->iJD -= c1; | |
| 13666 | - clearYMD_HMS_TZ(p); | |
| 13667 | - p->iJD += c1 - localtimeOffset(p); | |
| 13668 | - rc = 0; | |
| 13700 | + c1 = localtimeOffset(p, pCtx, &rc); | |
| 13701 | + if( rc==SQLITE_OK ){ | |
| 13702 | + p->iJD -= c1; | |
| 13703 | + clearYMD_HMS_TZ(p); | |
| 13704 | + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); | |
| 13705 | + } | |
| 13669 | 13706 | } |
| 13670 | 13707 | #endif |
| 13671 | 13708 | break; |
| 13672 | 13709 | } |
| 13673 | 13710 | case 'w': { |
| @@ -13844,13 +13881,12 @@ | ||
| 13844 | 13881 | if( !z || parseDateOrTime(context, (char*)z, p) ){ |
| 13845 | 13882 | return 1; |
| 13846 | 13883 | } |
| 13847 | 13884 | } |
| 13848 | 13885 | for(i=1; i<argc; i++){ |
| 13849 | - if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){ | |
| 13850 | - return 1; | |
| 13851 | - } | |
| 13886 | + z = sqlite3_value_text(argv[i]); | |
| 13887 | + if( z==0 || parseModifier(context, (char*)z, p) ) return 1; | |
| 13852 | 13888 | } |
| 13853 | 13889 | return 0; |
| 13854 | 13890 | } |
| 13855 | 13891 | |
| 13856 | 13892 | |
| @@ -24364,10 +24400,14 @@ | ||
| 24364 | 24400 | |
| 24365 | 24401 | #if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) |
| 24366 | 24402 | # include <sys/mount.h> |
| 24367 | 24403 | #endif |
| 24368 | 24404 | |
| 24405 | +#ifdef HAVE_UTIME | |
| 24406 | +# include <utime.h> | |
| 24407 | +#endif | |
| 24408 | + | |
| 24369 | 24409 | /* |
| 24370 | 24410 | ** Allowed values of unixFile.fsFlags |
| 24371 | 24411 | */ |
| 24372 | 24412 | #define SQLITE_FSFLAGS_IS_MSDOS 0x1 |
| 24373 | 24413 | |
| @@ -26369,12 +26409,14 @@ | ||
| 26369 | 26409 | /* If we have any lock, then the lock file already exists. All we have |
| 26370 | 26410 | ** to do is adjust our internal record of the lock level. |
| 26371 | 26411 | */ |
| 26372 | 26412 | if( pFile->eFileLock > NO_LOCK ){ |
| 26373 | 26413 | pFile->eFileLock = eFileLock; |
| 26374 | -#if !OS_VXWORKS | |
| 26375 | 26414 | /* Always update the timestamp on the old file */ |
| 26415 | +#ifdef HAVE_UTIME | |
| 26416 | + utime(zLockFile, NULL); | |
| 26417 | +#else | |
| 26376 | 26418 | utimes(zLockFile, NULL); |
| 26377 | 26419 | #endif |
| 26378 | 26420 | return SQLITE_OK; |
| 26379 | 26421 | } |
| 26380 | 26422 | |
| @@ -28096,11 +28138,11 @@ | ||
| 28096 | 28138 | unixShmNode *p = pFd->pInode->pShmNode; |
| 28097 | 28139 | assert( unixMutexHeld() ); |
| 28098 | 28140 | if( p && p->nRef==0 ){ |
| 28099 | 28141 | int i; |
| 28100 | 28142 | assert( p->pInode==pFd->pInode ); |
| 28101 | - if( p->mutex ) sqlite3_mutex_free(p->mutex); | |
| 28143 | + sqlite3_mutex_free(p->mutex); | |
| 28102 | 28144 | for(i=0; i<p->nRegion; i++){ |
| 28103 | 28145 | if( p->h>=0 ){ |
| 28104 | 28146 | munmap(p->apRegion[i], p->szRegion); |
| 28105 | 28147 | }else{ |
| 28106 | 28148 | sqlite3_free(p->apRegion[i]); |
| @@ -32254,11 +32296,12 @@ | ||
| 32254 | 32296 | rc = 1; |
| 32255 | 32297 | } |
| 32256 | 32298 | } |
| 32257 | 32299 | |
| 32258 | 32300 | if( rc ){ |
| 32259 | - if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ | |
| 32301 | + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) | |
| 32302 | + || ( pFile->lastErrno==ERROR_DISK_FULL )){ | |
| 32260 | 32303 | return SQLITE_FULL; |
| 32261 | 32304 | } |
| 32262 | 32305 | return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); |
| 32263 | 32306 | } |
| 32264 | 32307 | return SQLITE_OK; |
| @@ -61205,10 +61248,18 @@ | ||
| 61205 | 61248 | rc = db->errCode = p->rc; |
| 61206 | 61249 | } |
| 61207 | 61250 | return (rc&db->errMask); |
| 61208 | 61251 | } |
| 61209 | 61252 | |
| 61253 | +/* | |
| 61254 | +** The maximum number of times that a statement will try to reparse | |
| 61255 | +** itself before giving up and returning SQLITE_SCHEMA. | |
| 61256 | +*/ | |
| 61257 | +#ifndef SQLITE_MAX_SCHEMA_RETRY | |
| 61258 | +# define SQLITE_MAX_SCHEMA_RETRY 5 | |
| 61259 | +#endif | |
| 61260 | + | |
| 61210 | 61261 | /* |
| 61211 | 61262 | ** This is the top-level implementation of sqlite3_step(). Call |
| 61212 | 61263 | ** sqlite3Step() to do most of the work. If a schema error occurs, |
| 61213 | 61264 | ** call sqlite3Reprepare() and try again. |
| 61214 | 61265 | */ |
| @@ -61223,11 +61274,11 @@ | ||
| 61223 | 61274 | return SQLITE_MISUSE_BKPT; |
| 61224 | 61275 | } |
| 61225 | 61276 | db = v->db; |
| 61226 | 61277 | sqlite3_mutex_enter(db->mutex); |
| 61227 | 61278 | while( (rc = sqlite3Step(v))==SQLITE_SCHEMA |
| 61228 | - && cnt++ < 5 | |
| 61279 | + && cnt++ < SQLITE_MAX_SCHEMA_RETRY | |
| 61229 | 61280 | && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ |
| 61230 | 61281 | sqlite3_reset(pStmt); |
| 61231 | 61282 | v->expired = 0; |
| 61232 | 61283 | } |
| 61233 | 61284 | if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ |
| @@ -63496,11 +63547,11 @@ | ||
| 63496 | 63547 | break; |
| 63497 | 63548 | } |
| 63498 | 63549 | |
| 63499 | 63550 | /* Opcode: HaltIfNull P1 P2 P3 P4 * |
| 63500 | 63551 | ** |
| 63501 | -** Check the value in register P3. If is is NULL then Halt using | |
| 63552 | +** Check the value in register P3. If it is NULL then Halt using | |
| 63502 | 63553 | ** parameter P1, P2, and P4 as if this were a Halt instruction. If the |
| 63503 | 63554 | ** value in register P3 is not NULL, then this routine is a no-op. |
| 63504 | 63555 | */ |
| 63505 | 63556 | case OP_HaltIfNull: { /* in3 */ |
| 63506 | 63557 | pIn3 = &aMem[pOp->p3]; |
| @@ -64433,11 +64484,11 @@ | ||
| 64433 | 64484 | ** additional information. |
| 64434 | 64485 | ** |
| 64435 | 64486 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64436 | 64487 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64437 | 64488 | ** of comparison is false. If either operand is NULL then the result is true. |
| 64438 | -** If neither operand is NULL the the result is the same as it would be if | |
| 64489 | +** If neither operand is NULL the result is the same as it would be if | |
| 64439 | 64490 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64440 | 64491 | */ |
| 64441 | 64492 | /* Opcode: Eq P1 P2 P3 P4 P5 |
| 64442 | 64493 | ** |
| 64443 | 64494 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64445,11 +64496,11 @@ | ||
| 64445 | 64496 | ** See the Lt opcode for additional information. |
| 64446 | 64497 | ** |
| 64447 | 64498 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64448 | 64499 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64449 | 64500 | ** of comparison is true. If either operand is NULL then the result is false. |
| 64450 | -** If neither operand is NULL the the result is the same as it would be if | |
| 64501 | +** If neither operand is NULL the result is the same as it would be if | |
| 64451 | 64502 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64452 | 64503 | */ |
| 64453 | 64504 | /* Opcode: Le P1 P2 P3 P4 P5 |
| 64454 | 64505 | ** |
| 64455 | 64506 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64730,17 +64781,17 @@ | ||
| 64730 | 64781 | break; |
| 64731 | 64782 | } |
| 64732 | 64783 | |
| 64733 | 64784 | /* Opcode: If P1 P2 P3 * * |
| 64734 | 64785 | ** |
| 64735 | -** Jump to P2 if the value in register P1 is true. The value is | |
| 64786 | +** Jump to P2 if the value in register P1 is true. The value | |
| 64736 | 64787 | ** is considered true if it is numeric and non-zero. If the value |
| 64737 | 64788 | ** in P1 is NULL then take the jump if P3 is true. |
| 64738 | 64789 | */ |
| 64739 | 64790 | /* Opcode: IfNot P1 P2 P3 * * |
| 64740 | 64791 | ** |
| 64741 | -** Jump to P2 if the value in register P1 is False. The value is | |
| 64792 | +** Jump to P2 if the value in register P1 is False. The value | |
| 64742 | 64793 | ** is considered true if it has a numeric value of zero. If the value |
| 64743 | 64794 | ** in P1 is NULL then take the jump if P3 is true. |
| 64744 | 64795 | */ |
| 64745 | 64796 | case OP_If: /* jump, in1 */ |
| 64746 | 64797 | case OP_IfNot: { /* jump, in1 */ |
| @@ -66390,11 +66441,11 @@ | ||
| 66390 | 66441 | break; |
| 66391 | 66442 | } |
| 66392 | 66443 | |
| 66393 | 66444 | /* Opcode: NotExists P1 P2 P3 * * |
| 66394 | 66445 | ** |
| 66395 | -** Use the content of register P3 as a integer key. If a record | |
| 66446 | +** Use the content of register P3 as an integer key. If a record | |
| 66396 | 66447 | ** with that key does not exist in table of P1, then jump to P2. |
| 66397 | 66448 | ** If the record does exist, then fall through. The cursor is left |
| 66398 | 66449 | ** pointing to the record if it exists. |
| 66399 | 66450 | ** |
| 66400 | 66451 | ** The difference between this operation and NotFound is that this |
| @@ -66468,11 +66519,11 @@ | ||
| 66468 | 66519 | ** written to register P2. |
| 66469 | 66520 | ** |
| 66470 | 66521 | ** If P3>0 then P3 is a register in the root frame of this VDBE that holds |
| 66471 | 66522 | ** the largest previously generated record number. No new record numbers are |
| 66472 | 66523 | ** allowed to be less than this value. When this value reaches its maximum, |
| 66473 | -** a SQLITE_FULL error is generated. The P3 register is updated with the ' | |
| 66524 | +** an SQLITE_FULL error is generated. The P3 register is updated with the ' | |
| 66474 | 66525 | ** generated record number. This P3 mechanism is used to help implement the |
| 66475 | 66526 | ** AUTOINCREMENT feature. |
| 66476 | 66527 | */ |
| 66477 | 66528 | case OP_NewRowid: { /* out2-prerelease */ |
| 66478 | 66529 | #if 0 /* local variables moved into u.be */ |
| @@ -67110,11 +67161,11 @@ | ||
| 67110 | 67161 | break; |
| 67111 | 67162 | } |
| 67112 | 67163 | |
| 67113 | 67164 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 67114 | 67165 | ** |
| 67115 | -** Register P2 holds a SQL index key made using the | |
| 67166 | +** Register P2 holds an SQL index key made using the | |
| 67116 | 67167 | ** MakeRecord instructions. This opcode writes that key |
| 67117 | 67168 | ** into the index P1. Data for the entry is nil. |
| 67118 | 67169 | ** |
| 67119 | 67170 | ** P3 is a flag that provides a hint to the b-tree layer that this |
| 67120 | 67171 | ** insert is likely to be an append. |
| @@ -82135,12 +82186,18 @@ | ||
| 82135 | 82186 | sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); |
| 82136 | 82187 | sqlite3ColumnDefault(v, pTab, idx, -1); |
| 82137 | 82188 | } |
| 82138 | 82189 | } |
| 82139 | 82190 | if( doMakeRec ){ |
| 82191 | + const char *zAff; | |
| 82192 | + if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ | |
| 82193 | + zAff = 0; | |
| 82194 | + }else{ | |
| 82195 | + zAff = sqlite3IndexAffinityStr(v, pIdx); | |
| 82196 | + } | |
| 82140 | 82197 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); |
| 82141 | - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); | |
| 82198 | + sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); | |
| 82142 | 82199 | } |
| 82143 | 82200 | sqlite3ReleaseTempRange(pParse, regBase, nCol+1); |
| 82144 | 82201 | return regBase; |
| 82145 | 82202 | } |
| 82146 | 82203 | |
| @@ -110763,10 +110820,21 @@ | ||
| 110763 | 110820 | if( sz ) *ppNew = sqlite3ScratchMalloc(sz); |
| 110764 | 110821 | sqlite3ScratchFree(pFree); |
| 110765 | 110822 | break; |
| 110766 | 110823 | } |
| 110767 | 110824 | |
| 110825 | + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); | |
| 110826 | + ** | |
| 110827 | + ** If parameter onoff is non-zero, configure the wrappers so that all | |
| 110828 | + ** subsequent calls to localtime() and variants fail. If onoff is zero, | |
| 110829 | + ** undo this setting. | |
| 110830 | + */ | |
| 110831 | + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { | |
| 110832 | + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); | |
| 110833 | + break; | |
| 110834 | + } | |
| 110835 | + | |
| 110768 | 110836 | } |
| 110769 | 110837 | va_end(ap); |
| 110770 | 110838 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 110771 | 110839 | return rc; |
| 110772 | 110840 | } |
| @@ -111420,16 +111488,10 @@ | ||
| 111420 | 111488 | ** TODO(shess) Provide a VACUUM type operation to clear out all |
| 111421 | 111489 | ** deletions and duplications. This would basically be a forced merge |
| 111422 | 111490 | ** into a single segment. |
| 111423 | 111491 | */ |
| 111424 | 111492 | |
| 111425 | -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) | |
| 111426 | - | |
| 111427 | -#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) | |
| 111428 | -# define SQLITE_CORE 1 | |
| 111429 | -#endif | |
| 111430 | - | |
| 111431 | 111493 | /************** Include fts3Int.h in the middle of fts3.c ********************/ |
| 111432 | 111494 | /************** Begin file fts3Int.h *****************************************/ |
| 111433 | 111495 | /* |
| 111434 | 111496 | ** 2009 Nov 12 |
| 111435 | 111497 | ** |
| @@ -111441,18 +111503,27 @@ | ||
| 111441 | 111503 | ** May you share freely, never taking more than you give. |
| 111442 | 111504 | ** |
| 111443 | 111505 | ****************************************************************************** |
| 111444 | 111506 | ** |
| 111445 | 111507 | */ |
| 111446 | - | |
| 111447 | 111508 | #ifndef _FTSINT_H |
| 111448 | 111509 | #define _FTSINT_H |
| 111449 | 111510 | |
| 111450 | 111511 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 111451 | 111512 | # define NDEBUG 1 |
| 111452 | 111513 | #endif |
| 111453 | 111514 | |
| 111515 | +/* | |
| 111516 | +** FTS4 is really an extension for FTS3. It is enabled using the | |
| 111517 | +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all | |
| 111518 | +** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. | |
| 111519 | +*/ | |
| 111520 | +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) | |
| 111521 | +# define SQLITE_ENABLE_FTS3 | |
| 111522 | +#endif | |
| 111523 | + | |
| 111524 | +#ifdef SQLITE_ENABLE_FTS3 | |
| 111454 | 111525 | /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ |
| 111455 | 111526 | /************** Begin file fts3_tokenizer.h **********************************/ |
| 111456 | 111527 | /* |
| 111457 | 111528 | ** 2006 July 10 |
| 111458 | 111529 | ** |
| @@ -111940,11 +112011,11 @@ | ||
| 111940 | 112011 | char *aDoclist; /* List of docids for full-text queries */ |
| 111941 | 112012 | int nDoclist; /* Size of buffer at aDoclist */ |
| 111942 | 112013 | u8 bDesc; /* True to sort in descending order */ |
| 111943 | 112014 | int eEvalmode; /* An FTS3_EVAL_XX constant */ |
| 111944 | 112015 | int nRowAvg; /* Average size of database rows, in pages */ |
| 111945 | - int nDoc; /* Documents in table */ | |
| 112016 | + sqlite3_int64 nDoc; /* Documents in table */ | |
| 111946 | 112017 | |
| 111947 | 112018 | int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ |
| 111948 | 112019 | u32 *aMatchinfo; /* Information about most recent match */ |
| 111949 | 112020 | int nMatchinfo; /* Number of elements in aMatchinfo[] */ |
| 111950 | 112021 | char *zMatchinfo; /* Matchinfo specification */ |
| @@ -111997,19 +112068,19 @@ | ||
| 111997 | 112068 | int isPrefix; /* True if token ends with a "*" character */ |
| 111998 | 112069 | |
| 111999 | 112070 | /* Variables above this point are populated when the expression is |
| 112000 | 112071 | ** parsed (by code in fts3_expr.c). Below this point the variables are |
| 112001 | 112072 | ** used when evaluating the expression. */ |
| 112002 | - int bFulltext; /* True if full-text index was used */ | |
| 112003 | 112073 | Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ |
| 112004 | 112074 | Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ |
| 112005 | 112075 | }; |
| 112006 | 112076 | |
| 112007 | 112077 | struct Fts3Phrase { |
| 112008 | 112078 | /* Cache of doclist for this phrase. */ |
| 112009 | 112079 | Fts3Doclist doclist; |
| 112010 | 112080 | int bIncr; /* True if doclist is loaded incrementally */ |
| 112081 | + int iDoclistToken; | |
| 112011 | 112082 | |
| 112012 | 112083 | /* Variables below this point are populated by fts3_expr.c when parsing |
| 112013 | 112084 | ** a MATCH expression. Everything above is part of the evaluation phase. |
| 112014 | 112085 | */ |
| 112015 | 112086 | int nToken; /* Number of tokens in the phrase */ |
| @@ -112130,10 +112201,11 @@ | ||
| 112130 | 112201 | Fts3SegFilter *pFilter; /* Pointer to filter object */ |
| 112131 | 112202 | char *aBuffer; /* Buffer to merge doclists in */ |
| 112132 | 112203 | int nBuffer; /* Allocated size of aBuffer[] in bytes */ |
| 112133 | 112204 | |
| 112134 | 112205 | int iColFilter; /* If >=0, filter for this column */ |
| 112206 | + int bRestart; | |
| 112135 | 112207 | |
| 112136 | 112208 | /* Used by fts3.c only. */ |
| 112137 | 112209 | int nCost; /* Cost of running iterator */ |
| 112138 | 112210 | int bLookup; /* True if a lookup of a single entry. */ |
| 112139 | 112211 | |
| @@ -112199,18 +112271,24 @@ | ||
| 112199 | 112271 | Fts3Table*, Fts3MultiSegReader*, int, const char*, int); |
| 112200 | 112272 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 112201 | 112273 | Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); |
| 112202 | 112274 | SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol); |
| 112203 | 112275 | SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); |
| 112276 | +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); | |
| 112204 | 112277 | |
| 112205 | 112278 | SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); |
| 112206 | 112279 | |
| 112207 | - | |
| 112280 | +#endif /* SQLITE_ENABLE_FTS3 */ | |
| 112208 | 112281 | #endif /* _FTSINT_H */ |
| 112209 | 112282 | |
| 112210 | 112283 | /************** End of fts3Int.h *********************************************/ |
| 112211 | 112284 | /************** Continuing where we left off in fts3.c ***********************/ |
| 112285 | +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) | |
| 112286 | + | |
| 112287 | +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) | |
| 112288 | +# define SQLITE_CORE 1 | |
| 112289 | +#endif | |
| 112212 | 112290 | |
| 112213 | 112291 | |
| 112214 | 112292 | #ifndef SQLITE_CORE |
| 112215 | 112293 | SQLITE_EXTENSION_INIT1 |
| 112216 | 112294 | #endif |
| @@ -112545,10 +112623,13 @@ | ||
| 112545 | 112623 | rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); |
| 112546 | 112624 | if( rc==SQLITE_OK ){ |
| 112547 | 112625 | sqlite3_step(pStmt); |
| 112548 | 112626 | p->nPgsz = sqlite3_column_int(pStmt, 0); |
| 112549 | 112627 | rc = sqlite3_finalize(pStmt); |
| 112628 | + }else if( rc==SQLITE_AUTH ){ | |
| 112629 | + p->nPgsz = 1024; | |
| 112630 | + rc = SQLITE_OK; | |
| 112550 | 112631 | } |
| 112551 | 112632 | } |
| 112552 | 112633 | assert( p->nPgsz>0 || rc!=SQLITE_OK ); |
| 112553 | 112634 | sqlite3_free(zSql); |
| 112554 | 112635 | *pRc = rc; |
| @@ -112995,11 +113076,11 @@ | ||
| 112995 | 113076 | zCsr += nDb; |
| 112996 | 113077 | |
| 112997 | 113078 | /* Fill in the azColumn array */ |
| 112998 | 113079 | for(iCol=0; iCol<nCol; iCol++){ |
| 112999 | 113080 | char *z; |
| 113000 | - int n; | |
| 113081 | + int n = 0; | |
| 113001 | 113082 | z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n); |
| 113002 | 113083 | memcpy(zCsr, z, n); |
| 113003 | 113084 | zCsr[n] = '\0'; |
| 113004 | 113085 | sqlite3Fts3Dequote(zCsr); |
| 113005 | 113086 | p->azColumn[iCol] = zCsr; |
| @@ -114581,12 +114662,12 @@ | ||
| 114581 | 114662 | |
| 114582 | 114663 | /* |
| 114583 | 114664 | ** Implementation of xBegin() method. This is a no-op. |
| 114584 | 114665 | */ |
| 114585 | 114666 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114586 | - UNUSED_PARAMETER(pVtab); | |
| 114587 | 114667 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114668 | + UNUSED_PARAMETER(pVtab); | |
| 114588 | 114669 | assert( p->pSegments==0 ); |
| 114589 | 114670 | assert( p->nPendingData==0 ); |
| 114590 | 114671 | assert( p->inTransaction!=1 ); |
| 114591 | 114672 | TESTONLY( p->inTransaction = 1 ); |
| 114592 | 114673 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -114597,12 +114678,12 @@ | ||
| 114597 | 114678 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| 114598 | 114679 | ** the pending-terms hash-table have already been flushed into the database |
| 114599 | 114680 | ** by fts3SyncMethod(). |
| 114600 | 114681 | */ |
| 114601 | 114682 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114602 | - UNUSED_PARAMETER(pVtab); | |
| 114603 | 114683 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114684 | + UNUSED_PARAMETER(pVtab); | |
| 114604 | 114685 | assert( p->nPendingData==0 ); |
| 114605 | 114686 | assert( p->inTransaction!=0 ); |
| 114606 | 114687 | assert( p->pSegments==0 ); |
| 114607 | 114688 | TESTONLY( p->inTransaction = 0 ); |
| 114608 | 114689 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -115083,75 +115164,105 @@ | ||
| 115083 | 115164 | if( rc!=SQLITE_OK ){ |
| 115084 | 115165 | *pRc = rc; |
| 115085 | 115166 | return; |
| 115086 | 115167 | } |
| 115087 | 115168 | } |
| 115169 | + assert( pExpr->pPhrase->iDoclistToken==0 ); | |
| 115170 | + pExpr->pPhrase->iDoclistToken = -1; | |
| 115088 | 115171 | }else{ |
| 115089 | 115172 | *pnOr += (pExpr->eType==FTSQUERY_OR); |
| 115090 | 115173 | fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); |
| 115091 | 115174 | fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); |
| 115092 | 115175 | } |
| 115093 | 115176 | } |
| 115094 | 115177 | } |
| 115178 | + | |
| 115179 | +static void fts3EvalPhraseMergeToken( | |
| 115180 | + Fts3Table *pTab, | |
| 115181 | + Fts3Phrase *p, | |
| 115182 | + int iToken, | |
| 115183 | + char *pList, | |
| 115184 | + int nList | |
| 115185 | +){ | |
| 115186 | + assert( iToken!=p->iDoclistToken ); | |
| 115187 | + | |
| 115188 | + if( pList==0 ){ | |
| 115189 | + sqlite3_free(p->doclist.aAll); | |
| 115190 | + p->doclist.aAll = 0; | |
| 115191 | + p->doclist.nAll = 0; | |
| 115192 | + } | |
| 115193 | + | |
| 115194 | + else if( p->iDoclistToken<0 ){ | |
| 115195 | + p->doclist.aAll = pList; | |
| 115196 | + p->doclist.nAll = nList; | |
| 115197 | + } | |
| 115198 | + | |
| 115199 | + else if( p->doclist.aAll==0 ){ | |
| 115200 | + sqlite3_free(pList); | |
| 115201 | + } | |
| 115202 | + | |
| 115203 | + else { | |
| 115204 | + char *pLeft; | |
| 115205 | + char *pRight; | |
| 115206 | + int nLeft; | |
| 115207 | + int nRight; | |
| 115208 | + int nDiff; | |
| 115209 | + | |
| 115210 | + if( p->iDoclistToken<iToken ){ | |
| 115211 | + pLeft = p->doclist.aAll; | |
| 115212 | + nLeft = p->doclist.nAll; | |
| 115213 | + pRight = pList; | |
| 115214 | + nRight = nList; | |
| 115215 | + nDiff = iToken - p->iDoclistToken; | |
| 115216 | + }else{ | |
| 115217 | + pRight = p->doclist.aAll; | |
| 115218 | + nRight = p->doclist.nAll; | |
| 115219 | + pLeft = pList; | |
| 115220 | + nLeft = nList; | |
| 115221 | + nDiff = p->iDoclistToken - iToken; | |
| 115222 | + } | |
| 115223 | + | |
| 115224 | + fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight); | |
| 115225 | + sqlite3_free(pLeft); | |
| 115226 | + p->doclist.aAll = pRight; | |
| 115227 | + p->doclist.nAll = nRight; | |
| 115228 | + } | |
| 115229 | + | |
| 115230 | + if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; | |
| 115231 | +} | |
| 115095 | 115232 | |
| 115096 | 115233 | static int fts3EvalPhraseLoad( |
| 115097 | 115234 | Fts3Cursor *pCsr, |
| 115098 | 115235 | Fts3Phrase *p |
| 115099 | 115236 | ){ |
| 115100 | 115237 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115101 | 115238 | int iToken; |
| 115102 | 115239 | int rc = SQLITE_OK; |
| 115103 | 115240 | |
| 115104 | - char *aDoclist = 0; | |
| 115105 | - int nDoclist = 0; | |
| 115106 | - int iPrev = -1; | |
| 115107 | - | |
| 115108 | 115241 | for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){ |
| 115109 | 115242 | Fts3PhraseToken *pToken = &p->aToken[iToken]; |
| 115110 | - assert( pToken->pSegcsr || pToken->pDeferred ); | |
| 115243 | + assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); | |
| 115111 | 115244 | |
| 115112 | - if( pToken->pDeferred==0 ){ | |
| 115245 | + if( pToken->pSegcsr ){ | |
| 115113 | 115246 | int nThis = 0; |
| 115114 | 115247 | char *pThis = 0; |
| 115115 | 115248 | rc = fts3TermSelect(pTab, pToken, p->iColumn, 1, &nThis, &pThis); |
| 115116 | 115249 | if( rc==SQLITE_OK ){ |
| 115117 | - if( pThis==0 ){ | |
| 115118 | - sqlite3_free(aDoclist); | |
| 115119 | - aDoclist = 0; | |
| 115120 | - nDoclist = 0; | |
| 115121 | - break; | |
| 115122 | - }else if( aDoclist==0 ){ | |
| 115123 | - aDoclist = pThis; | |
| 115124 | - nDoclist = nThis; | |
| 115125 | - }else{ | |
| 115126 | - assert( iPrev>=0 ); | |
| 115127 | - fts3DoclistPhraseMerge(pTab->bDescIdx, | |
| 115128 | - iToken-iPrev, aDoclist, nDoclist, pThis, &nThis | |
| 115129 | - ); | |
| 115130 | - sqlite3_free(aDoclist); | |
| 115131 | - aDoclist = pThis; | |
| 115132 | - nDoclist = nThis; | |
| 115133 | - } | |
| 115134 | - iPrev = iToken; | |
| 115135 | - } | |
| 115136 | - } | |
| 115137 | - } | |
| 115138 | - | |
| 115139 | - if( rc==SQLITE_OK ){ | |
| 115140 | - p->doclist.aAll = aDoclist; | |
| 115141 | - p->doclist.nAll = nDoclist; | |
| 115142 | - }else{ | |
| 115143 | - sqlite3_free(aDoclist); | |
| 115144 | - } | |
| 115250 | + fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); | |
| 115251 | + } | |
| 115252 | + } | |
| 115253 | + assert( pToken->pSegcsr==0 ); | |
| 115254 | + } | |
| 115255 | + | |
| 115145 | 115256 | return rc; |
| 115146 | 115257 | } |
| 115147 | 115258 | |
| 115148 | 115259 | static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ |
| 115149 | 115260 | int iToken; |
| 115150 | 115261 | int rc = SQLITE_OK; |
| 115151 | 115262 | |
| 115152 | - int nMaxUndeferred = -1; | |
| 115263 | + int nMaxUndeferred = pPhrase->iDoclistToken; | |
| 115153 | 115264 | char *aPoslist = 0; |
| 115154 | 115265 | int nPoslist = 0; |
| 115155 | 115266 | int iPrev = -1; |
| 115156 | 115267 | |
| 115157 | 115268 | assert( pPhrase->doclist.bFreeList==0 ); |
| @@ -115192,12 +115303,10 @@ | ||
| 115192 | 115303 | pPhrase->doclist.nList = 0; |
| 115193 | 115304 | return SQLITE_OK; |
| 115194 | 115305 | } |
| 115195 | 115306 | } |
| 115196 | 115307 | iPrev = iToken; |
| 115197 | - }else{ | |
| 115198 | - nMaxUndeferred = iToken; | |
| 115199 | 115308 | } |
| 115200 | 115309 | } |
| 115201 | 115310 | |
| 115202 | 115311 | if( iPrev>=0 ){ |
| 115203 | 115312 | if( nMaxUndeferred<0 ){ |
| @@ -115252,13 +115361,15 @@ | ||
| 115252 | 115361 | static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ |
| 115253 | 115362 | int rc; |
| 115254 | 115363 | Fts3PhraseToken *pFirst = &p->aToken[0]; |
| 115255 | 115364 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115256 | 115365 | |
| 115257 | - assert( p->doclist.aAll==0 ); | |
| 115258 | - if( pCsr->bDesc==pTab->bDescIdx && bOptOk==1 && p->nToken==1 | |
| 115259 | - && pFirst->pSegcsr && pFirst->pSegcsr->bLookup | |
| 115366 | + if( pCsr->bDesc==pTab->bDescIdx | |
| 115367 | + && bOptOk==1 | |
| 115368 | + && p->nToken==1 | |
| 115369 | + && pFirst->pSegcsr | |
| 115370 | + && pFirst->pSegcsr->bLookup | |
| 115260 | 115371 | ){ |
| 115261 | 115372 | /* Use the incremental approach. */ |
| 115262 | 115373 | int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); |
| 115263 | 115374 | rc = sqlite3Fts3MsrIncrStart( |
| 115264 | 115375 | pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); |
| @@ -115394,11 +115505,11 @@ | ||
| 115394 | 115505 | ** with this case by advancing pIter past the zero-padding added by |
| 115395 | 115506 | ** fts3EvalNearTrim2(). */ |
| 115396 | 115507 | while( pIter<pEnd && *pIter==0 ) pIter++; |
| 115397 | 115508 | |
| 115398 | 115509 | pDL->pNextDocid = pIter; |
| 115399 | - assert( *pIter || pIter>=&pDL->aAll[pDL->nAll] ); | |
| 115510 | + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); | |
| 115400 | 115511 | *pbEof = 0; |
| 115401 | 115512 | } |
| 115402 | 115513 | } |
| 115403 | 115514 | |
| 115404 | 115515 | return rc; |
| @@ -115425,17 +115536,18 @@ | ||
| 115425 | 115536 | pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); |
| 115426 | 115537 | } |
| 115427 | 115538 | } |
| 115428 | 115539 | } |
| 115429 | 115540 | |
| 115430 | - | |
| 115431 | 115541 | typedef struct Fts3TokenAndCost Fts3TokenAndCost; |
| 115432 | 115542 | struct Fts3TokenAndCost { |
| 115433 | - Fts3PhraseToken *pToken; | |
| 115434 | - Fts3Expr *pRoot; | |
| 115543 | + Fts3Phrase *pPhrase; /* The phrase the token belongs to */ | |
| 115544 | + int iToken; /* Position of token in phrase */ | |
| 115545 | + Fts3PhraseToken *pToken; /* The token itself */ | |
| 115546 | + Fts3Expr *pRoot; | |
| 115435 | 115547 | int nOvfl; |
| 115436 | - int iCol; | |
| 115548 | + int iCol; /* The column the token must match */ | |
| 115437 | 115549 | }; |
| 115438 | 115550 | |
| 115439 | 115551 | static void fts3EvalTokenCosts( |
| 115440 | 115552 | Fts3Cursor *pCsr, |
| 115441 | 115553 | Fts3Expr *pRoot, |
| @@ -115448,10 +115560,12 @@ | ||
| 115448 | 115560 | if( pExpr->eType==FTSQUERY_PHRASE ){ |
| 115449 | 115561 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 115450 | 115562 | int i; |
| 115451 | 115563 | for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){ |
| 115452 | 115564 | Fts3TokenAndCost *pTC = (*ppTC)++; |
| 115565 | + pTC->pPhrase = pPhrase; | |
| 115566 | + pTC->iToken = i; | |
| 115453 | 115567 | pTC->pRoot = pRoot; |
| 115454 | 115568 | pTC->pToken = &pPhrase->aToken[i]; |
| 115455 | 115569 | pTC->iCol = pPhrase->iColumn; |
| 115456 | 115570 | *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); |
| 115457 | 115571 | } |
| @@ -115560,23 +115674,19 @@ | ||
| 115560 | 115674 | /* At this point pTC points to the cheapest remaining token. */ |
| 115561 | 115675 | if( ii==0 ){ |
| 115562 | 115676 | if( pTC->nOvfl ){ |
| 115563 | 115677 | nDocEst = (pTC->nOvfl * pTab->nPgsz + pTab->nPgsz) / 10; |
| 115564 | 115678 | }else{ |
| 115565 | - /* TODO: Fix this so that the doclist need not be read twice. */ | |
| 115566 | 115679 | Fts3PhraseToken *pToken = pTC->pToken; |
| 115567 | 115680 | int nList = 0; |
| 115568 | 115681 | char *pList = 0; |
| 115569 | 115682 | rc = fts3TermSelect(pTab, pToken, pTC->iCol, 1, &nList, &pList); |
| 115683 | + assert( rc==SQLITE_OK || pList==0 ); | |
| 115684 | + | |
| 115570 | 115685 | if( rc==SQLITE_OK ){ |
| 115571 | 115686 | nDocEst = fts3DoclistCountDocids(1, pList, nList); |
| 115572 | - } | |
| 115573 | - sqlite3_free(pList); | |
| 115574 | - if( rc==SQLITE_OK ){ | |
| 115575 | - rc = sqlite3Fts3TermSegReaderCursor(pCsr, | |
| 115576 | - pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr | |
| 115577 | - ); | |
| 115687 | + fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList); | |
| 115578 | 115688 | } |
| 115579 | 115689 | } |
| 115580 | 115690 | }else{ |
| 115581 | 115691 | if( pTC->nOvfl>=(nDocEst*nDocSize) ){ |
| 115582 | 115692 | Fts3PhraseToken *pToken = pTC->pToken; |
| @@ -116032,17 +116142,18 @@ | ||
| 116032 | 116142 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 116033 | 116143 | |
| 116034 | 116144 | if( pPhrase ){ |
| 116035 | 116145 | fts3EvalZeroPoslist(pPhrase); |
| 116036 | 116146 | if( pPhrase->bIncr ){ |
| 116037 | - sqlite3Fts3EvalPhraseCleanup(pPhrase); | |
| 116038 | - memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); | |
| 116039 | - *pRc = sqlite3Fts3EvalStart(pCsr, pExpr, 0); | |
| 116040 | - }else{ | |
| 116041 | - pPhrase->doclist.pNextDocid = 0; | |
| 116042 | - pPhrase->doclist.iDocid = 0; | |
| 116147 | + assert( pPhrase->nToken==1 ); | |
| 116148 | + assert( pPhrase->aToken[0].pSegcsr ); | |
| 116149 | + sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr); | |
| 116150 | + *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); | |
| 116043 | 116151 | } |
| 116152 | + | |
| 116153 | + pPhrase->doclist.pNextDocid = 0; | |
| 116154 | + pPhrase->doclist.iDocid = 0; | |
| 116044 | 116155 | } |
| 116045 | 116156 | |
| 116046 | 116157 | pExpr->iDocid = 0; |
| 116047 | 116158 | pExpr->bEof = 0; |
| 116048 | 116159 | pExpr->bStart = 0; |
| @@ -116225,12 +116336,12 @@ | ||
| 116225 | 116336 | int iCol; |
| 116226 | 116337 | |
| 116227 | 116338 | if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ |
| 116228 | 116339 | assert( pCsr->nDoc>0 ); |
| 116229 | 116340 | for(iCol=0; iCol<pTab->nColumn; iCol++){ |
| 116230 | - aiOut[iCol*3 + 1] = pCsr->nDoc; | |
| 116231 | - aiOut[iCol*3 + 2] = pCsr->nDoc; | |
| 116341 | + aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; | |
| 116342 | + aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; | |
| 116232 | 116343 | } |
| 116233 | 116344 | }else{ |
| 116234 | 116345 | rc = fts3EvalGatherStats(pCsr, pExpr); |
| 116235 | 116346 | if( rc==SQLITE_OK ){ |
| 116236 | 116347 | assert( pExpr->aMI ); |
| @@ -116334,11 +116445,10 @@ | ||
| 116334 | 116445 | ** May you share freely, never taking more than you give. |
| 116335 | 116446 | ** |
| 116336 | 116447 | ****************************************************************************** |
| 116337 | 116448 | ** |
| 116338 | 116449 | */ |
| 116339 | - | |
| 116340 | 116450 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 116341 | 116451 | |
| 116342 | 116452 | |
| 116343 | 116453 | typedef struct Fts3auxTable Fts3auxTable; |
| 116344 | 116454 | typedef struct Fts3auxCursor Fts3auxCursor; |
| @@ -118168,11 +118278,10 @@ | ||
| 118168 | 118278 | */ |
| 118169 | 118279 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 118170 | 118280 | |
| 118171 | 118281 | |
| 118172 | 118282 | |
| 118173 | - | |
| 118174 | 118283 | /* |
| 118175 | 118284 | ** Class derived from sqlite3_tokenizer |
| 118176 | 118285 | */ |
| 118177 | 118286 | typedef struct porter_tokenizer { |
| 118178 | 118287 | sqlite3_tokenizer base; /* Base class */ |
| @@ -118808,15 +118917,15 @@ | ||
| 118808 | 118917 | ** (in which case SQLITE_CORE is not defined), or |
| 118809 | 118918 | ** |
| 118810 | 118919 | ** * The FTS3 module is being built into the core of |
| 118811 | 118920 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 118812 | 118921 | */ |
| 118813 | -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) | |
| 118814 | - | |
| 118815 | 118922 | #ifndef SQLITE_CORE |
| 118816 | 118923 | SQLITE_EXTENSION_INIT1 |
| 118817 | 118924 | #endif |
| 118925 | + | |
| 118926 | +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) | |
| 118818 | 118927 | |
| 118819 | 118928 | |
| 118820 | 118929 | /* |
| 118821 | 118930 | ** Implementation of the SQL scalar function for accessing the underlying |
| 118822 | 118931 | ** hash table. This function may be called as follows: |
| @@ -118937,11 +119046,11 @@ | ||
| 118937 | 119046 | sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ |
| 118938 | 119047 | char **pzErr /* OUT: Set to malloced error message */ |
| 118939 | 119048 | ){ |
| 118940 | 119049 | int rc; |
| 118941 | 119050 | char *z = (char *)zArg; |
| 118942 | - int n; | |
| 119051 | + int n = 0; | |
| 118943 | 119052 | char *zCopy; |
| 118944 | 119053 | char *zEnd; /* Pointer to nul-term of zCopy */ |
| 118945 | 119054 | sqlite3_tokenizer_module *m; |
| 118946 | 119055 | |
| 118947 | 119056 | zCopy = sqlite3_mprintf("%s", zArg); |
| @@ -119299,11 +119408,10 @@ | ||
| 119299 | 119408 | ** |
| 119300 | 119409 | ** * The FTS3 module is being built into the core of |
| 119301 | 119410 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 119302 | 119411 | */ |
| 119303 | 119412 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 119304 | - | |
| 119305 | 119413 | |
| 119306 | 119414 | |
| 119307 | 119415 | |
| 119308 | 119416 | typedef struct simple_tokenizer { |
| 119309 | 119417 | sqlite3_tokenizer base; |
| @@ -120750,10 +120858,11 @@ | ||
| 120750 | 120858 | pReader->pOffsetList = 0; |
| 120751 | 120859 | }else{ |
| 120752 | 120860 | pReader->pOffsetList = p; |
| 120753 | 120861 | } |
| 120754 | 120862 | }else{ |
| 120863 | + char *pEnd = &pReader->aDoclist[pReader->nDoclist]; | |
| 120755 | 120864 | |
| 120756 | 120865 | /* Pointer p currently points at the first byte of an offset list. The |
| 120757 | 120866 | ** following block advances it to point one byte past the end of |
| 120758 | 120867 | ** the same offset list. */ |
| 120759 | 120868 | while( 1 ){ |
| @@ -120778,17 +120887,19 @@ | ||
| 120778 | 120887 | */ |
| 120779 | 120888 | if( ppOffsetList ){ |
| 120780 | 120889 | *ppOffsetList = pReader->pOffsetList; |
| 120781 | 120890 | *pnOffsetList = (int)(p - pReader->pOffsetList - 1); |
| 120782 | 120891 | } |
| 120892 | + | |
| 120893 | + while( p<pEnd && *p==0 ) p++; | |
| 120783 | 120894 | |
| 120784 | 120895 | /* If there are no more entries in the doclist, set pOffsetList to |
| 120785 | 120896 | ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and |
| 120786 | 120897 | ** Fts3SegReader.pOffsetList to point to the next offset list before |
| 120787 | 120898 | ** returning. |
| 120788 | 120899 | */ |
| 120789 | - if( p>=&pReader->aDoclist[pReader->nDoclist] ){ | |
| 120900 | + if( p>=pEnd ){ | |
| 120790 | 120901 | pReader->pOffsetList = 0; |
| 120791 | 120902 | }else{ |
| 120792 | 120903 | rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); |
| 120793 | 120904 | if( rc==SQLITE_OK ){ |
| 120794 | 120905 | sqlite3_int64 iDelta; |
| @@ -120823,11 +120934,11 @@ | ||
| 120823 | 120934 | for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){ |
| 120824 | 120935 | Fts3SegReader *pReader = pMsr->apSegment[ii]; |
| 120825 | 120936 | if( !fts3SegReaderIsPending(pReader) |
| 120826 | 120937 | && !fts3SegReaderIsRootOnly(pReader) |
| 120827 | 120938 | ){ |
| 120828 | - int jj; | |
| 120939 | + sqlite3_int64 jj; | |
| 120829 | 120940 | for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ |
| 120830 | 120941 | int nBlob; |
| 120831 | 120942 | rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); |
| 120832 | 120943 | if( rc!=SQLITE_OK ) break; |
| 120833 | 120944 | if( (nBlob+35)>pgsz ){ |
| @@ -121768,55 +121879,31 @@ | ||
| 121768 | 121879 | |
| 121769 | 121880 | *ppList = pList; |
| 121770 | 121881 | *pnList = nList; |
| 121771 | 121882 | } |
| 121772 | 121883 | |
| 121773 | -SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( | |
| 121774 | - Fts3Table *p, /* Virtual table handle */ | |
| 121775 | - Fts3MultiSegReader *pCsr, /* Cursor object */ | |
| 121776 | - int iCol, /* Column to match on. */ | |
| 121777 | - const char *zTerm, /* Term to iterate through a doclist for */ | |
| 121778 | - int nTerm /* Number of bytes in zTerm */ | |
| 121884 | +/* | |
| 121885 | +** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any | |
| 121886 | +** existing data). Grow the buffer if required. | |
| 121887 | +** | |
| 121888 | +** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered | |
| 121889 | +** trying to resize the buffer, return SQLITE_NOMEM. | |
| 121890 | +*/ | |
| 121891 | +static int fts3MsrBufferData( | |
| 121892 | + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ | |
| 121893 | + char *pList, | |
| 121894 | + int nList | |
| 121779 | 121895 | ){ |
| 121780 | - int i; | |
| 121781 | - int nSegment = pCsr->nSegment; | |
| 121782 | - int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( | |
| 121783 | - p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp | |
| 121784 | - ); | |
| 121785 | - | |
| 121786 | - assert( pCsr->pFilter==0 ); | |
| 121787 | - assert( zTerm && nTerm>0 ); | |
| 121788 | - | |
| 121789 | - /* Advance each segment iterator until it points to the term zTerm/nTerm. */ | |
| 121790 | - for(i=0; i<nSegment; i++){ | |
| 121791 | - Fts3SegReader *pSeg = pCsr->apSegment[i]; | |
| 121792 | - do { | |
| 121793 | - int rc = fts3SegReaderNext(p, pSeg, 1); | |
| 121794 | - if( rc!=SQLITE_OK ) return rc; | |
| 121795 | - }while( fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); | |
| 121796 | - } | |
| 121797 | - fts3SegReaderSort(pCsr->apSegment, nSegment, nSegment, fts3SegReaderCmp); | |
| 121798 | - | |
| 121799 | - /* Determine how many of the segments actually point to zTerm/nTerm. */ | |
| 121800 | - for(i=0; i<nSegment; i++){ | |
| 121801 | - Fts3SegReader *pSeg = pCsr->apSegment[i]; | |
| 121802 | - if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ | |
| 121803 | - break; | |
| 121804 | - } | |
| 121805 | - } | |
| 121806 | - pCsr->nAdvance = i; | |
| 121807 | - | |
| 121808 | - /* Advance each of the segments to point to the first docid. */ | |
| 121809 | - for(i=0; i<pCsr->nAdvance; i++){ | |
| 121810 | - int rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); | |
| 121811 | - if( rc!=SQLITE_OK ) return rc; | |
| 121812 | - } | |
| 121813 | - fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); | |
| 121814 | - | |
| 121815 | - assert( iCol<0 || iCol<p->nColumn ); | |
| 121816 | - pCsr->iColFilter = iCol; | |
| 121817 | - | |
| 121896 | + if( nList>pMsr->nBuffer ){ | |
| 121897 | + char *pNew; | |
| 121898 | + pMsr->nBuffer = nList*2; | |
| 121899 | + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); | |
| 121900 | + if( !pNew ) return SQLITE_NOMEM; | |
| 121901 | + pMsr->aBuffer = pNew; | |
| 121902 | + } | |
| 121903 | + | |
| 121904 | + memcpy(pMsr->aBuffer, pList, nList); | |
| 121818 | 121905 | return SQLITE_OK; |
| 121819 | 121906 | } |
| 121820 | 121907 | |
| 121821 | 121908 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 121822 | 121909 | Fts3Table *p, /* Virtual table handle */ |
| @@ -121866,52 +121953,138 @@ | ||
| 121866 | 121953 | if( pMsr->iColFilter>=0 ){ |
| 121867 | 121954 | fts3ColumnFilter(pMsr->iColFilter, &pList, &nList); |
| 121868 | 121955 | } |
| 121869 | 121956 | |
| 121870 | 121957 | if( nList>0 ){ |
| 121958 | + if( fts3SegReaderIsPending(apSegment[0]) ){ | |
| 121959 | + rc = fts3MsrBufferData(pMsr, pList, nList+1); | |
| 121960 | + if( rc!=SQLITE_OK ) return rc; | |
| 121961 | + *paPoslist = pMsr->aBuffer; | |
| 121962 | + assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); | |
| 121963 | + }else{ | |
| 121964 | + *paPoslist = pList; | |
| 121965 | + } | |
| 121871 | 121966 | *piDocid = iDocid; |
| 121872 | - *paPoslist = pList; | |
| 121873 | 121967 | *pnPoslist = nList; |
| 121874 | 121968 | break; |
| 121875 | 121969 | } |
| 121876 | 121970 | } |
| 121877 | - | |
| 121878 | 121971 | } |
| 121879 | 121972 | |
| 121973 | + return SQLITE_OK; | |
| 121974 | +} | |
| 121975 | + | |
| 121976 | +static int fts3SegReaderStart( | |
| 121977 | + Fts3Table *p, /* Virtual table handle */ | |
| 121978 | + Fts3MultiSegReader *pCsr, /* Cursor object */ | |
| 121979 | + const char *zTerm, /* Term searched for (or NULL) */ | |
| 121980 | + int nTerm /* Length of zTerm in bytes */ | |
| 121981 | +){ | |
| 121982 | + int i; | |
| 121983 | + int nSeg = pCsr->nSegment; | |
| 121984 | + | |
| 121985 | + /* If the Fts3SegFilter defines a specific term (or term prefix) to search | |
| 121986 | + ** for, then advance each segment iterator until it points to a term of | |
| 121987 | + ** equal or greater value than the specified term. This prevents many | |
| 121988 | + ** unnecessary merge/sort operations for the case where single segment | |
| 121989 | + ** b-tree leaf nodes contain more than one term. | |
| 121990 | + */ | |
| 121991 | + for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){ | |
| 121992 | + Fts3SegReader *pSeg = pCsr->apSegment[i]; | |
| 121993 | + do { | |
| 121994 | + int rc = fts3SegReaderNext(p, pSeg, 0); | |
| 121995 | + if( rc!=SQLITE_OK ) return rc; | |
| 121996 | + }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); | |
| 121997 | + } | |
| 121998 | + fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); | |
| 121999 | + | |
| 121880 | 122000 | return SQLITE_OK; |
| 121881 | 122001 | } |
| 121882 | 122002 | |
| 121883 | 122003 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( |
| 121884 | 122004 | Fts3Table *p, /* Virtual table handle */ |
| 121885 | 122005 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 121886 | 122006 | Fts3SegFilter *pFilter /* Restrictions on range of iteration */ |
| 121887 | 122007 | ){ |
| 121888 | - int i; | |
| 121889 | - | |
| 121890 | - /* Initialize the cursor object */ | |
| 121891 | 122008 | pCsr->pFilter = pFilter; |
| 121892 | - | |
| 121893 | - /* If the Fts3SegFilter defines a specific term (or term prefix) to search | |
| 121894 | - ** for, then advance each segment iterator until it points to a term of | |
| 121895 | - ** equal or greater value than the specified term. This prevents many | |
| 121896 | - ** unnecessary merge/sort operations for the case where single segment | |
| 121897 | - ** b-tree leaf nodes contain more than one term. | |
| 121898 | - */ | |
| 121899 | - for(i=0; i<pCsr->nSegment; i++){ | |
| 121900 | - int nTerm = pFilter->nTerm; | |
| 121901 | - const char *zTerm = pFilter->zTerm; | |
| 122009 | + return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); | |
| 122010 | +} | |
| 122011 | + | |
| 122012 | +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( | |
| 122013 | + Fts3Table *p, /* Virtual table handle */ | |
| 122014 | + Fts3MultiSegReader *pCsr, /* Cursor object */ | |
| 122015 | + int iCol, /* Column to match on. */ | |
| 122016 | + const char *zTerm, /* Term to iterate through a doclist for */ | |
| 122017 | + int nTerm /* Number of bytes in zTerm */ | |
| 122018 | +){ | |
| 122019 | + int i; | |
| 122020 | + int rc; | |
| 122021 | + int nSegment = pCsr->nSegment; | |
| 122022 | + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( | |
| 122023 | + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp | |
| 122024 | + ); | |
| 122025 | + | |
| 122026 | + assert( pCsr->pFilter==0 ); | |
| 122027 | + assert( zTerm && nTerm>0 ); | |
| 122028 | + | |
| 122029 | + /* Advance each segment iterator until it points to the term zTerm/nTerm. */ | |
| 122030 | + rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); | |
| 122031 | + if( rc!=SQLITE_OK ) return rc; | |
| 122032 | + | |
| 122033 | + /* Determine how many of the segments actually point to zTerm/nTerm. */ | |
| 122034 | + for(i=0; i<nSegment; i++){ | |
| 121902 | 122035 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 121903 | - do { | |
| 121904 | - int rc = fts3SegReaderNext(p, pSeg, 0); | |
| 121905 | - if( rc!=SQLITE_OK ) return rc; | |
| 121906 | - }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); | |
| 122036 | + if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ | |
| 122037 | + break; | |
| 122038 | + } | |
| 121907 | 122039 | } |
| 121908 | - fts3SegReaderSort( | |
| 121909 | - pCsr->apSegment, pCsr->nSegment, pCsr->nSegment, fts3SegReaderCmp); | |
| 122040 | + pCsr->nAdvance = i; | |
| 122041 | + | |
| 122042 | + /* Advance each of the segments to point to the first docid. */ | |
| 122043 | + for(i=0; i<pCsr->nAdvance; i++){ | |
| 122044 | + rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); | |
| 122045 | + if( rc!=SQLITE_OK ) return rc; | |
| 122046 | + } | |
| 122047 | + fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); | |
| 122048 | + | |
| 122049 | + assert( iCol<0 || iCol<p->nColumn ); | |
| 122050 | + pCsr->iColFilter = iCol; | |
| 122051 | + | |
| 122052 | + return SQLITE_OK; | |
| 122053 | +} | |
| 122054 | + | |
| 122055 | +/* | |
| 122056 | +** This function is called on a MultiSegReader that has been started using | |
| 122057 | +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also | |
| 122058 | +** have been made. Calling this function puts the MultiSegReader in such | |
| 122059 | +** a state that if the next two calls are: | |
| 122060 | +** | |
| 122061 | +** sqlite3Fts3SegReaderStart() | |
| 122062 | +** sqlite3Fts3SegReaderStep() | |
| 122063 | +** | |
| 122064 | +** then the entire doclist for the term is available in | |
| 122065 | +** MultiSegReader.aDoclist/nDoclist. | |
| 122066 | +*/ | |
| 122067 | +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ | |
| 122068 | + int i; /* Used to iterate through segment-readers */ | |
| 122069 | + | |
| 122070 | + assert( pCsr->zTerm==0 ); | |
| 122071 | + assert( pCsr->nTerm==0 ); | |
| 122072 | + assert( pCsr->aDoclist==0 ); | |
| 122073 | + assert( pCsr->nDoclist==0 ); | |
| 122074 | + | |
| 122075 | + pCsr->nAdvance = 0; | |
| 122076 | + pCsr->bRestart = 1; | |
| 122077 | + for(i=0; i<pCsr->nSegment; i++){ | |
| 122078 | + pCsr->apSegment[i]->pOffsetList = 0; | |
| 122079 | + pCsr->apSegment[i]->nOffsetList = 0; | |
| 122080 | + pCsr->apSegment[i]->iDocid = 0; | |
| 122081 | + } | |
| 121910 | 122082 | |
| 121911 | 122083 | return SQLITE_OK; |
| 121912 | 122084 | } |
| 122085 | + | |
| 121913 | 122086 | |
| 121914 | 122087 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( |
| 121915 | 122088 | Fts3Table *p, /* Virtual table handle */ |
| 121916 | 122089 | Fts3MultiSegReader *pCsr /* Cursor object */ |
| 121917 | 122090 | ){ |
| @@ -121981,13 +122154,18 @@ | ||
| 121981 | 122154 | assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); |
| 121982 | 122155 | if( nMerge==1 |
| 121983 | 122156 | && !isIgnoreEmpty |
| 121984 | 122157 | && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) |
| 121985 | 122158 | ){ |
| 121986 | - pCsr->aDoclist = apSegment[0]->aDoclist; | |
| 121987 | 122159 | pCsr->nDoclist = apSegment[0]->nDoclist; |
| 121988 | - rc = SQLITE_ROW; | |
| 122160 | + if( fts3SegReaderIsPending(apSegment[0]) ){ | |
| 122161 | + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); | |
| 122162 | + pCsr->aDoclist = pCsr->aBuffer; | |
| 122163 | + }else{ | |
| 122164 | + pCsr->aDoclist = apSegment[0]->aDoclist; | |
| 122165 | + } | |
| 122166 | + if( rc==SQLITE_OK ) rc = SQLITE_ROW; | |
| 121989 | 122167 | }else{ |
| 121990 | 122168 | int nDoclist = 0; /* Size of doclist */ |
| 121991 | 122169 | sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ |
| 121992 | 122170 | |
| 121993 | 122171 | /* The current term of the first nMerge entries in the array |
| @@ -123725,11 +123903,11 @@ | ||
| 123725 | 123903 | if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; |
| 123726 | 123904 | break; |
| 123727 | 123905 | |
| 123728 | 123906 | case FTS3_MATCHINFO_NDOC: |
| 123729 | 123907 | if( bGlobal ){ |
| 123730 | - sqlite3_int64 nDoc; | |
| 123908 | + sqlite3_int64 nDoc = 0; | |
| 123731 | 123909 | rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); |
| 123732 | 123910 | pInfo->aMatchinfo[0] = (u32)nDoc; |
| 123733 | 123911 | } |
| 123734 | 123912 | break; |
| 123735 | 123913 | |
| @@ -125620,11 +125798,11 @@ | ||
| 125620 | 125798 | */ |
| 125621 | 125799 | static float cellArea(Rtree *pRtree, RtreeCell *p){ |
| 125622 | 125800 | float area = 1.0; |
| 125623 | 125801 | int ii; |
| 125624 | 125802 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125625 | - area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); | |
| 125803 | + area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); | |
| 125626 | 125804 | } |
| 125627 | 125805 | return area; |
| 125628 | 125806 | } |
| 125629 | 125807 | |
| 125630 | 125808 | /* |
| @@ -125633,11 +125811,11 @@ | ||
| 125633 | 125811 | */ |
| 125634 | 125812 | static float cellMargin(Rtree *pRtree, RtreeCell *p){ |
| 125635 | 125813 | float margin = 0.0; |
| 125636 | 125814 | int ii; |
| 125637 | 125815 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125638 | - margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); | |
| 125816 | + margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); | |
| 125639 | 125817 | } |
| 125640 | 125818 | return margin; |
| 125641 | 125819 | } |
| 125642 | 125820 | |
| 125643 | 125821 | /* |
| @@ -125718,11 +125896,11 @@ | ||
| 125718 | 125896 | |
| 125719 | 125897 | if( x2<x1 ){ |
| 125720 | 125898 | o = 0.0; |
| 125721 | 125899 | break; |
| 125722 | 125900 | }else{ |
| 125723 | - o = o * (x2-x1); | |
| 125901 | + o = o * (float)(x2-x1); | |
| 125724 | 125902 | } |
| 125725 | 125903 | } |
| 125726 | 125904 | overlap += o; |
| 125727 | 125905 | } |
| 125728 | 125906 | } |
| @@ -125737,16 +125915,16 @@ | ||
| 125737 | 125915 | RtreeCell *pInsert, |
| 125738 | 125916 | RtreeCell *aCell, |
| 125739 | 125917 | int nCell, |
| 125740 | 125918 | int iExclude |
| 125741 | 125919 | ){ |
| 125742 | - float before; | |
| 125743 | - float after; | |
| 125920 | + double before; | |
| 125921 | + double after; | |
| 125744 | 125922 | before = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125745 | 125923 | cellUnion(pRtree, p, pInsert); |
| 125746 | 125924 | after = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125747 | - return after-before; | |
| 125925 | + return (float)(after-before); | |
| 125748 | 125926 | } |
| 125749 | 125927 | #endif |
| 125750 | 125928 | |
| 125751 | 125929 | |
| 125752 | 125930 | /* |
| @@ -125764,15 +125942,15 @@ | ||
| 125764 | 125942 | RtreeNode *pNode; |
| 125765 | 125943 | rc = nodeAcquire(pRtree, 1, 0, &pNode); |
| 125766 | 125944 | |
| 125767 | 125945 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 125768 | 125946 | int iCell; |
| 125769 | - sqlite3_int64 iBest; | |
| 125947 | + sqlite3_int64 iBest = 0; | |
| 125770 | 125948 | |
| 125771 | - float fMinGrowth; | |
| 125772 | - float fMinArea; | |
| 125773 | - float fMinOverlap; | |
| 125949 | + float fMinGrowth = 0.0; | |
| 125950 | + float fMinArea = 0.0; | |
| 125951 | + float fMinOverlap = 0.0; | |
| 125774 | 125952 | |
| 125775 | 125953 | int nCell = NCELL(pNode); |
| 125776 | 125954 | RtreeCell cell; |
| 125777 | 125955 | RtreeNode *pChild; |
| 125778 | 125956 | |
| @@ -126198,13 +126376,13 @@ | ||
| 126198 | 126376 | ){ |
| 126199 | 126377 | int **aaSorted; |
| 126200 | 126378 | int *aSpare; |
| 126201 | 126379 | int ii; |
| 126202 | 126380 | |
| 126203 | - int iBestDim; | |
| 126204 | - int iBestSplit; | |
| 126205 | - float fBestMargin; | |
| 126381 | + int iBestDim = 0; | |
| 126382 | + int iBestSplit = 0; | |
| 126383 | + float fBestMargin = 0.0; | |
| 126206 | 126384 | |
| 126207 | 126385 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 126208 | 126386 | |
| 126209 | 126387 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 126210 | 126388 | if( !aaSorted ){ |
| @@ -126222,13 +126400,13 @@ | ||
| 126222 | 126400 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 126223 | 126401 | } |
| 126224 | 126402 | |
| 126225 | 126403 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 126226 | 126404 | float margin = 0.0; |
| 126227 | - float fBestOverlap; | |
| 126228 | - float fBestArea; | |
| 126229 | - int iBestLeft; | |
| 126405 | + float fBestOverlap = 0.0; | |
| 126406 | + float fBestArea = 0.0; | |
| 126407 | + int iBestLeft = 0; | |
| 126230 | 126408 | int nLeft; |
| 126231 | 126409 | |
| 126232 | 126410 | for( |
| 126233 | 126411 | nLeft=RTREE_MINCELLS(pRtree); |
| 126234 | 126412 | nLeft<=(nCell-RTREE_MINCELLS(pRtree)); |
| @@ -126539,11 +126717,11 @@ | ||
| 126539 | 126717 | static int deleteCell(Rtree *, RtreeNode *, int, int); |
| 126540 | 126718 | |
| 126541 | 126719 | static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ |
| 126542 | 126720 | int rc; |
| 126543 | 126721 | int rc2; |
| 126544 | - RtreeNode *pParent; | |
| 126722 | + RtreeNode *pParent = 0; | |
| 126545 | 126723 | int iCell; |
| 126546 | 126724 | |
| 126547 | 126725 | assert( pNode->nRef==1 ); |
| 126548 | 126726 | |
| 126549 | 126727 | /* Remove the entry in the parent cell. */ |
| @@ -126687,23 +126865,23 @@ | ||
| 126687 | 126865 | }else{ |
| 126688 | 126866 | nodeGetCell(pRtree, pNode, ii, &aCell[ii]); |
| 126689 | 126867 | } |
| 126690 | 126868 | aOrder[ii] = ii; |
| 126691 | 126869 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126692 | - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); | |
| 126693 | - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); | |
| 126870 | + aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]); | |
| 126871 | + aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]); | |
| 126694 | 126872 | } |
| 126695 | 126873 | } |
| 126696 | 126874 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126697 | - aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0); | |
| 126875 | + aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0)); | |
| 126698 | 126876 | } |
| 126699 | 126877 | |
| 126700 | 126878 | for(ii=0; ii<nCell; ii++){ |
| 126701 | 126879 | aDistance[ii] = 0.0; |
| 126702 | 126880 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126703 | - float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) - | |
| 126704 | - DCOORD(aCell[ii].aCoord[iDim*2]); | |
| 126881 | + float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - | |
| 126882 | + DCOORD(aCell[ii].aCoord[iDim*2])); | |
| 126705 | 126883 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 126706 | 126884 | } |
| 126707 | 126885 | } |
| 126708 | 126886 | |
| 126709 | 126887 | SortByDistance(aOrder, nCell, aDistance, aSpare); |
| @@ -126798,14 +126976,14 @@ | ||
| 126798 | 126976 | nodeGetCell(pRtree, pNode, ii, &cell); |
| 126799 | 126977 | |
| 126800 | 126978 | /* Find a node to store this cell in. pNode->iNode currently contains |
| 126801 | 126979 | ** the height of the sub-tree headed by the cell. |
| 126802 | 126980 | */ |
| 126803 | - rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert); | |
| 126981 | + rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); | |
| 126804 | 126982 | if( rc==SQLITE_OK ){ |
| 126805 | 126983 | int rc2; |
| 126806 | - rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode); | |
| 126984 | + rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); | |
| 126807 | 126985 | rc2 = nodeRelease(pRtree, pInsert); |
| 126808 | 126986 | if( rc==SQLITE_OK ){ |
| 126809 | 126987 | rc = rc2; |
| 126810 | 126988 | } |
| 126811 | 126989 | } |
| @@ -127190,11 +127368,11 @@ | ||
| 127190 | 127368 | int isCreate /* True for xCreate, false for xConnect */ |
| 127191 | 127369 | ){ |
| 127192 | 127370 | int rc; |
| 127193 | 127371 | char *zSql; |
| 127194 | 127372 | if( isCreate ){ |
| 127195 | - int iPageSize; | |
| 127373 | + int iPageSize = 0; | |
| 127196 | 127374 | zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); |
| 127197 | 127375 | rc = getIntFromStmt(db, zSql, &iPageSize); |
| 127198 | 127376 | if( rc==SQLITE_OK ){ |
| 127199 | 127377 | pRtree->iNodeSize = iPageSize-64; |
| 127200 | 127378 | if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){ |
| @@ -127993,14 +128171,11 @@ | ||
| 127993 | 128171 | ** May you find forgiveness for yourself and forgive others. |
| 127994 | 128172 | ** May you share freely, never taking more than you give. |
| 127995 | 128173 | ** |
| 127996 | 128174 | ************************************************************************* |
| 127997 | 128175 | ** This file implements a tokenizer for fts3 based on the ICU library. |
| 127998 | -** | |
| 127999 | -** $Id: fts3_icu.c,v 1.3 2008/09/01 18:34:20 danielk1977 Exp $ | |
| 128000 | 128176 | */ |
| 128001 | - | |
| 128002 | 128177 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 128003 | 128178 | #ifdef SQLITE_ENABLE_ICU |
| 128004 | 128179 | |
| 128005 | 128180 | |
| 128006 | 128181 | #include <unicode/ubrk.h> |
| 128007 | 128182 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -650,11 +650,11 @@ | |
| 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | */ |
| 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | #define SQLITE_SOURCE_ID "2011-06-15 13:11:06 f9750870ee04935f338e4d808900fee5a8b2b389" |
| 656 | |
| 657 | /* |
| 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | ** |
| @@ -851,11 +851,11 @@ | |
| 851 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 852 | ** in the context of the [database connection] passed in as its 1st |
| 853 | ** argument. ^If the callback function of the 3rd argument to |
| 854 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 855 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 856 | ** to sqlite3_exec() is relayed through to the 1st argument of each |
| 857 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 858 | ** is NULL, then no callback is ever invoked and result rows are |
| 859 | ** ignored. |
| 860 | ** |
| 861 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -1443,11 +1443,11 @@ | |
| 1443 | ** The xSleep() method causes the calling thread to sleep for at |
| 1444 | ** least the number of microseconds given. ^The xCurrentTime() |
| 1445 | ** method returns a Julian Day Number for the current date and time as |
| 1446 | ** a floating point value. |
| 1447 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 1448 | ** Day Number multipled by 86400000 (the number of milliseconds in |
| 1449 | ** a 24-hour day). |
| 1450 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 1451 | ** date and time if that method is available (if iVersion is 2 or |
| 1452 | ** greater and the function pointer is not NULL) and will fall back |
| 1453 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1881,11 +1881,11 @@ | |
| 1881 | ** scratch memory beyond what is provided by this configuration option, then |
| 1882 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1883 | ** |
| 1884 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1885 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1886 | ** the database page cache with the default page cache implemenation. |
| 1887 | ** This configuration should not be used if an application-define page |
| 1888 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1889 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1890 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1891 | ** The sz argument should be the size of the largest database page |
| @@ -2979,16 +2979,16 @@ | |
| 2979 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2980 | ** |
| 2981 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2982 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2983 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2984 | ** is set in the fourth argument to sqlite3_open_v2(), or if it has |
| 2985 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2986 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2987 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2988 | ** by default, but future releases of SQLite might enable URI filename |
| 2989 | ** intepretation by default. See "[URI filenames]" for additional |
| 2990 | ** information. |
| 2991 | ** |
| 2992 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2993 | ** authority, then it must be either an empty string or the string |
| 2994 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3803,11 +3803,11 @@ | |
| 3803 | ** [extended result codes] might be returned as well. |
| 3804 | ** |
| 3805 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3806 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3807 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3808 | ** statement. If the statement is not a [COMMIT] and occurs within a |
| 3809 | ** explicit transaction then you should rollback the transaction before |
| 3810 | ** continuing. |
| 3811 | ** |
| 3812 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3813 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -4082,11 +4082,11 @@ | |
| 4082 | |
| 4083 | /* |
| 4084 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 4085 | ** |
| 4086 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 4087 | ** ^If the most recent evaluation of the statement encountered no errors or |
| 4088 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 4089 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 4090 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 4091 | ** [extended error code]. |
| 4092 | ** |
| @@ -5996,11 +5996,11 @@ | |
| 5996 | ** versions of these routines, it should at least provide stubs that always |
| 5997 | ** return true so that one does not get spurious assertion failures. |
| 5998 | ** |
| 5999 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 6000 | ** the routine should return 1. This seems counter-intuitive since |
| 6001 | ** clearly the mutex cannot be held if it does not exist. But the |
| 6002 | ** the reason the mutex does not exist is because the build is not |
| 6003 | ** using mutexes. And we do not want the assert() containing the |
| 6004 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 6005 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 6006 | ** interface should also return 1 when given a NULL pointer. |
| @@ -6119,11 +6119,12 @@ | |
| 6119 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 6120 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 6121 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 6122 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 6123 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 6124 | #define SQLITE_TESTCTRL_LAST 18 |
| 6125 | |
| 6126 | /* |
| 6127 | ** CAPI3REF: SQLite Runtime Status |
| 6128 | ** |
| 6129 | ** ^This interface is used to retrieve runtime status information |
| @@ -6505,11 +6506,11 @@ | |
| 6505 | ** [[the xFetch() page cache methods]] |
| 6506 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 6507 | ** the page, or a NULL pointer. |
| 6508 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 6509 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 6510 | ** mimimum key value is 1. After it has been retrieved using xFetch, the page |
| 6511 | ** is considered to be "pinned". |
| 6512 | ** |
| 6513 | ** If the requested page is already in the page cache, then the page cache |
| 6514 | ** implementation must return a pointer to the page buffer with its content |
| 6515 | ** intact. If the requested page is not already in the cache, then the |
| @@ -9556,10 +9557,11 @@ | |
| 9556 | #define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ |
| 9557 | #define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ |
| 9558 | #define SQLITE_IndexCover 0x10 /* Disable index covering table */ |
| 9559 | #define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ |
| 9560 | #define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ |
| 9561 | #define SQLITE_OptMask 0xff /* Mask of all disablable opts */ |
| 9562 | |
| 9563 | /* |
| 9564 | ** Possible values for the sqlite.magic field. |
| 9565 | ** The numbers are obtained at random and have no special meaning, other |
| @@ -11053,10 +11055,11 @@ | |
| 11053 | int isPCacheInit; /* True after malloc is initialized */ |
| 11054 | sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ |
| 11055 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 11056 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 11057 | void *pLogArg; /* First argument to xLog() */ |
| 11058 | }; |
| 11059 | |
| 11060 | /* |
| 11061 | ** Context pointer passed down through the tree-walk. |
| 11062 | */ |
| @@ -12013,10 +12016,11 @@ | |
| 12013 | 0, /* isPCacheInit */ |
| 12014 | 0, /* pInitMutex */ |
| 12015 | 0, /* nRefInitMutex */ |
| 12016 | 0, /* xLog */ |
| 12017 | 0, /* pLogArg */ |
| 12018 | }; |
| 12019 | |
| 12020 | |
| 12021 | /* |
| 12022 | ** Hash table for global functions - functions common to all |
| @@ -13163,26 +13167,10 @@ | |
| 13163 | */ |
| 13164 | #include <time.h> |
| 13165 | |
| 13166 | #ifndef SQLITE_OMIT_DATETIME_FUNCS |
| 13167 | |
| 13168 | /* |
| 13169 | ** On recent Windows platforms, the localtime_s() function is available |
| 13170 | ** as part of the "Secure CRT". It is essentially equivalent to |
| 13171 | ** localtime_r() available under most POSIX platforms, except that the |
| 13172 | ** order of the parameters is reversed. |
| 13173 | ** |
| 13174 | ** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. |
| 13175 | ** |
| 13176 | ** If the user has not indicated to use localtime_r() or localtime_s() |
| 13177 | ** already, check for an MSVC build environment that provides |
| 13178 | ** localtime_s(). |
| 13179 | */ |
| 13180 | #if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ |
| 13181 | defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
| 13182 | #define HAVE_LOCALTIME_S 1 |
| 13183 | #endif |
| 13184 | |
| 13185 | /* |
| 13186 | ** A structure for holding a single date and time. |
| 13187 | */ |
| 13188 | typedef struct DateTime DateTime; |
| @@ -13523,20 +13511,90 @@ | |
| 13523 | static void clearYMD_HMS_TZ(DateTime *p){ |
| 13524 | p->validYMD = 0; |
| 13525 | p->validHMS = 0; |
| 13526 | p->validTZ = 0; |
| 13527 | } |
| 13528 | |
| 13529 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13530 | /* |
| 13531 | ** Compute the difference (in milliseconds) |
| 13532 | ** between localtime and UTC (a.k.a. GMT) |
| 13533 | ** for the time value p where p is in UTC. |
| 13534 | */ |
| 13535 | static sqlite3_int64 localtimeOffset(DateTime *p){ |
| 13536 | DateTime x, y; |
| 13537 | time_t t; |
| 13538 | x = *p; |
| 13539 | computeYMD_HMS(&x); |
| 13540 | if( x.Y<1971 || x.Y>=2038 ){ |
| 13541 | x.Y = 2000; |
| 13542 | x.M = 1; |
| @@ -13550,51 +13608,27 @@ | |
| 13550 | } |
| 13551 | x.tz = 0; |
| 13552 | x.validJD = 0; |
| 13553 | computeJD(&x); |
| 13554 | t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); |
| 13555 | #ifdef HAVE_LOCALTIME_R |
| 13556 | { |
| 13557 | struct tm sLocal; |
| 13558 | localtime_r(&t, &sLocal); |
| 13559 | y.Y = sLocal.tm_year + 1900; |
| 13560 | y.M = sLocal.tm_mon + 1; |
| 13561 | y.D = sLocal.tm_mday; |
| 13562 | y.h = sLocal.tm_hour; |
| 13563 | y.m = sLocal.tm_min; |
| 13564 | y.s = sLocal.tm_sec; |
| 13565 | } |
| 13566 | #elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S |
| 13567 | { |
| 13568 | struct tm sLocal; |
| 13569 | localtime_s(&sLocal, &t); |
| 13570 | y.Y = sLocal.tm_year + 1900; |
| 13571 | y.M = sLocal.tm_mon + 1; |
| 13572 | y.D = sLocal.tm_mday; |
| 13573 | y.h = sLocal.tm_hour; |
| 13574 | y.m = sLocal.tm_min; |
| 13575 | y.s = sLocal.tm_sec; |
| 13576 | } |
| 13577 | #else |
| 13578 | { |
| 13579 | struct tm *pTm; |
| 13580 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| 13581 | pTm = localtime(&t); |
| 13582 | y.Y = pTm->tm_year + 1900; |
| 13583 | y.M = pTm->tm_mon + 1; |
| 13584 | y.D = pTm->tm_mday; |
| 13585 | y.h = pTm->tm_hour; |
| 13586 | y.m = pTm->tm_min; |
| 13587 | y.s = pTm->tm_sec; |
| 13588 | sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| 13589 | } |
| 13590 | #endif |
| 13591 | y.validYMD = 1; |
| 13592 | y.validHMS = 1; |
| 13593 | y.validJD = 0; |
| 13594 | y.validTZ = 0; |
| 13595 | computeJD(&y); |
| 13596 | return y.iJD - x.iJD; |
| 13597 | } |
| 13598 | #endif /* SQLITE_OMIT_LOCALTIME */ |
| 13599 | |
| 13600 | /* |
| @@ -13614,13 +13648,16 @@ | |
| 13614 | ** weekday N |
| 13615 | ** unixepoch |
| 13616 | ** localtime |
| 13617 | ** utc |
| 13618 | ** |
| 13619 | ** Return 0 on success and 1 if there is any kind of error. |
| 13620 | */ |
| 13621 | static int parseModifier(const char *zMod, DateTime *p){ |
| 13622 | int rc = 1; |
| 13623 | int n; |
| 13624 | double r; |
| 13625 | char *z, zBuf[30]; |
| 13626 | z = zBuf; |
| @@ -13636,13 +13673,12 @@ | |
| 13636 | ** Assuming the current time value is UTC (a.k.a. GMT), shift it to |
| 13637 | ** show local time. |
| 13638 | */ |
| 13639 | if( strcmp(z, "localtime")==0 ){ |
| 13640 | computeJD(p); |
| 13641 | p->iJD += localtimeOffset(p); |
| 13642 | clearYMD_HMS_TZ(p); |
| 13643 | rc = 0; |
| 13644 | } |
| 13645 | break; |
| 13646 | } |
| 13647 | #endif |
| 13648 | case 'u': { |
| @@ -13659,15 +13695,16 @@ | |
| 13659 | } |
| 13660 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13661 | else if( strcmp(z, "utc")==0 ){ |
| 13662 | sqlite3_int64 c1; |
| 13663 | computeJD(p); |
| 13664 | c1 = localtimeOffset(p); |
| 13665 | p->iJD -= c1; |
| 13666 | clearYMD_HMS_TZ(p); |
| 13667 | p->iJD += c1 - localtimeOffset(p); |
| 13668 | rc = 0; |
| 13669 | } |
| 13670 | #endif |
| 13671 | break; |
| 13672 | } |
| 13673 | case 'w': { |
| @@ -13844,13 +13881,12 @@ | |
| 13844 | if( !z || parseDateOrTime(context, (char*)z, p) ){ |
| 13845 | return 1; |
| 13846 | } |
| 13847 | } |
| 13848 | for(i=1; i<argc; i++){ |
| 13849 | if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){ |
| 13850 | return 1; |
| 13851 | } |
| 13852 | } |
| 13853 | return 0; |
| 13854 | } |
| 13855 | |
| 13856 | |
| @@ -24364,10 +24400,14 @@ | |
| 24364 | |
| 24365 | #if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) |
| 24366 | # include <sys/mount.h> |
| 24367 | #endif |
| 24368 | |
| 24369 | /* |
| 24370 | ** Allowed values of unixFile.fsFlags |
| 24371 | */ |
| 24372 | #define SQLITE_FSFLAGS_IS_MSDOS 0x1 |
| 24373 | |
| @@ -26369,12 +26409,14 @@ | |
| 26369 | /* If we have any lock, then the lock file already exists. All we have |
| 26370 | ** to do is adjust our internal record of the lock level. |
| 26371 | */ |
| 26372 | if( pFile->eFileLock > NO_LOCK ){ |
| 26373 | pFile->eFileLock = eFileLock; |
| 26374 | #if !OS_VXWORKS |
| 26375 | /* Always update the timestamp on the old file */ |
| 26376 | utimes(zLockFile, NULL); |
| 26377 | #endif |
| 26378 | return SQLITE_OK; |
| 26379 | } |
| 26380 | |
| @@ -28096,11 +28138,11 @@ | |
| 28096 | unixShmNode *p = pFd->pInode->pShmNode; |
| 28097 | assert( unixMutexHeld() ); |
| 28098 | if( p && p->nRef==0 ){ |
| 28099 | int i; |
| 28100 | assert( p->pInode==pFd->pInode ); |
| 28101 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 28102 | for(i=0; i<p->nRegion; i++){ |
| 28103 | if( p->h>=0 ){ |
| 28104 | munmap(p->apRegion[i], p->szRegion); |
| 28105 | }else{ |
| 28106 | sqlite3_free(p->apRegion[i]); |
| @@ -32254,11 +32296,12 @@ | |
| 32254 | rc = 1; |
| 32255 | } |
| 32256 | } |
| 32257 | |
| 32258 | if( rc ){ |
| 32259 | if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ |
| 32260 | return SQLITE_FULL; |
| 32261 | } |
| 32262 | return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); |
| 32263 | } |
| 32264 | return SQLITE_OK; |
| @@ -61205,10 +61248,18 @@ | |
| 61205 | rc = db->errCode = p->rc; |
| 61206 | } |
| 61207 | return (rc&db->errMask); |
| 61208 | } |
| 61209 | |
| 61210 | /* |
| 61211 | ** This is the top-level implementation of sqlite3_step(). Call |
| 61212 | ** sqlite3Step() to do most of the work. If a schema error occurs, |
| 61213 | ** call sqlite3Reprepare() and try again. |
| 61214 | */ |
| @@ -61223,11 +61274,11 @@ | |
| 61223 | return SQLITE_MISUSE_BKPT; |
| 61224 | } |
| 61225 | db = v->db; |
| 61226 | sqlite3_mutex_enter(db->mutex); |
| 61227 | while( (rc = sqlite3Step(v))==SQLITE_SCHEMA |
| 61228 | && cnt++ < 5 |
| 61229 | && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ |
| 61230 | sqlite3_reset(pStmt); |
| 61231 | v->expired = 0; |
| 61232 | } |
| 61233 | if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ |
| @@ -63496,11 +63547,11 @@ | |
| 63496 | break; |
| 63497 | } |
| 63498 | |
| 63499 | /* Opcode: HaltIfNull P1 P2 P3 P4 * |
| 63500 | ** |
| 63501 | ** Check the value in register P3. If is is NULL then Halt using |
| 63502 | ** parameter P1, P2, and P4 as if this were a Halt instruction. If the |
| 63503 | ** value in register P3 is not NULL, then this routine is a no-op. |
| 63504 | */ |
| 63505 | case OP_HaltIfNull: { /* in3 */ |
| 63506 | pIn3 = &aMem[pOp->p3]; |
| @@ -64433,11 +64484,11 @@ | |
| 64433 | ** additional information. |
| 64434 | ** |
| 64435 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64436 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64437 | ** of comparison is false. If either operand is NULL then the result is true. |
| 64438 | ** If neither operand is NULL the the result is the same as it would be if |
| 64439 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64440 | */ |
| 64441 | /* Opcode: Eq P1 P2 P3 P4 P5 |
| 64442 | ** |
| 64443 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64445,11 +64496,11 @@ | |
| 64445 | ** See the Lt opcode for additional information. |
| 64446 | ** |
| 64447 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64448 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64449 | ** of comparison is true. If either operand is NULL then the result is false. |
| 64450 | ** If neither operand is NULL the the result is the same as it would be if |
| 64451 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64452 | */ |
| 64453 | /* Opcode: Le P1 P2 P3 P4 P5 |
| 64454 | ** |
| 64455 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64730,17 +64781,17 @@ | |
| 64730 | break; |
| 64731 | } |
| 64732 | |
| 64733 | /* Opcode: If P1 P2 P3 * * |
| 64734 | ** |
| 64735 | ** Jump to P2 if the value in register P1 is true. The value is |
| 64736 | ** is considered true if it is numeric and non-zero. If the value |
| 64737 | ** in P1 is NULL then take the jump if P3 is true. |
| 64738 | */ |
| 64739 | /* Opcode: IfNot P1 P2 P3 * * |
| 64740 | ** |
| 64741 | ** Jump to P2 if the value in register P1 is False. The value is |
| 64742 | ** is considered true if it has a numeric value of zero. If the value |
| 64743 | ** in P1 is NULL then take the jump if P3 is true. |
| 64744 | */ |
| 64745 | case OP_If: /* jump, in1 */ |
| 64746 | case OP_IfNot: { /* jump, in1 */ |
| @@ -66390,11 +66441,11 @@ | |
| 66390 | break; |
| 66391 | } |
| 66392 | |
| 66393 | /* Opcode: NotExists P1 P2 P3 * * |
| 66394 | ** |
| 66395 | ** Use the content of register P3 as a integer key. If a record |
| 66396 | ** with that key does not exist in table of P1, then jump to P2. |
| 66397 | ** If the record does exist, then fall through. The cursor is left |
| 66398 | ** pointing to the record if it exists. |
| 66399 | ** |
| 66400 | ** The difference between this operation and NotFound is that this |
| @@ -66468,11 +66519,11 @@ | |
| 66468 | ** written to register P2. |
| 66469 | ** |
| 66470 | ** If P3>0 then P3 is a register in the root frame of this VDBE that holds |
| 66471 | ** the largest previously generated record number. No new record numbers are |
| 66472 | ** allowed to be less than this value. When this value reaches its maximum, |
| 66473 | ** a SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 66474 | ** generated record number. This P3 mechanism is used to help implement the |
| 66475 | ** AUTOINCREMENT feature. |
| 66476 | */ |
| 66477 | case OP_NewRowid: { /* out2-prerelease */ |
| 66478 | #if 0 /* local variables moved into u.be */ |
| @@ -67110,11 +67161,11 @@ | |
| 67110 | break; |
| 67111 | } |
| 67112 | |
| 67113 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 67114 | ** |
| 67115 | ** Register P2 holds a SQL index key made using the |
| 67116 | ** MakeRecord instructions. This opcode writes that key |
| 67117 | ** into the index P1. Data for the entry is nil. |
| 67118 | ** |
| 67119 | ** P3 is a flag that provides a hint to the b-tree layer that this |
| 67120 | ** insert is likely to be an append. |
| @@ -82135,12 +82186,18 @@ | |
| 82135 | sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); |
| 82136 | sqlite3ColumnDefault(v, pTab, idx, -1); |
| 82137 | } |
| 82138 | } |
| 82139 | if( doMakeRec ){ |
| 82140 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); |
| 82141 | sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); |
| 82142 | } |
| 82143 | sqlite3ReleaseTempRange(pParse, regBase, nCol+1); |
| 82144 | return regBase; |
| 82145 | } |
| 82146 | |
| @@ -110763,10 +110820,21 @@ | |
| 110763 | if( sz ) *ppNew = sqlite3ScratchMalloc(sz); |
| 110764 | sqlite3ScratchFree(pFree); |
| 110765 | break; |
| 110766 | } |
| 110767 | |
| 110768 | } |
| 110769 | va_end(ap); |
| 110770 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 110771 | return rc; |
| 110772 | } |
| @@ -111420,16 +111488,10 @@ | |
| 111420 | ** TODO(shess) Provide a VACUUM type operation to clear out all |
| 111421 | ** deletions and duplications. This would basically be a forced merge |
| 111422 | ** into a single segment. |
| 111423 | */ |
| 111424 | |
| 111425 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 111426 | |
| 111427 | #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) |
| 111428 | # define SQLITE_CORE 1 |
| 111429 | #endif |
| 111430 | |
| 111431 | /************** Include fts3Int.h in the middle of fts3.c ********************/ |
| 111432 | /************** Begin file fts3Int.h *****************************************/ |
| 111433 | /* |
| 111434 | ** 2009 Nov 12 |
| 111435 | ** |
| @@ -111441,18 +111503,27 @@ | |
| 111441 | ** May you share freely, never taking more than you give. |
| 111442 | ** |
| 111443 | ****************************************************************************** |
| 111444 | ** |
| 111445 | */ |
| 111446 | |
| 111447 | #ifndef _FTSINT_H |
| 111448 | #define _FTSINT_H |
| 111449 | |
| 111450 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 111451 | # define NDEBUG 1 |
| 111452 | #endif |
| 111453 | |
| 111454 | /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ |
| 111455 | /************** Begin file fts3_tokenizer.h **********************************/ |
| 111456 | /* |
| 111457 | ** 2006 July 10 |
| 111458 | ** |
| @@ -111940,11 +112011,11 @@ | |
| 111940 | char *aDoclist; /* List of docids for full-text queries */ |
| 111941 | int nDoclist; /* Size of buffer at aDoclist */ |
| 111942 | u8 bDesc; /* True to sort in descending order */ |
| 111943 | int eEvalmode; /* An FTS3_EVAL_XX constant */ |
| 111944 | int nRowAvg; /* Average size of database rows, in pages */ |
| 111945 | int nDoc; /* Documents in table */ |
| 111946 | |
| 111947 | int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ |
| 111948 | u32 *aMatchinfo; /* Information about most recent match */ |
| 111949 | int nMatchinfo; /* Number of elements in aMatchinfo[] */ |
| 111950 | char *zMatchinfo; /* Matchinfo specification */ |
| @@ -111997,19 +112068,19 @@ | |
| 111997 | int isPrefix; /* True if token ends with a "*" character */ |
| 111998 | |
| 111999 | /* Variables above this point are populated when the expression is |
| 112000 | ** parsed (by code in fts3_expr.c). Below this point the variables are |
| 112001 | ** used when evaluating the expression. */ |
| 112002 | int bFulltext; /* True if full-text index was used */ |
| 112003 | Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ |
| 112004 | Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ |
| 112005 | }; |
| 112006 | |
| 112007 | struct Fts3Phrase { |
| 112008 | /* Cache of doclist for this phrase. */ |
| 112009 | Fts3Doclist doclist; |
| 112010 | int bIncr; /* True if doclist is loaded incrementally */ |
| 112011 | |
| 112012 | /* Variables below this point are populated by fts3_expr.c when parsing |
| 112013 | ** a MATCH expression. Everything above is part of the evaluation phase. |
| 112014 | */ |
| 112015 | int nToken; /* Number of tokens in the phrase */ |
| @@ -112130,10 +112201,11 @@ | |
| 112130 | Fts3SegFilter *pFilter; /* Pointer to filter object */ |
| 112131 | char *aBuffer; /* Buffer to merge doclists in */ |
| 112132 | int nBuffer; /* Allocated size of aBuffer[] in bytes */ |
| 112133 | |
| 112134 | int iColFilter; /* If >=0, filter for this column */ |
| 112135 | |
| 112136 | /* Used by fts3.c only. */ |
| 112137 | int nCost; /* Cost of running iterator */ |
| 112138 | int bLookup; /* True if a lookup of a single entry. */ |
| 112139 | |
| @@ -112199,18 +112271,24 @@ | |
| 112199 | Fts3Table*, Fts3MultiSegReader*, int, const char*, int); |
| 112200 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 112201 | Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); |
| 112202 | SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol); |
| 112203 | SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); |
| 112204 | |
| 112205 | SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); |
| 112206 | |
| 112207 | |
| 112208 | #endif /* _FTSINT_H */ |
| 112209 | |
| 112210 | /************** End of fts3Int.h *********************************************/ |
| 112211 | /************** Continuing where we left off in fts3.c ***********************/ |
| 112212 | |
| 112213 | |
| 112214 | #ifndef SQLITE_CORE |
| 112215 | SQLITE_EXTENSION_INIT1 |
| 112216 | #endif |
| @@ -112545,10 +112623,13 @@ | |
| 112545 | rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); |
| 112546 | if( rc==SQLITE_OK ){ |
| 112547 | sqlite3_step(pStmt); |
| 112548 | p->nPgsz = sqlite3_column_int(pStmt, 0); |
| 112549 | rc = sqlite3_finalize(pStmt); |
| 112550 | } |
| 112551 | } |
| 112552 | assert( p->nPgsz>0 || rc!=SQLITE_OK ); |
| 112553 | sqlite3_free(zSql); |
| 112554 | *pRc = rc; |
| @@ -112995,11 +113076,11 @@ | |
| 112995 | zCsr += nDb; |
| 112996 | |
| 112997 | /* Fill in the azColumn array */ |
| 112998 | for(iCol=0; iCol<nCol; iCol++){ |
| 112999 | char *z; |
| 113000 | int n; |
| 113001 | z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n); |
| 113002 | memcpy(zCsr, z, n); |
| 113003 | zCsr[n] = '\0'; |
| 113004 | sqlite3Fts3Dequote(zCsr); |
| 113005 | p->azColumn[iCol] = zCsr; |
| @@ -114581,12 +114662,12 @@ | |
| 114581 | |
| 114582 | /* |
| 114583 | ** Implementation of xBegin() method. This is a no-op. |
| 114584 | */ |
| 114585 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114586 | UNUSED_PARAMETER(pVtab); |
| 114587 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114588 | assert( p->pSegments==0 ); |
| 114589 | assert( p->nPendingData==0 ); |
| 114590 | assert( p->inTransaction!=1 ); |
| 114591 | TESTONLY( p->inTransaction = 1 ); |
| 114592 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -114597,12 +114678,12 @@ | |
| 114597 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| 114598 | ** the pending-terms hash-table have already been flushed into the database |
| 114599 | ** by fts3SyncMethod(). |
| 114600 | */ |
| 114601 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114602 | UNUSED_PARAMETER(pVtab); |
| 114603 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114604 | assert( p->nPendingData==0 ); |
| 114605 | assert( p->inTransaction!=0 ); |
| 114606 | assert( p->pSegments==0 ); |
| 114607 | TESTONLY( p->inTransaction = 0 ); |
| 114608 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -115083,75 +115164,105 @@ | |
| 115083 | if( rc!=SQLITE_OK ){ |
| 115084 | *pRc = rc; |
| 115085 | return; |
| 115086 | } |
| 115087 | } |
| 115088 | }else{ |
| 115089 | *pnOr += (pExpr->eType==FTSQUERY_OR); |
| 115090 | fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); |
| 115091 | fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); |
| 115092 | } |
| 115093 | } |
| 115094 | } |
| 115095 | |
| 115096 | static int fts3EvalPhraseLoad( |
| 115097 | Fts3Cursor *pCsr, |
| 115098 | Fts3Phrase *p |
| 115099 | ){ |
| 115100 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115101 | int iToken; |
| 115102 | int rc = SQLITE_OK; |
| 115103 | |
| 115104 | char *aDoclist = 0; |
| 115105 | int nDoclist = 0; |
| 115106 | int iPrev = -1; |
| 115107 | |
| 115108 | for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){ |
| 115109 | Fts3PhraseToken *pToken = &p->aToken[iToken]; |
| 115110 | assert( pToken->pSegcsr || pToken->pDeferred ); |
| 115111 | |
| 115112 | if( pToken->pDeferred==0 ){ |
| 115113 | int nThis = 0; |
| 115114 | char *pThis = 0; |
| 115115 | rc = fts3TermSelect(pTab, pToken, p->iColumn, 1, &nThis, &pThis); |
| 115116 | if( rc==SQLITE_OK ){ |
| 115117 | if( pThis==0 ){ |
| 115118 | sqlite3_free(aDoclist); |
| 115119 | aDoclist = 0; |
| 115120 | nDoclist = 0; |
| 115121 | break; |
| 115122 | }else if( aDoclist==0 ){ |
| 115123 | aDoclist = pThis; |
| 115124 | nDoclist = nThis; |
| 115125 | }else{ |
| 115126 | assert( iPrev>=0 ); |
| 115127 | fts3DoclistPhraseMerge(pTab->bDescIdx, |
| 115128 | iToken-iPrev, aDoclist, nDoclist, pThis, &nThis |
| 115129 | ); |
| 115130 | sqlite3_free(aDoclist); |
| 115131 | aDoclist = pThis; |
| 115132 | nDoclist = nThis; |
| 115133 | } |
| 115134 | iPrev = iToken; |
| 115135 | } |
| 115136 | } |
| 115137 | } |
| 115138 | |
| 115139 | if( rc==SQLITE_OK ){ |
| 115140 | p->doclist.aAll = aDoclist; |
| 115141 | p->doclist.nAll = nDoclist; |
| 115142 | }else{ |
| 115143 | sqlite3_free(aDoclist); |
| 115144 | } |
| 115145 | return rc; |
| 115146 | } |
| 115147 | |
| 115148 | static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ |
| 115149 | int iToken; |
| 115150 | int rc = SQLITE_OK; |
| 115151 | |
| 115152 | int nMaxUndeferred = -1; |
| 115153 | char *aPoslist = 0; |
| 115154 | int nPoslist = 0; |
| 115155 | int iPrev = -1; |
| 115156 | |
| 115157 | assert( pPhrase->doclist.bFreeList==0 ); |
| @@ -115192,12 +115303,10 @@ | |
| 115192 | pPhrase->doclist.nList = 0; |
| 115193 | return SQLITE_OK; |
| 115194 | } |
| 115195 | } |
| 115196 | iPrev = iToken; |
| 115197 | }else{ |
| 115198 | nMaxUndeferred = iToken; |
| 115199 | } |
| 115200 | } |
| 115201 | |
| 115202 | if( iPrev>=0 ){ |
| 115203 | if( nMaxUndeferred<0 ){ |
| @@ -115252,13 +115361,15 @@ | |
| 115252 | static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ |
| 115253 | int rc; |
| 115254 | Fts3PhraseToken *pFirst = &p->aToken[0]; |
| 115255 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115256 | |
| 115257 | assert( p->doclist.aAll==0 ); |
| 115258 | if( pCsr->bDesc==pTab->bDescIdx && bOptOk==1 && p->nToken==1 |
| 115259 | && pFirst->pSegcsr && pFirst->pSegcsr->bLookup |
| 115260 | ){ |
| 115261 | /* Use the incremental approach. */ |
| 115262 | int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); |
| 115263 | rc = sqlite3Fts3MsrIncrStart( |
| 115264 | pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); |
| @@ -115394,11 +115505,11 @@ | |
| 115394 | ** with this case by advancing pIter past the zero-padding added by |
| 115395 | ** fts3EvalNearTrim2(). */ |
| 115396 | while( pIter<pEnd && *pIter==0 ) pIter++; |
| 115397 | |
| 115398 | pDL->pNextDocid = pIter; |
| 115399 | assert( *pIter || pIter>=&pDL->aAll[pDL->nAll] ); |
| 115400 | *pbEof = 0; |
| 115401 | } |
| 115402 | } |
| 115403 | |
| 115404 | return rc; |
| @@ -115425,17 +115536,18 @@ | |
| 115425 | pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); |
| 115426 | } |
| 115427 | } |
| 115428 | } |
| 115429 | |
| 115430 | |
| 115431 | typedef struct Fts3TokenAndCost Fts3TokenAndCost; |
| 115432 | struct Fts3TokenAndCost { |
| 115433 | Fts3PhraseToken *pToken; |
| 115434 | Fts3Expr *pRoot; |
| 115435 | int nOvfl; |
| 115436 | int iCol; |
| 115437 | }; |
| 115438 | |
| 115439 | static void fts3EvalTokenCosts( |
| 115440 | Fts3Cursor *pCsr, |
| 115441 | Fts3Expr *pRoot, |
| @@ -115448,10 +115560,12 @@ | |
| 115448 | if( pExpr->eType==FTSQUERY_PHRASE ){ |
| 115449 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 115450 | int i; |
| 115451 | for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){ |
| 115452 | Fts3TokenAndCost *pTC = (*ppTC)++; |
| 115453 | pTC->pRoot = pRoot; |
| 115454 | pTC->pToken = &pPhrase->aToken[i]; |
| 115455 | pTC->iCol = pPhrase->iColumn; |
| 115456 | *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); |
| 115457 | } |
| @@ -115560,23 +115674,19 @@ | |
| 115560 | /* At this point pTC points to the cheapest remaining token. */ |
| 115561 | if( ii==0 ){ |
| 115562 | if( pTC->nOvfl ){ |
| 115563 | nDocEst = (pTC->nOvfl * pTab->nPgsz + pTab->nPgsz) / 10; |
| 115564 | }else{ |
| 115565 | /* TODO: Fix this so that the doclist need not be read twice. */ |
| 115566 | Fts3PhraseToken *pToken = pTC->pToken; |
| 115567 | int nList = 0; |
| 115568 | char *pList = 0; |
| 115569 | rc = fts3TermSelect(pTab, pToken, pTC->iCol, 1, &nList, &pList); |
| 115570 | if( rc==SQLITE_OK ){ |
| 115571 | nDocEst = fts3DoclistCountDocids(1, pList, nList); |
| 115572 | } |
| 115573 | sqlite3_free(pList); |
| 115574 | if( rc==SQLITE_OK ){ |
| 115575 | rc = sqlite3Fts3TermSegReaderCursor(pCsr, |
| 115576 | pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr |
| 115577 | ); |
| 115578 | } |
| 115579 | } |
| 115580 | }else{ |
| 115581 | if( pTC->nOvfl>=(nDocEst*nDocSize) ){ |
| 115582 | Fts3PhraseToken *pToken = pTC->pToken; |
| @@ -116032,17 +116142,18 @@ | |
| 116032 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 116033 | |
| 116034 | if( pPhrase ){ |
| 116035 | fts3EvalZeroPoslist(pPhrase); |
| 116036 | if( pPhrase->bIncr ){ |
| 116037 | sqlite3Fts3EvalPhraseCleanup(pPhrase); |
| 116038 | memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); |
| 116039 | *pRc = sqlite3Fts3EvalStart(pCsr, pExpr, 0); |
| 116040 | }else{ |
| 116041 | pPhrase->doclist.pNextDocid = 0; |
| 116042 | pPhrase->doclist.iDocid = 0; |
| 116043 | } |
| 116044 | } |
| 116045 | |
| 116046 | pExpr->iDocid = 0; |
| 116047 | pExpr->bEof = 0; |
| 116048 | pExpr->bStart = 0; |
| @@ -116225,12 +116336,12 @@ | |
| 116225 | int iCol; |
| 116226 | |
| 116227 | if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ |
| 116228 | assert( pCsr->nDoc>0 ); |
| 116229 | for(iCol=0; iCol<pTab->nColumn; iCol++){ |
| 116230 | aiOut[iCol*3 + 1] = pCsr->nDoc; |
| 116231 | aiOut[iCol*3 + 2] = pCsr->nDoc; |
| 116232 | } |
| 116233 | }else{ |
| 116234 | rc = fts3EvalGatherStats(pCsr, pExpr); |
| 116235 | if( rc==SQLITE_OK ){ |
| 116236 | assert( pExpr->aMI ); |
| @@ -116334,11 +116445,10 @@ | |
| 116334 | ** May you share freely, never taking more than you give. |
| 116335 | ** |
| 116336 | ****************************************************************************** |
| 116337 | ** |
| 116338 | */ |
| 116339 | |
| 116340 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 116341 | |
| 116342 | |
| 116343 | typedef struct Fts3auxTable Fts3auxTable; |
| 116344 | typedef struct Fts3auxCursor Fts3auxCursor; |
| @@ -118168,11 +118278,10 @@ | |
| 118168 | */ |
| 118169 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 118170 | |
| 118171 | |
| 118172 | |
| 118173 | |
| 118174 | /* |
| 118175 | ** Class derived from sqlite3_tokenizer |
| 118176 | */ |
| 118177 | typedef struct porter_tokenizer { |
| 118178 | sqlite3_tokenizer base; /* Base class */ |
| @@ -118808,15 +118917,15 @@ | |
| 118808 | ** (in which case SQLITE_CORE is not defined), or |
| 118809 | ** |
| 118810 | ** * The FTS3 module is being built into the core of |
| 118811 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 118812 | */ |
| 118813 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 118814 | |
| 118815 | #ifndef SQLITE_CORE |
| 118816 | SQLITE_EXTENSION_INIT1 |
| 118817 | #endif |
| 118818 | |
| 118819 | |
| 118820 | /* |
| 118821 | ** Implementation of the SQL scalar function for accessing the underlying |
| 118822 | ** hash table. This function may be called as follows: |
| @@ -118937,11 +119046,11 @@ | |
| 118937 | sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ |
| 118938 | char **pzErr /* OUT: Set to malloced error message */ |
| 118939 | ){ |
| 118940 | int rc; |
| 118941 | char *z = (char *)zArg; |
| 118942 | int n; |
| 118943 | char *zCopy; |
| 118944 | char *zEnd; /* Pointer to nul-term of zCopy */ |
| 118945 | sqlite3_tokenizer_module *m; |
| 118946 | |
| 118947 | zCopy = sqlite3_mprintf("%s", zArg); |
| @@ -119299,11 +119408,10 @@ | |
| 119299 | ** |
| 119300 | ** * The FTS3 module is being built into the core of |
| 119301 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 119302 | */ |
| 119303 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 119304 | |
| 119305 | |
| 119306 | |
| 119307 | |
| 119308 | typedef struct simple_tokenizer { |
| 119309 | sqlite3_tokenizer base; |
| @@ -120750,10 +120858,11 @@ | |
| 120750 | pReader->pOffsetList = 0; |
| 120751 | }else{ |
| 120752 | pReader->pOffsetList = p; |
| 120753 | } |
| 120754 | }else{ |
| 120755 | |
| 120756 | /* Pointer p currently points at the first byte of an offset list. The |
| 120757 | ** following block advances it to point one byte past the end of |
| 120758 | ** the same offset list. */ |
| 120759 | while( 1 ){ |
| @@ -120778,17 +120887,19 @@ | |
| 120778 | */ |
| 120779 | if( ppOffsetList ){ |
| 120780 | *ppOffsetList = pReader->pOffsetList; |
| 120781 | *pnOffsetList = (int)(p - pReader->pOffsetList - 1); |
| 120782 | } |
| 120783 | |
| 120784 | /* If there are no more entries in the doclist, set pOffsetList to |
| 120785 | ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and |
| 120786 | ** Fts3SegReader.pOffsetList to point to the next offset list before |
| 120787 | ** returning. |
| 120788 | */ |
| 120789 | if( p>=&pReader->aDoclist[pReader->nDoclist] ){ |
| 120790 | pReader->pOffsetList = 0; |
| 120791 | }else{ |
| 120792 | rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); |
| 120793 | if( rc==SQLITE_OK ){ |
| 120794 | sqlite3_int64 iDelta; |
| @@ -120823,11 +120934,11 @@ | |
| 120823 | for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){ |
| 120824 | Fts3SegReader *pReader = pMsr->apSegment[ii]; |
| 120825 | if( !fts3SegReaderIsPending(pReader) |
| 120826 | && !fts3SegReaderIsRootOnly(pReader) |
| 120827 | ){ |
| 120828 | int jj; |
| 120829 | for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ |
| 120830 | int nBlob; |
| 120831 | rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); |
| 120832 | if( rc!=SQLITE_OK ) break; |
| 120833 | if( (nBlob+35)>pgsz ){ |
| @@ -121768,55 +121879,31 @@ | |
| 121768 | |
| 121769 | *ppList = pList; |
| 121770 | *pnList = nList; |
| 121771 | } |
| 121772 | |
| 121773 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( |
| 121774 | Fts3Table *p, /* Virtual table handle */ |
| 121775 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 121776 | int iCol, /* Column to match on. */ |
| 121777 | const char *zTerm, /* Term to iterate through a doclist for */ |
| 121778 | int nTerm /* Number of bytes in zTerm */ |
| 121779 | ){ |
| 121780 | int i; |
| 121781 | int nSegment = pCsr->nSegment; |
| 121782 | int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( |
| 121783 | p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp |
| 121784 | ); |
| 121785 | |
| 121786 | assert( pCsr->pFilter==0 ); |
| 121787 | assert( zTerm && nTerm>0 ); |
| 121788 | |
| 121789 | /* Advance each segment iterator until it points to the term zTerm/nTerm. */ |
| 121790 | for(i=0; i<nSegment; i++){ |
| 121791 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 121792 | do { |
| 121793 | int rc = fts3SegReaderNext(p, pSeg, 1); |
| 121794 | if( rc!=SQLITE_OK ) return rc; |
| 121795 | }while( fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); |
| 121796 | } |
| 121797 | fts3SegReaderSort(pCsr->apSegment, nSegment, nSegment, fts3SegReaderCmp); |
| 121798 | |
| 121799 | /* Determine how many of the segments actually point to zTerm/nTerm. */ |
| 121800 | for(i=0; i<nSegment; i++){ |
| 121801 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 121802 | if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ |
| 121803 | break; |
| 121804 | } |
| 121805 | } |
| 121806 | pCsr->nAdvance = i; |
| 121807 | |
| 121808 | /* Advance each of the segments to point to the first docid. */ |
| 121809 | for(i=0; i<pCsr->nAdvance; i++){ |
| 121810 | int rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); |
| 121811 | if( rc!=SQLITE_OK ) return rc; |
| 121812 | } |
| 121813 | fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); |
| 121814 | |
| 121815 | assert( iCol<0 || iCol<p->nColumn ); |
| 121816 | pCsr->iColFilter = iCol; |
| 121817 | |
| 121818 | return SQLITE_OK; |
| 121819 | } |
| 121820 | |
| 121821 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 121822 | Fts3Table *p, /* Virtual table handle */ |
| @@ -121866,52 +121953,138 @@ | |
| 121866 | if( pMsr->iColFilter>=0 ){ |
| 121867 | fts3ColumnFilter(pMsr->iColFilter, &pList, &nList); |
| 121868 | } |
| 121869 | |
| 121870 | if( nList>0 ){ |
| 121871 | *piDocid = iDocid; |
| 121872 | *paPoslist = pList; |
| 121873 | *pnPoslist = nList; |
| 121874 | break; |
| 121875 | } |
| 121876 | } |
| 121877 | |
| 121878 | } |
| 121879 | |
| 121880 | return SQLITE_OK; |
| 121881 | } |
| 121882 | |
| 121883 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( |
| 121884 | Fts3Table *p, /* Virtual table handle */ |
| 121885 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 121886 | Fts3SegFilter *pFilter /* Restrictions on range of iteration */ |
| 121887 | ){ |
| 121888 | int i; |
| 121889 | |
| 121890 | /* Initialize the cursor object */ |
| 121891 | pCsr->pFilter = pFilter; |
| 121892 | |
| 121893 | /* If the Fts3SegFilter defines a specific term (or term prefix) to search |
| 121894 | ** for, then advance each segment iterator until it points to a term of |
| 121895 | ** equal or greater value than the specified term. This prevents many |
| 121896 | ** unnecessary merge/sort operations for the case where single segment |
| 121897 | ** b-tree leaf nodes contain more than one term. |
| 121898 | */ |
| 121899 | for(i=0; i<pCsr->nSegment; i++){ |
| 121900 | int nTerm = pFilter->nTerm; |
| 121901 | const char *zTerm = pFilter->zTerm; |
| 121902 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 121903 | do { |
| 121904 | int rc = fts3SegReaderNext(p, pSeg, 0); |
| 121905 | if( rc!=SQLITE_OK ) return rc; |
| 121906 | }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); |
| 121907 | } |
| 121908 | fts3SegReaderSort( |
| 121909 | pCsr->apSegment, pCsr->nSegment, pCsr->nSegment, fts3SegReaderCmp); |
| 121910 | |
| 121911 | return SQLITE_OK; |
| 121912 | } |
| 121913 | |
| 121914 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( |
| 121915 | Fts3Table *p, /* Virtual table handle */ |
| 121916 | Fts3MultiSegReader *pCsr /* Cursor object */ |
| 121917 | ){ |
| @@ -121981,13 +122154,18 @@ | |
| 121981 | assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); |
| 121982 | if( nMerge==1 |
| 121983 | && !isIgnoreEmpty |
| 121984 | && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) |
| 121985 | ){ |
| 121986 | pCsr->aDoclist = apSegment[0]->aDoclist; |
| 121987 | pCsr->nDoclist = apSegment[0]->nDoclist; |
| 121988 | rc = SQLITE_ROW; |
| 121989 | }else{ |
| 121990 | int nDoclist = 0; /* Size of doclist */ |
| 121991 | sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ |
| 121992 | |
| 121993 | /* The current term of the first nMerge entries in the array |
| @@ -123725,11 +123903,11 @@ | |
| 123725 | if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; |
| 123726 | break; |
| 123727 | |
| 123728 | case FTS3_MATCHINFO_NDOC: |
| 123729 | if( bGlobal ){ |
| 123730 | sqlite3_int64 nDoc; |
| 123731 | rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); |
| 123732 | pInfo->aMatchinfo[0] = (u32)nDoc; |
| 123733 | } |
| 123734 | break; |
| 123735 | |
| @@ -125620,11 +125798,11 @@ | |
| 125620 | */ |
| 125621 | static float cellArea(Rtree *pRtree, RtreeCell *p){ |
| 125622 | float area = 1.0; |
| 125623 | int ii; |
| 125624 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125625 | area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); |
| 125626 | } |
| 125627 | return area; |
| 125628 | } |
| 125629 | |
| 125630 | /* |
| @@ -125633,11 +125811,11 @@ | |
| 125633 | */ |
| 125634 | static float cellMargin(Rtree *pRtree, RtreeCell *p){ |
| 125635 | float margin = 0.0; |
| 125636 | int ii; |
| 125637 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125638 | margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); |
| 125639 | } |
| 125640 | return margin; |
| 125641 | } |
| 125642 | |
| 125643 | /* |
| @@ -125718,11 +125896,11 @@ | |
| 125718 | |
| 125719 | if( x2<x1 ){ |
| 125720 | o = 0.0; |
| 125721 | break; |
| 125722 | }else{ |
| 125723 | o = o * (x2-x1); |
| 125724 | } |
| 125725 | } |
| 125726 | overlap += o; |
| 125727 | } |
| 125728 | } |
| @@ -125737,16 +125915,16 @@ | |
| 125737 | RtreeCell *pInsert, |
| 125738 | RtreeCell *aCell, |
| 125739 | int nCell, |
| 125740 | int iExclude |
| 125741 | ){ |
| 125742 | float before; |
| 125743 | float after; |
| 125744 | before = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125745 | cellUnion(pRtree, p, pInsert); |
| 125746 | after = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125747 | return after-before; |
| 125748 | } |
| 125749 | #endif |
| 125750 | |
| 125751 | |
| 125752 | /* |
| @@ -125764,15 +125942,15 @@ | |
| 125764 | RtreeNode *pNode; |
| 125765 | rc = nodeAcquire(pRtree, 1, 0, &pNode); |
| 125766 | |
| 125767 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 125768 | int iCell; |
| 125769 | sqlite3_int64 iBest; |
| 125770 | |
| 125771 | float fMinGrowth; |
| 125772 | float fMinArea; |
| 125773 | float fMinOverlap; |
| 125774 | |
| 125775 | int nCell = NCELL(pNode); |
| 125776 | RtreeCell cell; |
| 125777 | RtreeNode *pChild; |
| 125778 | |
| @@ -126198,13 +126376,13 @@ | |
| 126198 | ){ |
| 126199 | int **aaSorted; |
| 126200 | int *aSpare; |
| 126201 | int ii; |
| 126202 | |
| 126203 | int iBestDim; |
| 126204 | int iBestSplit; |
| 126205 | float fBestMargin; |
| 126206 | |
| 126207 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 126208 | |
| 126209 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 126210 | if( !aaSorted ){ |
| @@ -126222,13 +126400,13 @@ | |
| 126222 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 126223 | } |
| 126224 | |
| 126225 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 126226 | float margin = 0.0; |
| 126227 | float fBestOverlap; |
| 126228 | float fBestArea; |
| 126229 | int iBestLeft; |
| 126230 | int nLeft; |
| 126231 | |
| 126232 | for( |
| 126233 | nLeft=RTREE_MINCELLS(pRtree); |
| 126234 | nLeft<=(nCell-RTREE_MINCELLS(pRtree)); |
| @@ -126539,11 +126717,11 @@ | |
| 126539 | static int deleteCell(Rtree *, RtreeNode *, int, int); |
| 126540 | |
| 126541 | static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ |
| 126542 | int rc; |
| 126543 | int rc2; |
| 126544 | RtreeNode *pParent; |
| 126545 | int iCell; |
| 126546 | |
| 126547 | assert( pNode->nRef==1 ); |
| 126548 | |
| 126549 | /* Remove the entry in the parent cell. */ |
| @@ -126687,23 +126865,23 @@ | |
| 126687 | }else{ |
| 126688 | nodeGetCell(pRtree, pNode, ii, &aCell[ii]); |
| 126689 | } |
| 126690 | aOrder[ii] = ii; |
| 126691 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126692 | aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); |
| 126693 | aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); |
| 126694 | } |
| 126695 | } |
| 126696 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126697 | aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0); |
| 126698 | } |
| 126699 | |
| 126700 | for(ii=0; ii<nCell; ii++){ |
| 126701 | aDistance[ii] = 0.0; |
| 126702 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126703 | float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) - |
| 126704 | DCOORD(aCell[ii].aCoord[iDim*2]); |
| 126705 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 126706 | } |
| 126707 | } |
| 126708 | |
| 126709 | SortByDistance(aOrder, nCell, aDistance, aSpare); |
| @@ -126798,14 +126976,14 @@ | |
| 126798 | nodeGetCell(pRtree, pNode, ii, &cell); |
| 126799 | |
| 126800 | /* Find a node to store this cell in. pNode->iNode currently contains |
| 126801 | ** the height of the sub-tree headed by the cell. |
| 126802 | */ |
| 126803 | rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert); |
| 126804 | if( rc==SQLITE_OK ){ |
| 126805 | int rc2; |
| 126806 | rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode); |
| 126807 | rc2 = nodeRelease(pRtree, pInsert); |
| 126808 | if( rc==SQLITE_OK ){ |
| 126809 | rc = rc2; |
| 126810 | } |
| 126811 | } |
| @@ -127190,11 +127368,11 @@ | |
| 127190 | int isCreate /* True for xCreate, false for xConnect */ |
| 127191 | ){ |
| 127192 | int rc; |
| 127193 | char *zSql; |
| 127194 | if( isCreate ){ |
| 127195 | int iPageSize; |
| 127196 | zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); |
| 127197 | rc = getIntFromStmt(db, zSql, &iPageSize); |
| 127198 | if( rc==SQLITE_OK ){ |
| 127199 | pRtree->iNodeSize = iPageSize-64; |
| 127200 | if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){ |
| @@ -127993,14 +128171,11 @@ | |
| 127993 | ** May you find forgiveness for yourself and forgive others. |
| 127994 | ** May you share freely, never taking more than you give. |
| 127995 | ** |
| 127996 | ************************************************************************* |
| 127997 | ** This file implements a tokenizer for fts3 based on the ICU library. |
| 127998 | ** |
| 127999 | ** $Id: fts3_icu.c,v 1.3 2008/09/01 18:34:20 danielk1977 Exp $ |
| 128000 | */ |
| 128001 | |
| 128002 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 128003 | #ifdef SQLITE_ENABLE_ICU |
| 128004 | |
| 128005 | |
| 128006 | #include <unicode/ubrk.h> |
| 128007 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -650,11 +650,11 @@ | |
| 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | */ |
| 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | #define SQLITE_SOURCE_ID "2011-06-24 11:29:51 9b191bb4c7c1e1b12b188c0b3eee1f8f587887c8" |
| 656 | |
| 657 | /* |
| 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | ** |
| @@ -851,11 +851,11 @@ | |
| 851 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 852 | ** in the context of the [database connection] passed in as its 1st |
| 853 | ** argument. ^If the callback function of the 3rd argument to |
| 854 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 855 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 856 | ** sqlite3_exec() is relayed through to the 1st argument of each |
| 857 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 858 | ** is NULL, then no callback is ever invoked and result rows are |
| 859 | ** ignored. |
| 860 | ** |
| 861 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -1443,11 +1443,11 @@ | |
| 1443 | ** The xSleep() method causes the calling thread to sleep for at |
| 1444 | ** least the number of microseconds given. ^The xCurrentTime() |
| 1445 | ** method returns a Julian Day Number for the current date and time as |
| 1446 | ** a floating point value. |
| 1447 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 1448 | ** Day Number multiplied by 86400000 (the number of milliseconds in |
| 1449 | ** a 24-hour day). |
| 1450 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 1451 | ** date and time if that method is available (if iVersion is 2 or |
| 1452 | ** greater and the function pointer is not NULL) and will fall back |
| 1453 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1881,11 +1881,11 @@ | |
| 1881 | ** scratch memory beyond what is provided by this configuration option, then |
| 1882 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1883 | ** |
| 1884 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1885 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1886 | ** the database page cache with the default page cache implementation. |
| 1887 | ** This configuration should not be used if an application-define page |
| 1888 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1889 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1890 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1891 | ** The sz argument should be the size of the largest database page |
| @@ -2979,16 +2979,16 @@ | |
| 2979 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2980 | ** |
| 2981 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2982 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2983 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2984 | ** set in the fourth argument to sqlite3_open_v2(), or if it has |
| 2985 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2986 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2987 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2988 | ** by default, but future releases of SQLite might enable URI filename |
| 2989 | ** interpretation by default. See "[URI filenames]" for additional |
| 2990 | ** information. |
| 2991 | ** |
| 2992 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2993 | ** authority, then it must be either an empty string or the string |
| 2994 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3803,11 +3803,11 @@ | |
| 3803 | ** [extended result codes] might be returned as well. |
| 3804 | ** |
| 3805 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3806 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3807 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3808 | ** statement. If the statement is not a [COMMIT] and occurs within an |
| 3809 | ** explicit transaction then you should rollback the transaction before |
| 3810 | ** continuing. |
| 3811 | ** |
| 3812 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3813 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -4082,11 +4082,11 @@ | |
| 4082 | |
| 4083 | /* |
| 4084 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 4085 | ** |
| 4086 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 4087 | ** ^If the most recent evaluation of the statement encountered no errors |
| 4088 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 4089 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 4090 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 4091 | ** [extended error code]. |
| 4092 | ** |
| @@ -5996,11 +5996,11 @@ | |
| 5996 | ** versions of these routines, it should at least provide stubs that always |
| 5997 | ** return true so that one does not get spurious assertion failures. |
| 5998 | ** |
| 5999 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 6000 | ** the routine should return 1. This seems counter-intuitive since |
| 6001 | ** clearly the mutex cannot be held if it does not exist. But |
| 6002 | ** the reason the mutex does not exist is because the build is not |
| 6003 | ** using mutexes. And we do not want the assert() containing the |
| 6004 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 6005 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 6006 | ** interface should also return 1 when given a NULL pointer. |
| @@ -6119,11 +6119,12 @@ | |
| 6119 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 6120 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 6121 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 6122 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 6123 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 6124 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 |
| 6125 | #define SQLITE_TESTCTRL_LAST 19 |
| 6126 | |
| 6127 | /* |
| 6128 | ** CAPI3REF: SQLite Runtime Status |
| 6129 | ** |
| 6130 | ** ^This interface is used to retrieve runtime status information |
| @@ -6505,11 +6506,11 @@ | |
| 6506 | ** [[the xFetch() page cache methods]] |
| 6507 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 6508 | ** the page, or a NULL pointer. |
| 6509 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 6510 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 6511 | ** minimum key value is 1. After it has been retrieved using xFetch, the page |
| 6512 | ** is considered to be "pinned". |
| 6513 | ** |
| 6514 | ** If the requested page is already in the page cache, then the page cache |
| 6515 | ** implementation must return a pointer to the page buffer with its content |
| 6516 | ** intact. If the requested page is not already in the cache, then the |
| @@ -9556,10 +9557,11 @@ | |
| 9557 | #define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ |
| 9558 | #define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ |
| 9559 | #define SQLITE_IndexCover 0x10 /* Disable index covering table */ |
| 9560 | #define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ |
| 9561 | #define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ |
| 9562 | #define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ |
| 9563 | #define SQLITE_OptMask 0xff /* Mask of all disablable opts */ |
| 9564 | |
| 9565 | /* |
| 9566 | ** Possible values for the sqlite.magic field. |
| 9567 | ** The numbers are obtained at random and have no special meaning, other |
| @@ -11053,10 +11055,11 @@ | |
| 11055 | int isPCacheInit; /* True after malloc is initialized */ |
| 11056 | sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ |
| 11057 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 11058 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 11059 | void *pLogArg; /* First argument to xLog() */ |
| 11060 | int bLocaltimeFault; /* True to fail localtime() calls */ |
| 11061 | }; |
| 11062 | |
| 11063 | /* |
| 11064 | ** Context pointer passed down through the tree-walk. |
| 11065 | */ |
| @@ -12013,10 +12016,11 @@ | |
| 12016 | 0, /* isPCacheInit */ |
| 12017 | 0, /* pInitMutex */ |
| 12018 | 0, /* nRefInitMutex */ |
| 12019 | 0, /* xLog */ |
| 12020 | 0, /* pLogArg */ |
| 12021 | 0, /* bLocaltimeFault */ |
| 12022 | }; |
| 12023 | |
| 12024 | |
| 12025 | /* |
| 12026 | ** Hash table for global functions - functions common to all |
| @@ -13163,26 +13167,10 @@ | |
| 13167 | */ |
| 13168 | #include <time.h> |
| 13169 | |
| 13170 | #ifndef SQLITE_OMIT_DATETIME_FUNCS |
| 13171 | |
| 13172 | |
| 13173 | /* |
| 13174 | ** A structure for holding a single date and time. |
| 13175 | */ |
| 13176 | typedef struct DateTime DateTime; |
| @@ -13523,20 +13511,90 @@ | |
| 13511 | static void clearYMD_HMS_TZ(DateTime *p){ |
| 13512 | p->validYMD = 0; |
| 13513 | p->validHMS = 0; |
| 13514 | p->validTZ = 0; |
| 13515 | } |
| 13516 | |
| 13517 | /* |
| 13518 | ** On recent Windows platforms, the localtime_s() function is available |
| 13519 | ** as part of the "Secure CRT". It is essentially equivalent to |
| 13520 | ** localtime_r() available under most POSIX platforms, except that the |
| 13521 | ** order of the parameters is reversed. |
| 13522 | ** |
| 13523 | ** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. |
| 13524 | ** |
| 13525 | ** If the user has not indicated to use localtime_r() or localtime_s() |
| 13526 | ** already, check for an MSVC build environment that provides |
| 13527 | ** localtime_s(). |
| 13528 | */ |
| 13529 | #if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ |
| 13530 | defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
| 13531 | #define HAVE_LOCALTIME_S 1 |
| 13532 | #endif |
| 13533 | |
| 13534 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13535 | /* |
| 13536 | ** The following routine implements the rough equivalent of localtime_r() |
| 13537 | ** using whatever operating-system specific localtime facility that |
| 13538 | ** is available. This routine returns 0 on success and |
| 13539 | ** non-zero on any kind of error. |
| 13540 | ** |
| 13541 | ** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this |
| 13542 | ** routine will always fail. |
| 13543 | */ |
| 13544 | static int osLocaltime(time_t *t, struct tm *pTm){ |
| 13545 | int rc; |
| 13546 | #if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ |
| 13547 | && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) |
| 13548 | struct tm *pX; |
| 13549 | #if SQLITE_THREADSAFE>0 |
| 13550 | sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
| 13551 | #endif |
| 13552 | sqlite3_mutex_enter(mutex); |
| 13553 | pX = localtime(t); |
| 13554 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 13555 | if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; |
| 13556 | #endif |
| 13557 | if( pX ) *pTm = *pX; |
| 13558 | sqlite3_mutex_leave(mutex); |
| 13559 | rc = pX==0; |
| 13560 | #else |
| 13561 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 13562 | if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; |
| 13563 | #endif |
| 13564 | #if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R |
| 13565 | rc = localtime_r(t, pTm)==0; |
| 13566 | #else |
| 13567 | rc = localtime_s(pTm, t); |
| 13568 | #endif /* HAVE_LOCALTIME_R */ |
| 13569 | #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ |
| 13570 | return rc; |
| 13571 | } |
| 13572 | #endif /* SQLITE_OMIT_LOCALTIME */ |
| 13573 | |
| 13574 | |
| 13575 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13576 | /* |
| 13577 | ** Compute the difference (in milliseconds) between localtime and UTC |
| 13578 | ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, |
| 13579 | ** return this value and set *pRc to SQLITE_OK. |
| 13580 | ** |
| 13581 | ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value |
| 13582 | ** is undefined in this case. |
| 13583 | */ |
| 13584 | static sqlite3_int64 localtimeOffset( |
| 13585 | DateTime *p, /* Date at which to calculate offset */ |
| 13586 | sqlite3_context *pCtx, /* Write error here if one occurs */ |
| 13587 | int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ |
| 13588 | ){ |
| 13589 | DateTime x, y; |
| 13590 | time_t t; |
| 13591 | struct tm sLocal; |
| 13592 | |
| 13593 | /* Initialize the contents of sLocal to avoid a compiler warning. */ |
| 13594 | memset(&sLocal, 0, sizeof(sLocal)); |
| 13595 | |
| 13596 | x = *p; |
| 13597 | computeYMD_HMS(&x); |
| 13598 | if( x.Y<1971 || x.Y>=2038 ){ |
| 13599 | x.Y = 2000; |
| 13600 | x.M = 1; |
| @@ -13550,51 +13608,27 @@ | |
| 13608 | } |
| 13609 | x.tz = 0; |
| 13610 | x.validJD = 0; |
| 13611 | computeJD(&x); |
| 13612 | t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); |
| 13613 | if( osLocaltime(&t, &sLocal) ){ |
| 13614 | sqlite3_result_error(pCtx, "local time unavailable", -1); |
| 13615 | *pRc = SQLITE_ERROR; |
| 13616 | return 0; |
| 13617 | } |
| 13618 | y.Y = sLocal.tm_year + 1900; |
| 13619 | y.M = sLocal.tm_mon + 1; |
| 13620 | y.D = sLocal.tm_mday; |
| 13621 | y.h = sLocal.tm_hour; |
| 13622 | y.m = sLocal.tm_min; |
| 13623 | y.s = sLocal.tm_sec; |
| 13624 | y.validYMD = 1; |
| 13625 | y.validHMS = 1; |
| 13626 | y.validJD = 0; |
| 13627 | y.validTZ = 0; |
| 13628 | computeJD(&y); |
| 13629 | *pRc = SQLITE_OK; |
| 13630 | return y.iJD - x.iJD; |
| 13631 | } |
| 13632 | #endif /* SQLITE_OMIT_LOCALTIME */ |
| 13633 | |
| 13634 | /* |
| @@ -13614,13 +13648,16 @@ | |
| 13648 | ** weekday N |
| 13649 | ** unixepoch |
| 13650 | ** localtime |
| 13651 | ** utc |
| 13652 | ** |
| 13653 | ** Return 0 on success and 1 if there is any kind of error. If the error |
| 13654 | ** is in a system call (i.e. localtime()), then an error message is written |
| 13655 | ** to context pCtx. If the error is an unrecognized modifier, no error is |
| 13656 | ** written to pCtx. |
| 13657 | */ |
| 13658 | static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ |
| 13659 | int rc = 1; |
| 13660 | int n; |
| 13661 | double r; |
| 13662 | char *z, zBuf[30]; |
| 13663 | z = zBuf; |
| @@ -13636,13 +13673,12 @@ | |
| 13673 | ** Assuming the current time value is UTC (a.k.a. GMT), shift it to |
| 13674 | ** show local time. |
| 13675 | */ |
| 13676 | if( strcmp(z, "localtime")==0 ){ |
| 13677 | computeJD(p); |
| 13678 | p->iJD += localtimeOffset(p, pCtx, &rc); |
| 13679 | clearYMD_HMS_TZ(p); |
| 13680 | } |
| 13681 | break; |
| 13682 | } |
| 13683 | #endif |
| 13684 | case 'u': { |
| @@ -13659,15 +13695,16 @@ | |
| 13695 | } |
| 13696 | #ifndef SQLITE_OMIT_LOCALTIME |
| 13697 | else if( strcmp(z, "utc")==0 ){ |
| 13698 | sqlite3_int64 c1; |
| 13699 | computeJD(p); |
| 13700 | c1 = localtimeOffset(p, pCtx, &rc); |
| 13701 | if( rc==SQLITE_OK ){ |
| 13702 | p->iJD -= c1; |
| 13703 | clearYMD_HMS_TZ(p); |
| 13704 | p->iJD += c1 - localtimeOffset(p, pCtx, &rc); |
| 13705 | } |
| 13706 | } |
| 13707 | #endif |
| 13708 | break; |
| 13709 | } |
| 13710 | case 'w': { |
| @@ -13844,13 +13881,12 @@ | |
| 13881 | if( !z || parseDateOrTime(context, (char*)z, p) ){ |
| 13882 | return 1; |
| 13883 | } |
| 13884 | } |
| 13885 | for(i=1; i<argc; i++){ |
| 13886 | z = sqlite3_value_text(argv[i]); |
| 13887 | if( z==0 || parseModifier(context, (char*)z, p) ) return 1; |
| 13888 | } |
| 13889 | return 0; |
| 13890 | } |
| 13891 | |
| 13892 | |
| @@ -24364,10 +24400,14 @@ | |
| 24400 | |
| 24401 | #if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) |
| 24402 | # include <sys/mount.h> |
| 24403 | #endif |
| 24404 | |
| 24405 | #ifdef HAVE_UTIME |
| 24406 | # include <utime.h> |
| 24407 | #endif |
| 24408 | |
| 24409 | /* |
| 24410 | ** Allowed values of unixFile.fsFlags |
| 24411 | */ |
| 24412 | #define SQLITE_FSFLAGS_IS_MSDOS 0x1 |
| 24413 | |
| @@ -26369,12 +26409,14 @@ | |
| 26409 | /* If we have any lock, then the lock file already exists. All we have |
| 26410 | ** to do is adjust our internal record of the lock level. |
| 26411 | */ |
| 26412 | if( pFile->eFileLock > NO_LOCK ){ |
| 26413 | pFile->eFileLock = eFileLock; |
| 26414 | /* Always update the timestamp on the old file */ |
| 26415 | #ifdef HAVE_UTIME |
| 26416 | utime(zLockFile, NULL); |
| 26417 | #else |
| 26418 | utimes(zLockFile, NULL); |
| 26419 | #endif |
| 26420 | return SQLITE_OK; |
| 26421 | } |
| 26422 | |
| @@ -28096,11 +28138,11 @@ | |
| 28138 | unixShmNode *p = pFd->pInode->pShmNode; |
| 28139 | assert( unixMutexHeld() ); |
| 28140 | if( p && p->nRef==0 ){ |
| 28141 | int i; |
| 28142 | assert( p->pInode==pFd->pInode ); |
| 28143 | sqlite3_mutex_free(p->mutex); |
| 28144 | for(i=0; i<p->nRegion; i++){ |
| 28145 | if( p->h>=0 ){ |
| 28146 | munmap(p->apRegion[i], p->szRegion); |
| 28147 | }else{ |
| 28148 | sqlite3_free(p->apRegion[i]); |
| @@ -32254,11 +32296,12 @@ | |
| 32296 | rc = 1; |
| 32297 | } |
| 32298 | } |
| 32299 | |
| 32300 | if( rc ){ |
| 32301 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 32302 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 32303 | return SQLITE_FULL; |
| 32304 | } |
| 32305 | return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); |
| 32306 | } |
| 32307 | return SQLITE_OK; |
| @@ -61205,10 +61248,18 @@ | |
| 61248 | rc = db->errCode = p->rc; |
| 61249 | } |
| 61250 | return (rc&db->errMask); |
| 61251 | } |
| 61252 | |
| 61253 | /* |
| 61254 | ** The maximum number of times that a statement will try to reparse |
| 61255 | ** itself before giving up and returning SQLITE_SCHEMA. |
| 61256 | */ |
| 61257 | #ifndef SQLITE_MAX_SCHEMA_RETRY |
| 61258 | # define SQLITE_MAX_SCHEMA_RETRY 5 |
| 61259 | #endif |
| 61260 | |
| 61261 | /* |
| 61262 | ** This is the top-level implementation of sqlite3_step(). Call |
| 61263 | ** sqlite3Step() to do most of the work. If a schema error occurs, |
| 61264 | ** call sqlite3Reprepare() and try again. |
| 61265 | */ |
| @@ -61223,11 +61274,11 @@ | |
| 61274 | return SQLITE_MISUSE_BKPT; |
| 61275 | } |
| 61276 | db = v->db; |
| 61277 | sqlite3_mutex_enter(db->mutex); |
| 61278 | while( (rc = sqlite3Step(v))==SQLITE_SCHEMA |
| 61279 | && cnt++ < SQLITE_MAX_SCHEMA_RETRY |
| 61280 | && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ |
| 61281 | sqlite3_reset(pStmt); |
| 61282 | v->expired = 0; |
| 61283 | } |
| 61284 | if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ |
| @@ -63496,11 +63547,11 @@ | |
| 63547 | break; |
| 63548 | } |
| 63549 | |
| 63550 | /* Opcode: HaltIfNull P1 P2 P3 P4 * |
| 63551 | ** |
| 63552 | ** Check the value in register P3. If it is NULL then Halt using |
| 63553 | ** parameter P1, P2, and P4 as if this were a Halt instruction. If the |
| 63554 | ** value in register P3 is not NULL, then this routine is a no-op. |
| 63555 | */ |
| 63556 | case OP_HaltIfNull: { /* in3 */ |
| 63557 | pIn3 = &aMem[pOp->p3]; |
| @@ -64433,11 +64484,11 @@ | |
| 64484 | ** additional information. |
| 64485 | ** |
| 64486 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64487 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64488 | ** of comparison is false. If either operand is NULL then the result is true. |
| 64489 | ** If neither operand is NULL the result is the same as it would be if |
| 64490 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64491 | */ |
| 64492 | /* Opcode: Eq P1 P2 P3 P4 P5 |
| 64493 | ** |
| 64494 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64445,11 +64496,11 @@ | |
| 64496 | ** See the Lt opcode for additional information. |
| 64497 | ** |
| 64498 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
| 64499 | ** true or false and is never NULL. If both operands are NULL then the result |
| 64500 | ** of comparison is true. If either operand is NULL then the result is false. |
| 64501 | ** If neither operand is NULL the result is the same as it would be if |
| 64502 | ** the SQLITE_NULLEQ flag were omitted from P5. |
| 64503 | */ |
| 64504 | /* Opcode: Le P1 P2 P3 P4 P5 |
| 64505 | ** |
| 64506 | ** This works just like the Lt opcode except that the jump is taken if |
| @@ -64730,17 +64781,17 @@ | |
| 64781 | break; |
| 64782 | } |
| 64783 | |
| 64784 | /* Opcode: If P1 P2 P3 * * |
| 64785 | ** |
| 64786 | ** Jump to P2 if the value in register P1 is true. The value |
| 64787 | ** is considered true if it is numeric and non-zero. If the value |
| 64788 | ** in P1 is NULL then take the jump if P3 is true. |
| 64789 | */ |
| 64790 | /* Opcode: IfNot P1 P2 P3 * * |
| 64791 | ** |
| 64792 | ** Jump to P2 if the value in register P1 is False. The value |
| 64793 | ** is considered true if it has a numeric value of zero. If the value |
| 64794 | ** in P1 is NULL then take the jump if P3 is true. |
| 64795 | */ |
| 64796 | case OP_If: /* jump, in1 */ |
| 64797 | case OP_IfNot: { /* jump, in1 */ |
| @@ -66390,11 +66441,11 @@ | |
| 66441 | break; |
| 66442 | } |
| 66443 | |
| 66444 | /* Opcode: NotExists P1 P2 P3 * * |
| 66445 | ** |
| 66446 | ** Use the content of register P3 as an integer key. If a record |
| 66447 | ** with that key does not exist in table of P1, then jump to P2. |
| 66448 | ** If the record does exist, then fall through. The cursor is left |
| 66449 | ** pointing to the record if it exists. |
| 66450 | ** |
| 66451 | ** The difference between this operation and NotFound is that this |
| @@ -66468,11 +66519,11 @@ | |
| 66519 | ** written to register P2. |
| 66520 | ** |
| 66521 | ** If P3>0 then P3 is a register in the root frame of this VDBE that holds |
| 66522 | ** the largest previously generated record number. No new record numbers are |
| 66523 | ** allowed to be less than this value. When this value reaches its maximum, |
| 66524 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 66525 | ** generated record number. This P3 mechanism is used to help implement the |
| 66526 | ** AUTOINCREMENT feature. |
| 66527 | */ |
| 66528 | case OP_NewRowid: { /* out2-prerelease */ |
| 66529 | #if 0 /* local variables moved into u.be */ |
| @@ -67110,11 +67161,11 @@ | |
| 67161 | break; |
| 67162 | } |
| 67163 | |
| 67164 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 67165 | ** |
| 67166 | ** Register P2 holds an SQL index key made using the |
| 67167 | ** MakeRecord instructions. This opcode writes that key |
| 67168 | ** into the index P1. Data for the entry is nil. |
| 67169 | ** |
| 67170 | ** P3 is a flag that provides a hint to the b-tree layer that this |
| 67171 | ** insert is likely to be an append. |
| @@ -82135,12 +82186,18 @@ | |
| 82186 | sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); |
| 82187 | sqlite3ColumnDefault(v, pTab, idx, -1); |
| 82188 | } |
| 82189 | } |
| 82190 | if( doMakeRec ){ |
| 82191 | const char *zAff; |
| 82192 | if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ |
| 82193 | zAff = 0; |
| 82194 | }else{ |
| 82195 | zAff = sqlite3IndexAffinityStr(v, pIdx); |
| 82196 | } |
| 82197 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); |
| 82198 | sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); |
| 82199 | } |
| 82200 | sqlite3ReleaseTempRange(pParse, regBase, nCol+1); |
| 82201 | return regBase; |
| 82202 | } |
| 82203 | |
| @@ -110763,10 +110820,21 @@ | |
| 110820 | if( sz ) *ppNew = sqlite3ScratchMalloc(sz); |
| 110821 | sqlite3ScratchFree(pFree); |
| 110822 | break; |
| 110823 | } |
| 110824 | |
| 110825 | /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); |
| 110826 | ** |
| 110827 | ** If parameter onoff is non-zero, configure the wrappers so that all |
| 110828 | ** subsequent calls to localtime() and variants fail. If onoff is zero, |
| 110829 | ** undo this setting. |
| 110830 | */ |
| 110831 | case SQLITE_TESTCTRL_LOCALTIME_FAULT: { |
| 110832 | sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); |
| 110833 | break; |
| 110834 | } |
| 110835 | |
| 110836 | } |
| 110837 | va_end(ap); |
| 110838 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 110839 | return rc; |
| 110840 | } |
| @@ -111420,16 +111488,10 @@ | |
| 111488 | ** TODO(shess) Provide a VACUUM type operation to clear out all |
| 111489 | ** deletions and duplications. This would basically be a forced merge |
| 111490 | ** into a single segment. |
| 111491 | */ |
| 111492 | |
| 111493 | /************** Include fts3Int.h in the middle of fts3.c ********************/ |
| 111494 | /************** Begin file fts3Int.h *****************************************/ |
| 111495 | /* |
| 111496 | ** 2009 Nov 12 |
| 111497 | ** |
| @@ -111441,18 +111503,27 @@ | |
| 111503 | ** May you share freely, never taking more than you give. |
| 111504 | ** |
| 111505 | ****************************************************************************** |
| 111506 | ** |
| 111507 | */ |
| 111508 | #ifndef _FTSINT_H |
| 111509 | #define _FTSINT_H |
| 111510 | |
| 111511 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 111512 | # define NDEBUG 1 |
| 111513 | #endif |
| 111514 | |
| 111515 | /* |
| 111516 | ** FTS4 is really an extension for FTS3. It is enabled using the |
| 111517 | ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all |
| 111518 | ** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. |
| 111519 | */ |
| 111520 | #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) |
| 111521 | # define SQLITE_ENABLE_FTS3 |
| 111522 | #endif |
| 111523 | |
| 111524 | #ifdef SQLITE_ENABLE_FTS3 |
| 111525 | /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ |
| 111526 | /************** Begin file fts3_tokenizer.h **********************************/ |
| 111527 | /* |
| 111528 | ** 2006 July 10 |
| 111529 | ** |
| @@ -111940,11 +112011,11 @@ | |
| 112011 | char *aDoclist; /* List of docids for full-text queries */ |
| 112012 | int nDoclist; /* Size of buffer at aDoclist */ |
| 112013 | u8 bDesc; /* True to sort in descending order */ |
| 112014 | int eEvalmode; /* An FTS3_EVAL_XX constant */ |
| 112015 | int nRowAvg; /* Average size of database rows, in pages */ |
| 112016 | sqlite3_int64 nDoc; /* Documents in table */ |
| 112017 | |
| 112018 | int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ |
| 112019 | u32 *aMatchinfo; /* Information about most recent match */ |
| 112020 | int nMatchinfo; /* Number of elements in aMatchinfo[] */ |
| 112021 | char *zMatchinfo; /* Matchinfo specification */ |
| @@ -111997,19 +112068,19 @@ | |
| 112068 | int isPrefix; /* True if token ends with a "*" character */ |
| 112069 | |
| 112070 | /* Variables above this point are populated when the expression is |
| 112071 | ** parsed (by code in fts3_expr.c). Below this point the variables are |
| 112072 | ** used when evaluating the expression. */ |
| 112073 | Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ |
| 112074 | Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ |
| 112075 | }; |
| 112076 | |
| 112077 | struct Fts3Phrase { |
| 112078 | /* Cache of doclist for this phrase. */ |
| 112079 | Fts3Doclist doclist; |
| 112080 | int bIncr; /* True if doclist is loaded incrementally */ |
| 112081 | int iDoclistToken; |
| 112082 | |
| 112083 | /* Variables below this point are populated by fts3_expr.c when parsing |
| 112084 | ** a MATCH expression. Everything above is part of the evaluation phase. |
| 112085 | */ |
| 112086 | int nToken; /* Number of tokens in the phrase */ |
| @@ -112130,10 +112201,11 @@ | |
| 112201 | Fts3SegFilter *pFilter; /* Pointer to filter object */ |
| 112202 | char *aBuffer; /* Buffer to merge doclists in */ |
| 112203 | int nBuffer; /* Allocated size of aBuffer[] in bytes */ |
| 112204 | |
| 112205 | int iColFilter; /* If >=0, filter for this column */ |
| 112206 | int bRestart; |
| 112207 | |
| 112208 | /* Used by fts3.c only. */ |
| 112209 | int nCost; /* Cost of running iterator */ |
| 112210 | int bLookup; /* True if a lookup of a single entry. */ |
| 112211 | |
| @@ -112199,18 +112271,24 @@ | |
| 112271 | Fts3Table*, Fts3MultiSegReader*, int, const char*, int); |
| 112272 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 112273 | Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); |
| 112274 | SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol); |
| 112275 | SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); |
| 112276 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); |
| 112277 | |
| 112278 | SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); |
| 112279 | |
| 112280 | #endif /* SQLITE_ENABLE_FTS3 */ |
| 112281 | #endif /* _FTSINT_H */ |
| 112282 | |
| 112283 | /************** End of fts3Int.h *********************************************/ |
| 112284 | /************** Continuing where we left off in fts3.c ***********************/ |
| 112285 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 112286 | |
| 112287 | #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) |
| 112288 | # define SQLITE_CORE 1 |
| 112289 | #endif |
| 112290 | |
| 112291 | |
| 112292 | #ifndef SQLITE_CORE |
| 112293 | SQLITE_EXTENSION_INIT1 |
| 112294 | #endif |
| @@ -112545,10 +112623,13 @@ | |
| 112623 | rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); |
| 112624 | if( rc==SQLITE_OK ){ |
| 112625 | sqlite3_step(pStmt); |
| 112626 | p->nPgsz = sqlite3_column_int(pStmt, 0); |
| 112627 | rc = sqlite3_finalize(pStmt); |
| 112628 | }else if( rc==SQLITE_AUTH ){ |
| 112629 | p->nPgsz = 1024; |
| 112630 | rc = SQLITE_OK; |
| 112631 | } |
| 112632 | } |
| 112633 | assert( p->nPgsz>0 || rc!=SQLITE_OK ); |
| 112634 | sqlite3_free(zSql); |
| 112635 | *pRc = rc; |
| @@ -112995,11 +113076,11 @@ | |
| 113076 | zCsr += nDb; |
| 113077 | |
| 113078 | /* Fill in the azColumn array */ |
| 113079 | for(iCol=0; iCol<nCol; iCol++){ |
| 113080 | char *z; |
| 113081 | int n = 0; |
| 113082 | z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n); |
| 113083 | memcpy(zCsr, z, n); |
| 113084 | zCsr[n] = '\0'; |
| 113085 | sqlite3Fts3Dequote(zCsr); |
| 113086 | p->azColumn[iCol] = zCsr; |
| @@ -114581,12 +114662,12 @@ | |
| 114662 | |
| 114663 | /* |
| 114664 | ** Implementation of xBegin() method. This is a no-op. |
| 114665 | */ |
| 114666 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114667 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114668 | UNUSED_PARAMETER(pVtab); |
| 114669 | assert( p->pSegments==0 ); |
| 114670 | assert( p->nPendingData==0 ); |
| 114671 | assert( p->inTransaction!=1 ); |
| 114672 | TESTONLY( p->inTransaction = 1 ); |
| 114673 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -114597,12 +114678,12 @@ | |
| 114678 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| 114679 | ** the pending-terms hash-table have already been flushed into the database |
| 114680 | ** by fts3SyncMethod(). |
| 114681 | */ |
| 114682 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114683 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 114684 | UNUSED_PARAMETER(pVtab); |
| 114685 | assert( p->nPendingData==0 ); |
| 114686 | assert( p->inTransaction!=0 ); |
| 114687 | assert( p->pSegments==0 ); |
| 114688 | TESTONLY( p->inTransaction = 0 ); |
| 114689 | TESTONLY( p->mxSavepoint = -1; ); |
| @@ -115083,75 +115164,105 @@ | |
| 115164 | if( rc!=SQLITE_OK ){ |
| 115165 | *pRc = rc; |
| 115166 | return; |
| 115167 | } |
| 115168 | } |
| 115169 | assert( pExpr->pPhrase->iDoclistToken==0 ); |
| 115170 | pExpr->pPhrase->iDoclistToken = -1; |
| 115171 | }else{ |
| 115172 | *pnOr += (pExpr->eType==FTSQUERY_OR); |
| 115173 | fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); |
| 115174 | fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); |
| 115175 | } |
| 115176 | } |
| 115177 | } |
| 115178 | |
| 115179 | static void fts3EvalPhraseMergeToken( |
| 115180 | Fts3Table *pTab, |
| 115181 | Fts3Phrase *p, |
| 115182 | int iToken, |
| 115183 | char *pList, |
| 115184 | int nList |
| 115185 | ){ |
| 115186 | assert( iToken!=p->iDoclistToken ); |
| 115187 | |
| 115188 | if( pList==0 ){ |
| 115189 | sqlite3_free(p->doclist.aAll); |
| 115190 | p->doclist.aAll = 0; |
| 115191 | p->doclist.nAll = 0; |
| 115192 | } |
| 115193 | |
| 115194 | else if( p->iDoclistToken<0 ){ |
| 115195 | p->doclist.aAll = pList; |
| 115196 | p->doclist.nAll = nList; |
| 115197 | } |
| 115198 | |
| 115199 | else if( p->doclist.aAll==0 ){ |
| 115200 | sqlite3_free(pList); |
| 115201 | } |
| 115202 | |
| 115203 | else { |
| 115204 | char *pLeft; |
| 115205 | char *pRight; |
| 115206 | int nLeft; |
| 115207 | int nRight; |
| 115208 | int nDiff; |
| 115209 | |
| 115210 | if( p->iDoclistToken<iToken ){ |
| 115211 | pLeft = p->doclist.aAll; |
| 115212 | nLeft = p->doclist.nAll; |
| 115213 | pRight = pList; |
| 115214 | nRight = nList; |
| 115215 | nDiff = iToken - p->iDoclistToken; |
| 115216 | }else{ |
| 115217 | pRight = p->doclist.aAll; |
| 115218 | nRight = p->doclist.nAll; |
| 115219 | pLeft = pList; |
| 115220 | nLeft = nList; |
| 115221 | nDiff = p->iDoclistToken - iToken; |
| 115222 | } |
| 115223 | |
| 115224 | fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight); |
| 115225 | sqlite3_free(pLeft); |
| 115226 | p->doclist.aAll = pRight; |
| 115227 | p->doclist.nAll = nRight; |
| 115228 | } |
| 115229 | |
| 115230 | if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; |
| 115231 | } |
| 115232 | |
| 115233 | static int fts3EvalPhraseLoad( |
| 115234 | Fts3Cursor *pCsr, |
| 115235 | Fts3Phrase *p |
| 115236 | ){ |
| 115237 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115238 | int iToken; |
| 115239 | int rc = SQLITE_OK; |
| 115240 | |
| 115241 | for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){ |
| 115242 | Fts3PhraseToken *pToken = &p->aToken[iToken]; |
| 115243 | assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); |
| 115244 | |
| 115245 | if( pToken->pSegcsr ){ |
| 115246 | int nThis = 0; |
| 115247 | char *pThis = 0; |
| 115248 | rc = fts3TermSelect(pTab, pToken, p->iColumn, 1, &nThis, &pThis); |
| 115249 | if( rc==SQLITE_OK ){ |
| 115250 | fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); |
| 115251 | } |
| 115252 | } |
| 115253 | assert( pToken->pSegcsr==0 ); |
| 115254 | } |
| 115255 | |
| 115256 | return rc; |
| 115257 | } |
| 115258 | |
| 115259 | static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ |
| 115260 | int iToken; |
| 115261 | int rc = SQLITE_OK; |
| 115262 | |
| 115263 | int nMaxUndeferred = pPhrase->iDoclistToken; |
| 115264 | char *aPoslist = 0; |
| 115265 | int nPoslist = 0; |
| 115266 | int iPrev = -1; |
| 115267 | |
| 115268 | assert( pPhrase->doclist.bFreeList==0 ); |
| @@ -115192,12 +115303,10 @@ | |
| 115303 | pPhrase->doclist.nList = 0; |
| 115304 | return SQLITE_OK; |
| 115305 | } |
| 115306 | } |
| 115307 | iPrev = iToken; |
| 115308 | } |
| 115309 | } |
| 115310 | |
| 115311 | if( iPrev>=0 ){ |
| 115312 | if( nMaxUndeferred<0 ){ |
| @@ -115252,13 +115361,15 @@ | |
| 115361 | static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ |
| 115362 | int rc; |
| 115363 | Fts3PhraseToken *pFirst = &p->aToken[0]; |
| 115364 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 115365 | |
| 115366 | if( pCsr->bDesc==pTab->bDescIdx |
| 115367 | && bOptOk==1 |
| 115368 | && p->nToken==1 |
| 115369 | && pFirst->pSegcsr |
| 115370 | && pFirst->pSegcsr->bLookup |
| 115371 | ){ |
| 115372 | /* Use the incremental approach. */ |
| 115373 | int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); |
| 115374 | rc = sqlite3Fts3MsrIncrStart( |
| 115375 | pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); |
| @@ -115394,11 +115505,11 @@ | |
| 115505 | ** with this case by advancing pIter past the zero-padding added by |
| 115506 | ** fts3EvalNearTrim2(). */ |
| 115507 | while( pIter<pEnd && *pIter==0 ) pIter++; |
| 115508 | |
| 115509 | pDL->pNextDocid = pIter; |
| 115510 | assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); |
| 115511 | *pbEof = 0; |
| 115512 | } |
| 115513 | } |
| 115514 | |
| 115515 | return rc; |
| @@ -115425,17 +115536,18 @@ | |
| 115536 | pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); |
| 115537 | } |
| 115538 | } |
| 115539 | } |
| 115540 | |
| 115541 | typedef struct Fts3TokenAndCost Fts3TokenAndCost; |
| 115542 | struct Fts3TokenAndCost { |
| 115543 | Fts3Phrase *pPhrase; /* The phrase the token belongs to */ |
| 115544 | int iToken; /* Position of token in phrase */ |
| 115545 | Fts3PhraseToken *pToken; /* The token itself */ |
| 115546 | Fts3Expr *pRoot; |
| 115547 | int nOvfl; |
| 115548 | int iCol; /* The column the token must match */ |
| 115549 | }; |
| 115550 | |
| 115551 | static void fts3EvalTokenCosts( |
| 115552 | Fts3Cursor *pCsr, |
| 115553 | Fts3Expr *pRoot, |
| @@ -115448,10 +115560,12 @@ | |
| 115560 | if( pExpr->eType==FTSQUERY_PHRASE ){ |
| 115561 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 115562 | int i; |
| 115563 | for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){ |
| 115564 | Fts3TokenAndCost *pTC = (*ppTC)++; |
| 115565 | pTC->pPhrase = pPhrase; |
| 115566 | pTC->iToken = i; |
| 115567 | pTC->pRoot = pRoot; |
| 115568 | pTC->pToken = &pPhrase->aToken[i]; |
| 115569 | pTC->iCol = pPhrase->iColumn; |
| 115570 | *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); |
| 115571 | } |
| @@ -115560,23 +115674,19 @@ | |
| 115674 | /* At this point pTC points to the cheapest remaining token. */ |
| 115675 | if( ii==0 ){ |
| 115676 | if( pTC->nOvfl ){ |
| 115677 | nDocEst = (pTC->nOvfl * pTab->nPgsz + pTab->nPgsz) / 10; |
| 115678 | }else{ |
| 115679 | Fts3PhraseToken *pToken = pTC->pToken; |
| 115680 | int nList = 0; |
| 115681 | char *pList = 0; |
| 115682 | rc = fts3TermSelect(pTab, pToken, pTC->iCol, 1, &nList, &pList); |
| 115683 | assert( rc==SQLITE_OK || pList==0 ); |
| 115684 | |
| 115685 | if( rc==SQLITE_OK ){ |
| 115686 | nDocEst = fts3DoclistCountDocids(1, pList, nList); |
| 115687 | fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList); |
| 115688 | } |
| 115689 | } |
| 115690 | }else{ |
| 115691 | if( pTC->nOvfl>=(nDocEst*nDocSize) ){ |
| 115692 | Fts3PhraseToken *pToken = pTC->pToken; |
| @@ -116032,17 +116142,18 @@ | |
| 116142 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 116143 | |
| 116144 | if( pPhrase ){ |
| 116145 | fts3EvalZeroPoslist(pPhrase); |
| 116146 | if( pPhrase->bIncr ){ |
| 116147 | assert( pPhrase->nToken==1 ); |
| 116148 | assert( pPhrase->aToken[0].pSegcsr ); |
| 116149 | sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr); |
| 116150 | *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); |
| 116151 | } |
| 116152 | |
| 116153 | pPhrase->doclist.pNextDocid = 0; |
| 116154 | pPhrase->doclist.iDocid = 0; |
| 116155 | } |
| 116156 | |
| 116157 | pExpr->iDocid = 0; |
| 116158 | pExpr->bEof = 0; |
| 116159 | pExpr->bStart = 0; |
| @@ -116225,12 +116336,12 @@ | |
| 116336 | int iCol; |
| 116337 | |
| 116338 | if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ |
| 116339 | assert( pCsr->nDoc>0 ); |
| 116340 | for(iCol=0; iCol<pTab->nColumn; iCol++){ |
| 116341 | aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; |
| 116342 | aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; |
| 116343 | } |
| 116344 | }else{ |
| 116345 | rc = fts3EvalGatherStats(pCsr, pExpr); |
| 116346 | if( rc==SQLITE_OK ){ |
| 116347 | assert( pExpr->aMI ); |
| @@ -116334,11 +116445,10 @@ | |
| 116445 | ** May you share freely, never taking more than you give. |
| 116446 | ** |
| 116447 | ****************************************************************************** |
| 116448 | ** |
| 116449 | */ |
| 116450 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 116451 | |
| 116452 | |
| 116453 | typedef struct Fts3auxTable Fts3auxTable; |
| 116454 | typedef struct Fts3auxCursor Fts3auxCursor; |
| @@ -118168,11 +118278,10 @@ | |
| 118278 | */ |
| 118279 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 118280 | |
| 118281 | |
| 118282 | |
| 118283 | /* |
| 118284 | ** Class derived from sqlite3_tokenizer |
| 118285 | */ |
| 118286 | typedef struct porter_tokenizer { |
| 118287 | sqlite3_tokenizer base; /* Base class */ |
| @@ -118808,15 +118917,15 @@ | |
| 118917 | ** (in which case SQLITE_CORE is not defined), or |
| 118918 | ** |
| 118919 | ** * The FTS3 module is being built into the core of |
| 118920 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 118921 | */ |
| 118922 | #ifndef SQLITE_CORE |
| 118923 | SQLITE_EXTENSION_INIT1 |
| 118924 | #endif |
| 118925 | |
| 118926 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 118927 | |
| 118928 | |
| 118929 | /* |
| 118930 | ** Implementation of the SQL scalar function for accessing the underlying |
| 118931 | ** hash table. This function may be called as follows: |
| @@ -118937,11 +119046,11 @@ | |
| 119046 | sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ |
| 119047 | char **pzErr /* OUT: Set to malloced error message */ |
| 119048 | ){ |
| 119049 | int rc; |
| 119050 | char *z = (char *)zArg; |
| 119051 | int n = 0; |
| 119052 | char *zCopy; |
| 119053 | char *zEnd; /* Pointer to nul-term of zCopy */ |
| 119054 | sqlite3_tokenizer_module *m; |
| 119055 | |
| 119056 | zCopy = sqlite3_mprintf("%s", zArg); |
| @@ -119299,11 +119408,10 @@ | |
| 119408 | ** |
| 119409 | ** * The FTS3 module is being built into the core of |
| 119410 | ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). |
| 119411 | */ |
| 119412 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 119413 | |
| 119414 | |
| 119415 | |
| 119416 | typedef struct simple_tokenizer { |
| 119417 | sqlite3_tokenizer base; |
| @@ -120750,10 +120858,11 @@ | |
| 120858 | pReader->pOffsetList = 0; |
| 120859 | }else{ |
| 120860 | pReader->pOffsetList = p; |
| 120861 | } |
| 120862 | }else{ |
| 120863 | char *pEnd = &pReader->aDoclist[pReader->nDoclist]; |
| 120864 | |
| 120865 | /* Pointer p currently points at the first byte of an offset list. The |
| 120866 | ** following block advances it to point one byte past the end of |
| 120867 | ** the same offset list. */ |
| 120868 | while( 1 ){ |
| @@ -120778,17 +120887,19 @@ | |
| 120887 | */ |
| 120888 | if( ppOffsetList ){ |
| 120889 | *ppOffsetList = pReader->pOffsetList; |
| 120890 | *pnOffsetList = (int)(p - pReader->pOffsetList - 1); |
| 120891 | } |
| 120892 | |
| 120893 | while( p<pEnd && *p==0 ) p++; |
| 120894 | |
| 120895 | /* If there are no more entries in the doclist, set pOffsetList to |
| 120896 | ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and |
| 120897 | ** Fts3SegReader.pOffsetList to point to the next offset list before |
| 120898 | ** returning. |
| 120899 | */ |
| 120900 | if( p>=pEnd ){ |
| 120901 | pReader->pOffsetList = 0; |
| 120902 | }else{ |
| 120903 | rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); |
| 120904 | if( rc==SQLITE_OK ){ |
| 120905 | sqlite3_int64 iDelta; |
| @@ -120823,11 +120934,11 @@ | |
| 120934 | for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){ |
| 120935 | Fts3SegReader *pReader = pMsr->apSegment[ii]; |
| 120936 | if( !fts3SegReaderIsPending(pReader) |
| 120937 | && !fts3SegReaderIsRootOnly(pReader) |
| 120938 | ){ |
| 120939 | sqlite3_int64 jj; |
| 120940 | for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ |
| 120941 | int nBlob; |
| 120942 | rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); |
| 120943 | if( rc!=SQLITE_OK ) break; |
| 120944 | if( (nBlob+35)>pgsz ){ |
| @@ -121768,55 +121879,31 @@ | |
| 121879 | |
| 121880 | *ppList = pList; |
| 121881 | *pnList = nList; |
| 121882 | } |
| 121883 | |
| 121884 | /* |
| 121885 | ** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any |
| 121886 | ** existing data). Grow the buffer if required. |
| 121887 | ** |
| 121888 | ** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered |
| 121889 | ** trying to resize the buffer, return SQLITE_NOMEM. |
| 121890 | */ |
| 121891 | static int fts3MsrBufferData( |
| 121892 | Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ |
| 121893 | char *pList, |
| 121894 | int nList |
| 121895 | ){ |
| 121896 | if( nList>pMsr->nBuffer ){ |
| 121897 | char *pNew; |
| 121898 | pMsr->nBuffer = nList*2; |
| 121899 | pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); |
| 121900 | if( !pNew ) return SQLITE_NOMEM; |
| 121901 | pMsr->aBuffer = pNew; |
| 121902 | } |
| 121903 | |
| 121904 | memcpy(pMsr->aBuffer, pList, nList); |
| 121905 | return SQLITE_OK; |
| 121906 | } |
| 121907 | |
| 121908 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( |
| 121909 | Fts3Table *p, /* Virtual table handle */ |
| @@ -121866,52 +121953,138 @@ | |
| 121953 | if( pMsr->iColFilter>=0 ){ |
| 121954 | fts3ColumnFilter(pMsr->iColFilter, &pList, &nList); |
| 121955 | } |
| 121956 | |
| 121957 | if( nList>0 ){ |
| 121958 | if( fts3SegReaderIsPending(apSegment[0]) ){ |
| 121959 | rc = fts3MsrBufferData(pMsr, pList, nList+1); |
| 121960 | if( rc!=SQLITE_OK ) return rc; |
| 121961 | *paPoslist = pMsr->aBuffer; |
| 121962 | assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); |
| 121963 | }else{ |
| 121964 | *paPoslist = pList; |
| 121965 | } |
| 121966 | *piDocid = iDocid; |
| 121967 | *pnPoslist = nList; |
| 121968 | break; |
| 121969 | } |
| 121970 | } |
| 121971 | } |
| 121972 | |
| 121973 | return SQLITE_OK; |
| 121974 | } |
| 121975 | |
| 121976 | static int fts3SegReaderStart( |
| 121977 | Fts3Table *p, /* Virtual table handle */ |
| 121978 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 121979 | const char *zTerm, /* Term searched for (or NULL) */ |
| 121980 | int nTerm /* Length of zTerm in bytes */ |
| 121981 | ){ |
| 121982 | int i; |
| 121983 | int nSeg = pCsr->nSegment; |
| 121984 | |
| 121985 | /* If the Fts3SegFilter defines a specific term (or term prefix) to search |
| 121986 | ** for, then advance each segment iterator until it points to a term of |
| 121987 | ** equal or greater value than the specified term. This prevents many |
| 121988 | ** unnecessary merge/sort operations for the case where single segment |
| 121989 | ** b-tree leaf nodes contain more than one term. |
| 121990 | */ |
| 121991 | for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){ |
| 121992 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 121993 | do { |
| 121994 | int rc = fts3SegReaderNext(p, pSeg, 0); |
| 121995 | if( rc!=SQLITE_OK ) return rc; |
| 121996 | }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); |
| 121997 | } |
| 121998 | fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); |
| 121999 | |
| 122000 | return SQLITE_OK; |
| 122001 | } |
| 122002 | |
| 122003 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( |
| 122004 | Fts3Table *p, /* Virtual table handle */ |
| 122005 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 122006 | Fts3SegFilter *pFilter /* Restrictions on range of iteration */ |
| 122007 | ){ |
| 122008 | pCsr->pFilter = pFilter; |
| 122009 | return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); |
| 122010 | } |
| 122011 | |
| 122012 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( |
| 122013 | Fts3Table *p, /* Virtual table handle */ |
| 122014 | Fts3MultiSegReader *pCsr, /* Cursor object */ |
| 122015 | int iCol, /* Column to match on. */ |
| 122016 | const char *zTerm, /* Term to iterate through a doclist for */ |
| 122017 | int nTerm /* Number of bytes in zTerm */ |
| 122018 | ){ |
| 122019 | int i; |
| 122020 | int rc; |
| 122021 | int nSegment = pCsr->nSegment; |
| 122022 | int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( |
| 122023 | p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp |
| 122024 | ); |
| 122025 | |
| 122026 | assert( pCsr->pFilter==0 ); |
| 122027 | assert( zTerm && nTerm>0 ); |
| 122028 | |
| 122029 | /* Advance each segment iterator until it points to the term zTerm/nTerm. */ |
| 122030 | rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); |
| 122031 | if( rc!=SQLITE_OK ) return rc; |
| 122032 | |
| 122033 | /* Determine how many of the segments actually point to zTerm/nTerm. */ |
| 122034 | for(i=0; i<nSegment; i++){ |
| 122035 | Fts3SegReader *pSeg = pCsr->apSegment[i]; |
| 122036 | if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ |
| 122037 | break; |
| 122038 | } |
| 122039 | } |
| 122040 | pCsr->nAdvance = i; |
| 122041 | |
| 122042 | /* Advance each of the segments to point to the first docid. */ |
| 122043 | for(i=0; i<pCsr->nAdvance; i++){ |
| 122044 | rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); |
| 122045 | if( rc!=SQLITE_OK ) return rc; |
| 122046 | } |
| 122047 | fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); |
| 122048 | |
| 122049 | assert( iCol<0 || iCol<p->nColumn ); |
| 122050 | pCsr->iColFilter = iCol; |
| 122051 | |
| 122052 | return SQLITE_OK; |
| 122053 | } |
| 122054 | |
| 122055 | /* |
| 122056 | ** This function is called on a MultiSegReader that has been started using |
| 122057 | ** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also |
| 122058 | ** have been made. Calling this function puts the MultiSegReader in such |
| 122059 | ** a state that if the next two calls are: |
| 122060 | ** |
| 122061 | ** sqlite3Fts3SegReaderStart() |
| 122062 | ** sqlite3Fts3SegReaderStep() |
| 122063 | ** |
| 122064 | ** then the entire doclist for the term is available in |
| 122065 | ** MultiSegReader.aDoclist/nDoclist. |
| 122066 | */ |
| 122067 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ |
| 122068 | int i; /* Used to iterate through segment-readers */ |
| 122069 | |
| 122070 | assert( pCsr->zTerm==0 ); |
| 122071 | assert( pCsr->nTerm==0 ); |
| 122072 | assert( pCsr->aDoclist==0 ); |
| 122073 | assert( pCsr->nDoclist==0 ); |
| 122074 | |
| 122075 | pCsr->nAdvance = 0; |
| 122076 | pCsr->bRestart = 1; |
| 122077 | for(i=0; i<pCsr->nSegment; i++){ |
| 122078 | pCsr->apSegment[i]->pOffsetList = 0; |
| 122079 | pCsr->apSegment[i]->nOffsetList = 0; |
| 122080 | pCsr->apSegment[i]->iDocid = 0; |
| 122081 | } |
| 122082 | |
| 122083 | return SQLITE_OK; |
| 122084 | } |
| 122085 | |
| 122086 | |
| 122087 | SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( |
| 122088 | Fts3Table *p, /* Virtual table handle */ |
| 122089 | Fts3MultiSegReader *pCsr /* Cursor object */ |
| 122090 | ){ |
| @@ -121981,13 +122154,18 @@ | |
| 122154 | assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); |
| 122155 | if( nMerge==1 |
| 122156 | && !isIgnoreEmpty |
| 122157 | && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) |
| 122158 | ){ |
| 122159 | pCsr->nDoclist = apSegment[0]->nDoclist; |
| 122160 | if( fts3SegReaderIsPending(apSegment[0]) ){ |
| 122161 | rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); |
| 122162 | pCsr->aDoclist = pCsr->aBuffer; |
| 122163 | }else{ |
| 122164 | pCsr->aDoclist = apSegment[0]->aDoclist; |
| 122165 | } |
| 122166 | if( rc==SQLITE_OK ) rc = SQLITE_ROW; |
| 122167 | }else{ |
| 122168 | int nDoclist = 0; /* Size of doclist */ |
| 122169 | sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ |
| 122170 | |
| 122171 | /* The current term of the first nMerge entries in the array |
| @@ -123725,11 +123903,11 @@ | |
| 123903 | if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; |
| 123904 | break; |
| 123905 | |
| 123906 | case FTS3_MATCHINFO_NDOC: |
| 123907 | if( bGlobal ){ |
| 123908 | sqlite3_int64 nDoc = 0; |
| 123909 | rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); |
| 123910 | pInfo->aMatchinfo[0] = (u32)nDoc; |
| 123911 | } |
| 123912 | break; |
| 123913 | |
| @@ -125620,11 +125798,11 @@ | |
| 125798 | */ |
| 125799 | static float cellArea(Rtree *pRtree, RtreeCell *p){ |
| 125800 | float area = 1.0; |
| 125801 | int ii; |
| 125802 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125803 | area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); |
| 125804 | } |
| 125805 | return area; |
| 125806 | } |
| 125807 | |
| 125808 | /* |
| @@ -125633,11 +125811,11 @@ | |
| 125811 | */ |
| 125812 | static float cellMargin(Rtree *pRtree, RtreeCell *p){ |
| 125813 | float margin = 0.0; |
| 125814 | int ii; |
| 125815 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 125816 | margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); |
| 125817 | } |
| 125818 | return margin; |
| 125819 | } |
| 125820 | |
| 125821 | /* |
| @@ -125718,11 +125896,11 @@ | |
| 125896 | |
| 125897 | if( x2<x1 ){ |
| 125898 | o = 0.0; |
| 125899 | break; |
| 125900 | }else{ |
| 125901 | o = o * (float)(x2-x1); |
| 125902 | } |
| 125903 | } |
| 125904 | overlap += o; |
| 125905 | } |
| 125906 | } |
| @@ -125737,16 +125915,16 @@ | |
| 125915 | RtreeCell *pInsert, |
| 125916 | RtreeCell *aCell, |
| 125917 | int nCell, |
| 125918 | int iExclude |
| 125919 | ){ |
| 125920 | double before; |
| 125921 | double after; |
| 125922 | before = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125923 | cellUnion(pRtree, p, pInsert); |
| 125924 | after = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 125925 | return (float)(after-before); |
| 125926 | } |
| 125927 | #endif |
| 125928 | |
| 125929 | |
| 125930 | /* |
| @@ -125764,15 +125942,15 @@ | |
| 125942 | RtreeNode *pNode; |
| 125943 | rc = nodeAcquire(pRtree, 1, 0, &pNode); |
| 125944 | |
| 125945 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 125946 | int iCell; |
| 125947 | sqlite3_int64 iBest = 0; |
| 125948 | |
| 125949 | float fMinGrowth = 0.0; |
| 125950 | float fMinArea = 0.0; |
| 125951 | float fMinOverlap = 0.0; |
| 125952 | |
| 125953 | int nCell = NCELL(pNode); |
| 125954 | RtreeCell cell; |
| 125955 | RtreeNode *pChild; |
| 125956 | |
| @@ -126198,13 +126376,13 @@ | |
| 126376 | ){ |
| 126377 | int **aaSorted; |
| 126378 | int *aSpare; |
| 126379 | int ii; |
| 126380 | |
| 126381 | int iBestDim = 0; |
| 126382 | int iBestSplit = 0; |
| 126383 | float fBestMargin = 0.0; |
| 126384 | |
| 126385 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 126386 | |
| 126387 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 126388 | if( !aaSorted ){ |
| @@ -126222,13 +126400,13 @@ | |
| 126400 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 126401 | } |
| 126402 | |
| 126403 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 126404 | float margin = 0.0; |
| 126405 | float fBestOverlap = 0.0; |
| 126406 | float fBestArea = 0.0; |
| 126407 | int iBestLeft = 0; |
| 126408 | int nLeft; |
| 126409 | |
| 126410 | for( |
| 126411 | nLeft=RTREE_MINCELLS(pRtree); |
| 126412 | nLeft<=(nCell-RTREE_MINCELLS(pRtree)); |
| @@ -126539,11 +126717,11 @@ | |
| 126717 | static int deleteCell(Rtree *, RtreeNode *, int, int); |
| 126718 | |
| 126719 | static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ |
| 126720 | int rc; |
| 126721 | int rc2; |
| 126722 | RtreeNode *pParent = 0; |
| 126723 | int iCell; |
| 126724 | |
| 126725 | assert( pNode->nRef==1 ); |
| 126726 | |
| 126727 | /* Remove the entry in the parent cell. */ |
| @@ -126687,23 +126865,23 @@ | |
| 126865 | }else{ |
| 126866 | nodeGetCell(pRtree, pNode, ii, &aCell[ii]); |
| 126867 | } |
| 126868 | aOrder[ii] = ii; |
| 126869 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126870 | aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]); |
| 126871 | aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]); |
| 126872 | } |
| 126873 | } |
| 126874 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126875 | aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0)); |
| 126876 | } |
| 126877 | |
| 126878 | for(ii=0; ii<nCell; ii++){ |
| 126879 | aDistance[ii] = 0.0; |
| 126880 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 126881 | float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - |
| 126882 | DCOORD(aCell[ii].aCoord[iDim*2])); |
| 126883 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 126884 | } |
| 126885 | } |
| 126886 | |
| 126887 | SortByDistance(aOrder, nCell, aDistance, aSpare); |
| @@ -126798,14 +126976,14 @@ | |
| 126976 | nodeGetCell(pRtree, pNode, ii, &cell); |
| 126977 | |
| 126978 | /* Find a node to store this cell in. pNode->iNode currently contains |
| 126979 | ** the height of the sub-tree headed by the cell. |
| 126980 | */ |
| 126981 | rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); |
| 126982 | if( rc==SQLITE_OK ){ |
| 126983 | int rc2; |
| 126984 | rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); |
| 126985 | rc2 = nodeRelease(pRtree, pInsert); |
| 126986 | if( rc==SQLITE_OK ){ |
| 126987 | rc = rc2; |
| 126988 | } |
| 126989 | } |
| @@ -127190,11 +127368,11 @@ | |
| 127368 | int isCreate /* True for xCreate, false for xConnect */ |
| 127369 | ){ |
| 127370 | int rc; |
| 127371 | char *zSql; |
| 127372 | if( isCreate ){ |
| 127373 | int iPageSize = 0; |
| 127374 | zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); |
| 127375 | rc = getIntFromStmt(db, zSql, &iPageSize); |
| 127376 | if( rc==SQLITE_OK ){ |
| 127377 | pRtree->iNodeSize = iPageSize-64; |
| 127378 | if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){ |
| @@ -127993,14 +128171,11 @@ | |
| 128171 | ** May you find forgiveness for yourself and forgive others. |
| 128172 | ** May you share freely, never taking more than you give. |
| 128173 | ** |
| 128174 | ************************************************************************* |
| 128175 | ** This file implements a tokenizer for fts3 based on the ICU library. |
| 128176 | */ |
| 128177 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 128178 | #ifdef SQLITE_ENABLE_ICU |
| 128179 | |
| 128180 | |
| 128181 | #include <unicode/ubrk.h> |
| 128182 |
+12
-11
| --- 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.7.7" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | -#define SQLITE_SOURCE_ID "2011-06-15 13:11:06 f9750870ee04935f338e4d808900fee5a8b2b389" | |
| 112 | +#define SQLITE_SOURCE_ID "2011-06-24 11:29:51 9b191bb4c7c1e1b12b188c0b3eee1f8f587887c8" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -308,11 +308,11 @@ | ||
| 308 | 308 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 309 | 309 | ** in the context of the [database connection] passed in as its 1st |
| 310 | 310 | ** argument. ^If the callback function of the 3rd argument to |
| 311 | 311 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 312 | 312 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 313 | -** to sqlite3_exec() is relayed through to the 1st argument of each | |
| 313 | +** sqlite3_exec() is relayed through to the 1st argument of each | |
| 314 | 314 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 315 | 315 | ** is NULL, then no callback is ever invoked and result rows are |
| 316 | 316 | ** ignored. |
| 317 | 317 | ** |
| 318 | 318 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -900,11 +900,11 @@ | ||
| 900 | 900 | ** The xSleep() method causes the calling thread to sleep for at |
| 901 | 901 | ** least the number of microseconds given. ^The xCurrentTime() |
| 902 | 902 | ** method returns a Julian Day Number for the current date and time as |
| 903 | 903 | ** a floating point value. |
| 904 | 904 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 905 | -** Day Number multipled by 86400000 (the number of milliseconds in | |
| 905 | +** Day Number multiplied by 86400000 (the number of milliseconds in | |
| 906 | 906 | ** a 24-hour day). |
| 907 | 907 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 908 | 908 | ** date and time if that method is available (if iVersion is 2 or |
| 909 | 909 | ** greater and the function pointer is not NULL) and will fall back |
| 910 | 910 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1338,11 +1338,11 @@ | ||
| 1338 | 1338 | ** scratch memory beyond what is provided by this configuration option, then |
| 1339 | 1339 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1340 | 1340 | ** |
| 1341 | 1341 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1342 | 1342 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1343 | -** the database page cache with the default page cache implemenation. | |
| 1343 | +** the database page cache with the default page cache implementation. | |
| 1344 | 1344 | ** This configuration should not be used if an application-define page |
| 1345 | 1345 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1346 | 1346 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1347 | 1347 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1348 | 1348 | ** The sz argument should be the size of the largest database page |
| @@ -2436,16 +2436,16 @@ | ||
| 2436 | 2436 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2437 | 2437 | ** |
| 2438 | 2438 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2439 | 2439 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2440 | 2440 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2441 | -** is set in the fourth argument to sqlite3_open_v2(), or if it has | |
| 2441 | +** set in the fourth argument to sqlite3_open_v2(), or if it has | |
| 2442 | 2442 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2443 | 2443 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2444 | 2444 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2445 | 2445 | ** by default, but future releases of SQLite might enable URI filename |
| 2446 | -** intepretation by default. See "[URI filenames]" for additional | |
| 2446 | +** interpretation by default. See "[URI filenames]" for additional | |
| 2447 | 2447 | ** information. |
| 2448 | 2448 | ** |
| 2449 | 2449 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2450 | 2450 | ** authority, then it must be either an empty string or the string |
| 2451 | 2451 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3260,11 +3260,11 @@ | ||
| 3260 | 3260 | ** [extended result codes] might be returned as well. |
| 3261 | 3261 | ** |
| 3262 | 3262 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3263 | 3263 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3264 | 3264 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3265 | -** statement. If the statement is not a [COMMIT] and occurs within a | |
| 3265 | +** statement. If the statement is not a [COMMIT] and occurs within an | |
| 3266 | 3266 | ** explicit transaction then you should rollback the transaction before |
| 3267 | 3267 | ** continuing. |
| 3268 | 3268 | ** |
| 3269 | 3269 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3270 | 3270 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -3539,11 +3539,11 @@ | ||
| 3539 | 3539 | |
| 3540 | 3540 | /* |
| 3541 | 3541 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 3542 | 3542 | ** |
| 3543 | 3543 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 3544 | -** ^If the most recent evaluation of the statement encountered no errors or | |
| 3544 | +** ^If the most recent evaluation of the statement encountered no errors | |
| 3545 | 3545 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 3546 | 3546 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 3547 | 3547 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 3548 | 3548 | ** [extended error code]. |
| 3549 | 3549 | ** |
| @@ -5453,11 +5453,11 @@ | ||
| 5453 | 5453 | ** versions of these routines, it should at least provide stubs that always |
| 5454 | 5454 | ** return true so that one does not get spurious assertion failures. |
| 5455 | 5455 | ** |
| 5456 | 5456 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 5457 | 5457 | ** the routine should return 1. This seems counter-intuitive since |
| 5458 | -** clearly the mutex cannot be held if it does not exist. But the | |
| 5458 | +** clearly the mutex cannot be held if it does not exist. But | |
| 5459 | 5459 | ** the reason the mutex does not exist is because the build is not |
| 5460 | 5460 | ** using mutexes. And we do not want the assert() containing the |
| 5461 | 5461 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 5462 | 5462 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 5463 | 5463 | ** interface should also return 1 when given a NULL pointer. |
| @@ -5576,11 +5576,12 @@ | ||
| 5576 | 5576 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 5577 | 5577 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 5578 | 5578 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 5579 | 5579 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 5580 | 5580 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 5581 | -#define SQLITE_TESTCTRL_LAST 18 | |
| 5581 | +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 | |
| 5582 | +#define SQLITE_TESTCTRL_LAST 19 | |
| 5582 | 5583 | |
| 5583 | 5584 | /* |
| 5584 | 5585 | ** CAPI3REF: SQLite Runtime Status |
| 5585 | 5586 | ** |
| 5586 | 5587 | ** ^This interface is used to retrieve runtime status information |
| @@ -5962,11 +5963,11 @@ | ||
| 5962 | 5963 | ** [[the xFetch() page cache methods]] |
| 5963 | 5964 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 5964 | 5965 | ** the page, or a NULL pointer. |
| 5965 | 5966 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 5966 | 5967 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 5967 | -** mimimum key value is 1. After it has been retrieved using xFetch, the page | |
| 5968 | +** minimum key value is 1. After it has been retrieved using xFetch, the page | |
| 5968 | 5969 | ** is considered to be "pinned". |
| 5969 | 5970 | ** |
| 5970 | 5971 | ** If the requested page is already in the page cache, then the page cache |
| 5971 | 5972 | ** implementation must return a pointer to the page buffer with its content |
| 5972 | 5973 | ** intact. If the requested page is not already in the cache, then the |
| 5973 | 5974 |
| --- 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.7.7" |
| 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | #define SQLITE_SOURCE_ID "2011-06-15 13:11:06 f9750870ee04935f338e4d808900fee5a8b2b389" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -308,11 +308,11 @@ | |
| 308 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 309 | ** in the context of the [database connection] passed in as its 1st |
| 310 | ** argument. ^If the callback function of the 3rd argument to |
| 311 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 312 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 313 | ** to sqlite3_exec() is relayed through to the 1st argument of each |
| 314 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 315 | ** is NULL, then no callback is ever invoked and result rows are |
| 316 | ** ignored. |
| 317 | ** |
| 318 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -900,11 +900,11 @@ | |
| 900 | ** The xSleep() method causes the calling thread to sleep for at |
| 901 | ** least the number of microseconds given. ^The xCurrentTime() |
| 902 | ** method returns a Julian Day Number for the current date and time as |
| 903 | ** a floating point value. |
| 904 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 905 | ** Day Number multipled by 86400000 (the number of milliseconds in |
| 906 | ** a 24-hour day). |
| 907 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 908 | ** date and time if that method is available (if iVersion is 2 or |
| 909 | ** greater and the function pointer is not NULL) and will fall back |
| 910 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1338,11 +1338,11 @@ | |
| 1338 | ** scratch memory beyond what is provided by this configuration option, then |
| 1339 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1340 | ** |
| 1341 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1342 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1343 | ** the database page cache with the default page cache implemenation. |
| 1344 | ** This configuration should not be used if an application-define page |
| 1345 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1346 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1347 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1348 | ** The sz argument should be the size of the largest database page |
| @@ -2436,16 +2436,16 @@ | |
| 2436 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2437 | ** |
| 2438 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2439 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2440 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2441 | ** is set in the fourth argument to sqlite3_open_v2(), or if it has |
| 2442 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2443 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2444 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2445 | ** by default, but future releases of SQLite might enable URI filename |
| 2446 | ** intepretation by default. See "[URI filenames]" for additional |
| 2447 | ** information. |
| 2448 | ** |
| 2449 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2450 | ** authority, then it must be either an empty string or the string |
| 2451 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3260,11 +3260,11 @@ | |
| 3260 | ** [extended result codes] might be returned as well. |
| 3261 | ** |
| 3262 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3263 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3264 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3265 | ** statement. If the statement is not a [COMMIT] and occurs within a |
| 3266 | ** explicit transaction then you should rollback the transaction before |
| 3267 | ** continuing. |
| 3268 | ** |
| 3269 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3270 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -3539,11 +3539,11 @@ | |
| 3539 | |
| 3540 | /* |
| 3541 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 3542 | ** |
| 3543 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 3544 | ** ^If the most recent evaluation of the statement encountered no errors or |
| 3545 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 3546 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 3547 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 3548 | ** [extended error code]. |
| 3549 | ** |
| @@ -5453,11 +5453,11 @@ | |
| 5453 | ** versions of these routines, it should at least provide stubs that always |
| 5454 | ** return true so that one does not get spurious assertion failures. |
| 5455 | ** |
| 5456 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 5457 | ** the routine should return 1. This seems counter-intuitive since |
| 5458 | ** clearly the mutex cannot be held if it does not exist. But the |
| 5459 | ** the reason the mutex does not exist is because the build is not |
| 5460 | ** using mutexes. And we do not want the assert() containing the |
| 5461 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 5462 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 5463 | ** interface should also return 1 when given a NULL pointer. |
| @@ -5576,11 +5576,12 @@ | |
| 5576 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 5577 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 5578 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 5579 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 5580 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 5581 | #define SQLITE_TESTCTRL_LAST 18 |
| 5582 | |
| 5583 | /* |
| 5584 | ** CAPI3REF: SQLite Runtime Status |
| 5585 | ** |
| 5586 | ** ^This interface is used to retrieve runtime status information |
| @@ -5962,11 +5963,11 @@ | |
| 5962 | ** [[the xFetch() page cache methods]] |
| 5963 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 5964 | ** the page, or a NULL pointer. |
| 5965 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 5966 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 5967 | ** mimimum key value is 1. After it has been retrieved using xFetch, the page |
| 5968 | ** is considered to be "pinned". |
| 5969 | ** |
| 5970 | ** If the requested page is already in the page cache, then the page cache |
| 5971 | ** implementation must return a pointer to the page buffer with its content |
| 5972 | ** intact. If the requested page is not already in the cache, then the |
| 5973 |
| --- 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.7.7" |
| 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | #define SQLITE_SOURCE_ID "2011-06-24 11:29:51 9b191bb4c7c1e1b12b188c0b3eee1f8f587887c8" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -308,11 +308,11 @@ | |
| 308 | ** semicolon-separate SQL statements passed into its 2nd argument, |
| 309 | ** in the context of the [database connection] passed in as its 1st |
| 310 | ** argument. ^If the callback function of the 3rd argument to |
| 311 | ** sqlite3_exec() is not NULL, then it is invoked for each result row |
| 312 | ** coming out of the evaluated SQL statements. ^The 4th argument to |
| 313 | ** sqlite3_exec() is relayed through to the 1st argument of each |
| 314 | ** callback invocation. ^If the callback pointer to sqlite3_exec() |
| 315 | ** is NULL, then no callback is ever invoked and result rows are |
| 316 | ** ignored. |
| 317 | ** |
| 318 | ** ^If an error occurs while evaluating the SQL statements passed into |
| @@ -900,11 +900,11 @@ | |
| 900 | ** The xSleep() method causes the calling thread to sleep for at |
| 901 | ** least the number of microseconds given. ^The xCurrentTime() |
| 902 | ** method returns a Julian Day Number for the current date and time as |
| 903 | ** a floating point value. |
| 904 | ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 905 | ** Day Number multiplied by 86400000 (the number of milliseconds in |
| 906 | ** a 24-hour day). |
| 907 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 908 | ** date and time if that method is available (if iVersion is 2 or |
| 909 | ** greater and the function pointer is not NULL) and will fall back |
| 910 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| @@ -1338,11 +1338,11 @@ | |
| 1338 | ** scratch memory beyond what is provided by this configuration option, then |
| 1339 | ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd> |
| 1340 | ** |
| 1341 | ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> |
| 1342 | ** <dd> ^This option specifies a static memory buffer that SQLite can use for |
| 1343 | ** the database page cache with the default page cache implementation. |
| 1344 | ** This configuration should not be used if an application-define page |
| 1345 | ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. |
| 1346 | ** There are three arguments to this option: A pointer to 8-byte aligned |
| 1347 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1348 | ** The sz argument should be the size of the largest database page |
| @@ -2436,16 +2436,16 @@ | |
| 2436 | ** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> |
| 2437 | ** |
| 2438 | ** ^If [URI filename] interpretation is enabled, and the filename argument |
| 2439 | ** begins with "file:", then the filename is interpreted as a URI. ^URI |
| 2440 | ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is |
| 2441 | ** set in the fourth argument to sqlite3_open_v2(), or if it has |
| 2442 | ** been enabled globally using the [SQLITE_CONFIG_URI] option with the |
| 2443 | ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. |
| 2444 | ** As of SQLite version 3.7.7, URI filename interpretation is turned off |
| 2445 | ** by default, but future releases of SQLite might enable URI filename |
| 2446 | ** interpretation by default. See "[URI filenames]" for additional |
| 2447 | ** information. |
| 2448 | ** |
| 2449 | ** URI filenames are parsed according to RFC 3986. ^If the URI contains an |
| 2450 | ** authority, then it must be either an empty string or the string |
| 2451 | ** "localhost". ^If the authority is not an empty string or "localhost", an |
| @@ -3260,11 +3260,11 @@ | |
| 3260 | ** [extended result codes] might be returned as well. |
| 3261 | ** |
| 3262 | ** ^[SQLITE_BUSY] means that the database engine was unable to acquire the |
| 3263 | ** database locks it needs to do its job. ^If the statement is a [COMMIT] |
| 3264 | ** or occurs outside of an explicit transaction, then you can retry the |
| 3265 | ** statement. If the statement is not a [COMMIT] and occurs within an |
| 3266 | ** explicit transaction then you should rollback the transaction before |
| 3267 | ** continuing. |
| 3268 | ** |
| 3269 | ** ^[SQLITE_DONE] means that the statement has finished executing |
| 3270 | ** successfully. sqlite3_step() should not be called again on this virtual |
| @@ -3539,11 +3539,11 @@ | |
| 3539 | |
| 3540 | /* |
| 3541 | ** CAPI3REF: Destroy A Prepared Statement Object |
| 3542 | ** |
| 3543 | ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. |
| 3544 | ** ^If the most recent evaluation of the statement encountered no errors |
| 3545 | ** or if the statement is never been evaluated, then sqlite3_finalize() returns |
| 3546 | ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then |
| 3547 | ** sqlite3_finalize(S) returns the appropriate [error code] or |
| 3548 | ** [extended error code]. |
| 3549 | ** |
| @@ -5453,11 +5453,11 @@ | |
| 5453 | ** versions of these routines, it should at least provide stubs that always |
| 5454 | ** return true so that one does not get spurious assertion failures. |
| 5455 | ** |
| 5456 | ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then |
| 5457 | ** the routine should return 1. This seems counter-intuitive since |
| 5458 | ** clearly the mutex cannot be held if it does not exist. But |
| 5459 | ** the reason the mutex does not exist is because the build is not |
| 5460 | ** using mutexes. And we do not want the assert() containing the |
| 5461 | ** call to sqlite3_mutex_held() to fail, so a non-zero return is |
| 5462 | ** the appropriate thing to do. ^The sqlite3_mutex_notheld() |
| 5463 | ** interface should also return 1 when given a NULL pointer. |
| @@ -5576,11 +5576,12 @@ | |
| 5576 | #define SQLITE_TESTCTRL_RESERVE 14 |
| 5577 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 5578 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 5579 | #define SQLITE_TESTCTRL_PGHDRSZ 17 |
| 5580 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 18 |
| 5581 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 |
| 5582 | #define SQLITE_TESTCTRL_LAST 19 |
| 5583 | |
| 5584 | /* |
| 5585 | ** CAPI3REF: SQLite Runtime Status |
| 5586 | ** |
| 5587 | ** ^This interface is used to retrieve runtime status information |
| @@ -5962,11 +5963,11 @@ | |
| 5963 | ** [[the xFetch() page cache methods]] |
| 5964 | ** The xFetch() method locates a page in the cache and returns a pointer to |
| 5965 | ** the page, or a NULL pointer. |
| 5966 | ** A "page", in this context, means a buffer of szPage bytes aligned at an |
| 5967 | ** 8-byte boundary. The page to be fetched is determined by the key. ^The |
| 5968 | ** minimum key value is 1. After it has been retrieved using xFetch, the page |
| 5969 | ** is considered to be "pinned". |
| 5970 | ** |
| 5971 | ** If the requested page is already in the page cache, then the page cache |
| 5972 | ** implementation must return a pointer to the page buffer with its content |
| 5973 | ** intact. If the requested page is not already in the cache, then the |
| 5974 |
+1
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -100,10 +100,11 @@ | ||
| 100 | 100 | if( rid==0 ){ |
| 101 | 101 | /* A new file */ |
| 102 | 102 | blob_read_from_file(&content, zPath); |
| 103 | 103 | db_bind_blob(&ins, ":content", &content); |
| 104 | 104 | }else if( deleted ){ |
| 105 | + blob_zero(&content); | |
| 105 | 106 | db_bind_null(&ins, ":content"); |
| 106 | 107 | }else{ |
| 107 | 108 | /* A modified file */ |
| 108 | 109 | Blob orig; |
| 109 | 110 | Blob disk; |
| 110 | 111 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -100,10 +100,11 @@ | |
| 100 | if( rid==0 ){ |
| 101 | /* A new file */ |
| 102 | blob_read_from_file(&content, zPath); |
| 103 | db_bind_blob(&ins, ":content", &content); |
| 104 | }else if( deleted ){ |
| 105 | db_bind_null(&ins, ":content"); |
| 106 | }else{ |
| 107 | /* A modified file */ |
| 108 | Blob orig; |
| 109 | Blob disk; |
| 110 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -100,10 +100,11 @@ | |
| 100 | if( rid==0 ){ |
| 101 | /* A new file */ |
| 102 | blob_read_from_file(&content, zPath); |
| 103 | db_bind_blob(&ins, ":content", &content); |
| 104 | }else if( deleted ){ |
| 105 | blob_zero(&content); |
| 106 | db_bind_null(&ins, ":content"); |
| 107 | }else{ |
| 108 | /* A modified file */ |
| 109 | Blob orig; |
| 110 | Blob disk; |
| 111 |
+1
-1
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -731,11 +731,11 @@ | ||
| 731 | 731 | zUuid = PD("name",""); |
| 732 | 732 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 733 | 733 | style_submenu_element("Status", "Status", |
| 734 | 734 | "%s/info/%s", g.zTop, zUuid); |
| 735 | 735 | style_submenu_element("Check-ins", "Check-ins", |
| 736 | - "%s/tkttimeline?name=%s?y=ci", g.zTop, zUuid); | |
| 736 | + "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid); | |
| 737 | 737 | style_submenu_element("Timeline", "Timeline", |
| 738 | 738 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 739 | 739 | style_header(zTitle); |
| 740 | 740 | free(zTitle); |
| 741 | 741 | |
| 742 | 742 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -731,11 +731,11 @@ | |
| 731 | zUuid = PD("name",""); |
| 732 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 733 | style_submenu_element("Status", "Status", |
| 734 | "%s/info/%s", g.zTop, zUuid); |
| 735 | style_submenu_element("Check-ins", "Check-ins", |
| 736 | "%s/tkttimeline?name=%s?y=ci", g.zTop, zUuid); |
| 737 | style_submenu_element("Timeline", "Timeline", |
| 738 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 739 | style_header(zTitle); |
| 740 | free(zTitle); |
| 741 | |
| 742 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -731,11 +731,11 @@ | |
| 731 | zUuid = PD("name",""); |
| 732 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 733 | style_submenu_element("Status", "Status", |
| 734 | "%s/info/%s", g.zTop, zUuid); |
| 735 | style_submenu_element("Check-ins", "Check-ins", |
| 736 | "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid); |
| 737 | style_submenu_element("Timeline", "Timeline", |
| 738 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 739 | style_header(zTitle); |
| 740 | free(zTitle); |
| 741 | |
| 742 |
+8
-20
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -182,12 +182,11 @@ | ||
| 182 | 182 | " ORDER BY mtime DESC", zTag |
| 183 | 183 | ); |
| 184 | 184 | free(zTag); |
| 185 | 185 | pWiki = manifest_get(rid, CFTYPE_WIKI); |
| 186 | 186 | if( pWiki ){ |
| 187 | - while( fossil_isspace(pWiki->zWiki[0]) ) pWiki->zWiki++; | |
| 188 | - if( pWiki->zWiki[0] ) zBody = pWiki->zWiki; | |
| 187 | + zBody = pWiki->zWiki; | |
| 189 | 188 | } |
| 190 | 189 | } |
| 191 | 190 | if( !g.isHome ){ |
| 192 | 191 | if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ |
| 193 | 192 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| @@ -891,10 +890,11 @@ | ||
| 891 | 890 | char const *zPageName; /* Name of the wiki page to export */ |
| 892 | 891 | char const *zFile; /* Name of the output file (0=stdout) */ |
| 893 | 892 | int rid; /* Artifact ID of the wiki page */ |
| 894 | 893 | int i; /* Loop counter */ |
| 895 | 894 | char *zBody = 0; /* Wiki page content */ |
| 895 | + Blob body; /* Wiki page content */ | |
| 896 | 896 | Manifest *pWiki = 0; /* Parsed wiki page content */ |
| 897 | 897 | |
| 898 | 898 | if( (g.argc!=4) && (g.argc!=5) ){ |
| 899 | 899 | usage("export PAGENAME ?FILE?"); |
| 900 | 900 | } |
| @@ -909,28 +909,16 @@ | ||
| 909 | 909 | } |
| 910 | 910 | if( zBody==0 ){ |
| 911 | 911 | fossil_fatal("wiki page [%s] not found",zPageName); |
| 912 | 912 | } |
| 913 | 913 | for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){} |
| 914 | - zFile = (g.argc==4) ? 0 : g.argv[4]; | |
| 915 | - if( zFile ){ | |
| 916 | - FILE * zF; | |
| 917 | - short doClose = 0; | |
| 918 | - if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ | |
| 919 | - zF = stdout; | |
| 920 | - }else{ | |
| 921 | - zF = fossil_fopen( zFile, "w" ); | |
| 922 | - doClose = zF ? 1 : 0; | |
| 923 | - } | |
| 924 | - if( ! zF ){ | |
| 925 | - fossil_fatal("wiki export could not open output file for writing."); | |
| 926 | - } | |
| 927 | - fprintf(zF,"%.*s\n", i, zBody); | |
| 928 | - if( doClose ) fclose(zF); | |
| 929 | - }else{ | |
| 930 | - fossil_print("%.*s\n", i, zBody); | |
| 931 | - } | |
| 914 | + zBody[i] = 0; | |
| 915 | + zFile = (g.argc==4) ? "-" : g.argv[4]; | |
| 916 | + blob_init(&body, zBody, -1); | |
| 917 | + blob_append(&body, "\n", 1); | |
| 918 | + blob_write_to_file(&body, zFile); | |
| 919 | + blob_reset(&body); | |
| 932 | 920 | manifest_destroy(pWiki); |
| 933 | 921 | return; |
| 934 | 922 | }else |
| 935 | 923 | if( strncmp(g.argv[2],"commit",n)==0 |
| 936 | 924 | || strncmp(g.argv[2],"create",n)==0 ){ |
| 937 | 925 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -182,12 +182,11 @@ | |
| 182 | " ORDER BY mtime DESC", zTag |
| 183 | ); |
| 184 | free(zTag); |
| 185 | pWiki = manifest_get(rid, CFTYPE_WIKI); |
| 186 | if( pWiki ){ |
| 187 | while( fossil_isspace(pWiki->zWiki[0]) ) pWiki->zWiki++; |
| 188 | if( pWiki->zWiki[0] ) zBody = pWiki->zWiki; |
| 189 | } |
| 190 | } |
| 191 | if( !g.isHome ){ |
| 192 | if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ |
| 193 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| @@ -891,10 +890,11 @@ | |
| 891 | char const *zPageName; /* Name of the wiki page to export */ |
| 892 | char const *zFile; /* Name of the output file (0=stdout) */ |
| 893 | int rid; /* Artifact ID of the wiki page */ |
| 894 | int i; /* Loop counter */ |
| 895 | char *zBody = 0; /* Wiki page content */ |
| 896 | Manifest *pWiki = 0; /* Parsed wiki page content */ |
| 897 | |
| 898 | if( (g.argc!=4) && (g.argc!=5) ){ |
| 899 | usage("export PAGENAME ?FILE?"); |
| 900 | } |
| @@ -909,28 +909,16 @@ | |
| 909 | } |
| 910 | if( zBody==0 ){ |
| 911 | fossil_fatal("wiki page [%s] not found",zPageName); |
| 912 | } |
| 913 | for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){} |
| 914 | zFile = (g.argc==4) ? 0 : g.argv[4]; |
| 915 | if( zFile ){ |
| 916 | FILE * zF; |
| 917 | short doClose = 0; |
| 918 | if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ |
| 919 | zF = stdout; |
| 920 | }else{ |
| 921 | zF = fossil_fopen( zFile, "w" ); |
| 922 | doClose = zF ? 1 : 0; |
| 923 | } |
| 924 | if( ! zF ){ |
| 925 | fossil_fatal("wiki export could not open output file for writing."); |
| 926 | } |
| 927 | fprintf(zF,"%.*s\n", i, zBody); |
| 928 | if( doClose ) fclose(zF); |
| 929 | }else{ |
| 930 | fossil_print("%.*s\n", i, zBody); |
| 931 | } |
| 932 | manifest_destroy(pWiki); |
| 933 | return; |
| 934 | }else |
| 935 | if( strncmp(g.argv[2],"commit",n)==0 |
| 936 | || strncmp(g.argv[2],"create",n)==0 ){ |
| 937 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -182,12 +182,11 @@ | |
| 182 | " ORDER BY mtime DESC", zTag |
| 183 | ); |
| 184 | free(zTag); |
| 185 | pWiki = manifest_get(rid, CFTYPE_WIKI); |
| 186 | if( pWiki ){ |
| 187 | zBody = pWiki->zWiki; |
| 188 | } |
| 189 | } |
| 190 | if( !g.isHome ){ |
| 191 | if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ |
| 192 | style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", |
| @@ -891,10 +890,11 @@ | |
| 890 | char const *zPageName; /* Name of the wiki page to export */ |
| 891 | char const *zFile; /* Name of the output file (0=stdout) */ |
| 892 | int rid; /* Artifact ID of the wiki page */ |
| 893 | int i; /* Loop counter */ |
| 894 | char *zBody = 0; /* Wiki page content */ |
| 895 | Blob body; /* Wiki page content */ |
| 896 | Manifest *pWiki = 0; /* Parsed wiki page content */ |
| 897 | |
| 898 | if( (g.argc!=4) && (g.argc!=5) ){ |
| 899 | usage("export PAGENAME ?FILE?"); |
| 900 | } |
| @@ -909,28 +909,16 @@ | |
| 909 | } |
| 910 | if( zBody==0 ){ |
| 911 | fossil_fatal("wiki page [%s] not found",zPageName); |
| 912 | } |
| 913 | for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){} |
| 914 | zBody[i] = 0; |
| 915 | zFile = (g.argc==4) ? "-" : g.argv[4]; |
| 916 | blob_init(&body, zBody, -1); |
| 917 | blob_append(&body, "\n", 1); |
| 918 | blob_write_to_file(&body, zFile); |
| 919 | blob_reset(&body); |
| 920 | manifest_destroy(pWiki); |
| 921 | return; |
| 922 | }else |
| 923 | if( strncmp(g.argv[2],"commit",n)==0 |
| 924 | || strncmp(g.argv[2],"create",n)==0 ){ |
| 925 |
+644
-9
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -14,17 +14,18 @@ | ||
| 14 | 14 | ** http://www.hwaci.com/drh/ |
| 15 | 15 | ** |
| 16 | 16 | ******************************************************************************* |
| 17 | 17 | ** |
| 18 | 18 | ** This file implements a very simple (and low-performance) HTTP server |
| 19 | -** for windows. | |
| 19 | +** for windows. It also implements a Windows Service which allows the HTTP | |
| 20 | +** server to be run without any user logged on. | |
| 20 | 21 | */ |
| 21 | 22 | #include "config.h" |
| 22 | 23 | #ifdef _WIN32 |
| 23 | 24 | /* This code is for win32 only */ |
| 24 | -#include "winhttp.h" | |
| 25 | 25 | #include <windows.h> |
| 26 | +#include "winhttp.h" | |
| 26 | 27 | |
| 27 | 28 | /* |
| 28 | 29 | ** The HttpRequest structure holds information about each incoming |
| 29 | 30 | ** HTTP request. |
| 30 | 31 | */ |
| @@ -60,11 +61,11 @@ | ||
| 60 | 61 | } |
| 61 | 62 | |
| 62 | 63 | /* |
| 63 | 64 | ** Process a single incoming HTTP request. |
| 64 | 65 | */ |
| 65 | -void win32_process_one_http_request(void *pAppData){ | |
| 66 | +static void win32_process_one_http_request(void *pAppData){ | |
| 66 | 67 | HttpRequest *p = (HttpRequest*)pAppData; |
| 67 | 68 | FILE *in = 0, *out = 0; |
| 68 | 69 | int amt, got; |
| 69 | 70 | int wanted = 0; |
| 70 | 71 | char *z; |
| @@ -145,10 +146,11 @@ | ||
| 145 | 146 | SOCKET s = INVALID_SOCKET; |
| 146 | 147 | SOCKADDR_IN addr; |
| 147 | 148 | int idCnt = 0; |
| 148 | 149 | int iPort = mnPort; |
| 149 | 150 | Blob options; |
| 151 | + char zTmpPath[MAX_PATH]; | |
| 150 | 152 | |
| 151 | 153 | if( zStopper ) file_delete(zStopper); |
| 152 | 154 | blob_zero(&options); |
| 153 | 155 | if( zNotFound ){ |
| 154 | 156 | blob_appendf(&options, " --notfound %s", zNotFound); |
| @@ -189,31 +191,46 @@ | ||
| 189 | 191 | }else{ |
| 190 | 192 | fossil_fatal("unable to open listening socket on any" |
| 191 | 193 | " port in the range %d..%d", mnPort, mxPort); |
| 192 | 194 | } |
| 193 | 195 | } |
| 194 | - zTempPrefix = mprintf("fossil_server_P%d_", iPort); | |
| 196 | + if( !GetTempPath(sizeof(zTmpPath), zTmpPath) ){ | |
| 197 | + fossil_fatal("unable to get path to the temporary directory."); | |
| 198 | + } | |
| 199 | + zTempPrefix = mprintf("%sfossil_server_P%d_", zTmpPath, iPort); | |
| 195 | 200 | fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); |
| 196 | 201 | if( zBrowser ){ |
| 197 | 202 | zBrowser = mprintf(zBrowser, iPort); |
| 198 | 203 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 199 | 204 | fossil_system(zBrowser); |
| 200 | 205 | } |
| 201 | 206 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 207 | + /* Set the service status to running and pass the listener socket to the | |
| 208 | + ** service handling procedures. */ | |
| 209 | + win32_http_service_running(s); | |
| 202 | 210 | for(;;){ |
| 203 | 211 | SOCKET client; |
| 204 | 212 | SOCKADDR_IN client_addr; |
| 205 | 213 | HttpRequest *p; |
| 206 | 214 | int len = sizeof(client_addr); |
| 215 | + int wsaError; | |
| 207 | 216 | |
| 208 | 217 | client = accept(s, (struct sockaddr*)&client_addr, &len); |
| 209 | - if( zStopper && file_size(zStopper)>=0 ){ | |
| 210 | - break; | |
| 211 | - } | |
| 212 | 218 | if( client==INVALID_SOCKET ){ |
| 213 | - closesocket(s); | |
| 214 | - fossil_fatal("error from accept()"); | |
| 219 | + /* If the service control handler has closed the listener socket, | |
| 220 | + ** cleanup and return, otherwise report a fatal error. */ | |
| 221 | + wsaError = WSAGetLastError(); | |
| 222 | + if( (wsaError==WSAEINTR) || (wsaError==WSAENOTSOCK) ){ | |
| 223 | + WSACleanup(); | |
| 224 | + return; | |
| 225 | + }else{ | |
| 226 | + closesocket(s); | |
| 227 | + WSACleanup(); | |
| 228 | + fossil_fatal("error from accept()"); | |
| 229 | + } | |
| 230 | + }else if( zStopper && file_size(zStopper)>=0 ){ | |
| 231 | + break; | |
| 215 | 232 | } |
| 216 | 233 | p = fossil_malloc( sizeof(*p) ); |
| 217 | 234 | p->id = ++idCnt; |
| 218 | 235 | p->s = client; |
| 219 | 236 | p->addr = client_addr; |
| @@ -221,7 +238,625 @@ | ||
| 221 | 238 | _beginthread(win32_process_one_http_request, 0, (void*)p); |
| 222 | 239 | } |
| 223 | 240 | closesocket(s); |
| 224 | 241 | WSACleanup(); |
| 225 | 242 | } |
| 243 | + | |
| 244 | +/* | |
| 245 | +** The HttpService structure is used to pass information to the service main | |
| 246 | +** function and to the service control handler function. | |
| 247 | +*/ | |
| 248 | +typedef struct HttpService HttpService; | |
| 249 | +struct HttpService { | |
| 250 | + int port; /* Port on which the http server should run */ | |
| 251 | + const char *zNotFound; /* The --notfound option, or NULL */ | |
| 252 | + int flags; /* One or more HTTP_SERVER_ flags */ | |
| 253 | + int isRunningAsService; /* Are we running as a service ? */ | |
| 254 | + const char *zServiceName; /* Name of the service */ | |
| 255 | + SOCKET s; /* Socket on which the http server listens */ | |
| 256 | +}; | |
| 257 | + | |
| 258 | +/* | |
| 259 | +** Variables used for running as windows service. | |
| 260 | +*/ | |
| 261 | +static HttpService hsData = {8080, NULL, 0, 0, NULL, INVALID_SOCKET}; | |
| 262 | +static SERVICE_STATUS ssStatus; | |
| 263 | +static SERVICE_STATUS_HANDLE sshStatusHandle; | |
| 264 | + | |
| 265 | +/* | |
| 266 | +** Get message string of the last system error. Return a pointer to the | |
| 267 | +** message string. Call fossil_mbcs_free() to deallocate any memory used | |
| 268 | +** to store the message string when done. | |
| 269 | +*/ | |
| 270 | +static char *win32_get_last_errmsg(void){ | |
| 271 | + DWORD nMsg; | |
| 272 | + LPTSTR tmp = NULL; | |
| 273 | + char *zMsg = NULL; | |
| 274 | + | |
| 275 | + nMsg = FormatMessage( | |
| 276 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
| 277 | + FORMAT_MESSAGE_FROM_SYSTEM | | |
| 278 | + FORMAT_MESSAGE_IGNORE_INSERTS, | |
| 279 | + NULL, | |
| 280 | + GetLastError(), | |
| 281 | + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), | |
| 282 | + (LPTSTR) &tmp, | |
| 283 | + 0, | |
| 284 | + NULL | |
| 285 | + ); | |
| 286 | + if( nMsg ){ | |
| 287 | + zMsg = fossil_mbcs_to_utf8(tmp); | |
| 288 | + }else{ | |
| 289 | + fossil_fatal("unable to get system error message."); | |
| 290 | + } | |
| 291 | + if( tmp ){ | |
| 292 | + LocalFree((HLOCAL) tmp); | |
| 293 | + } | |
| 294 | + return zMsg; | |
| 295 | +} | |
| 296 | + | |
| 297 | +/* | |
| 298 | +** Report the current status of the service to the service control manager. | |
| 299 | +** Make sure that during service startup no control codes are accepted. | |
| 300 | +*/ | |
| 301 | +static void win32_report_service_status( | |
| 302 | + DWORD dwCurrentState, /* The current state of the service */ | |
| 303 | + DWORD dwWin32ExitCode, /* The error code to report */ | |
| 304 | + DWORD dwWaitHint /* The estimated time for a pending operation */ | |
| 305 | +){ | |
| 306 | + if( dwCurrentState==SERVICE_START_PENDING) { | |
| 307 | + ssStatus.dwControlsAccepted = 0; | |
| 308 | + }else{ | |
| 309 | + ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; | |
| 310 | + } | |
| 311 | + ssStatus.dwCurrentState = dwCurrentState; | |
| 312 | + ssStatus.dwWin32ExitCode = dwWin32ExitCode; | |
| 313 | + ssStatus.dwWaitHint = dwWaitHint; | |
| 314 | + | |
| 315 | + if( (dwCurrentState==SERVICE_RUNNING) || | |
| 316 | + (dwCurrentState==SERVICE_STOPPED) ){ | |
| 317 | + ssStatus.dwCheckPoint = 0; | |
| 318 | + }else{ | |
| 319 | + ssStatus.dwCheckPoint++; | |
| 320 | + } | |
| 321 | + SetServiceStatus(sshStatusHandle, &ssStatus); | |
| 322 | + return ; | |
| 323 | +} | |
| 324 | + | |
| 325 | +/* | |
| 326 | +** Handle control codes sent from the service control manager. | |
| 327 | +** The control dispatcher in the main thread of the service process invokes | |
| 328 | +** this function whenever it receives a control request from the service | |
| 329 | +** control manager. | |
| 330 | +*/ | |
| 331 | +static void WINAPI win32_http_service_ctrl( | |
| 332 | + DWORD dwCtrlCode | |
| 333 | +){ | |
| 334 | + switch( dwCtrlCode ){ | |
| 335 | + case SERVICE_CONTROL_STOP: { | |
| 336 | + win32_report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 0); | |
| 337 | + if( hsData.s != INVALID_SOCKET ){ | |
| 338 | + closesocket(hsData.s); | |
| 339 | + } | |
| 340 | + win32_report_service_status(ssStatus.dwCurrentState, NO_ERROR, 0); | |
| 341 | + break; | |
| 342 | + } | |
| 343 | + default: { | |
| 344 | + break; | |
| 345 | + } | |
| 346 | + } | |
| 347 | + return; | |
| 348 | +} | |
| 349 | + | |
| 350 | +/* | |
| 351 | +** This is the main entry point for the service. | |
| 352 | +** When the service control manager receives a request to start the service, | |
| 353 | +** it starts the service process (if it is not already running). The main | |
| 354 | +** thread of the service process calls the StartServiceCtrlDispatcher | |
| 355 | +** function with a pointer to an array of SERVICE_TABLE_ENTRY structures. | |
| 356 | +** Then the service control manager sends a start request to the service | |
| 357 | +** control dispatcher for this service process. The service control dispatcher | |
| 358 | +** creates a new thread to execute the ServiceMain function (this function) | |
| 359 | +** of the service being started. | |
| 360 | +*/ | |
| 361 | +static void WINAPI win32_http_service_main( | |
| 362 | + DWORD argc, /* Number of arguments in argv */ | |
| 363 | + LPTSTR *argv /* Arguments passed */ | |
| 364 | +){ | |
| 365 | + | |
| 366 | + /* Update the service information. */ | |
| 367 | + hsData.isRunningAsService = 1; | |
| 368 | + if( argc>0 ){ | |
| 369 | + hsData.zServiceName = argv[0]; | |
| 370 | + } | |
| 371 | + | |
| 372 | + /* Register the service control handler function */ | |
| 373 | + sshStatusHandle = RegisterServiceCtrlHandler("", win32_http_service_ctrl); | |
| 374 | + if( !sshStatusHandle ){ | |
| 375 | + win32_report_service_status(SERVICE_STOPPED, NO_ERROR, 0); | |
| 376 | + return; | |
| 377 | + } | |
| 378 | + | |
| 379 | + /* Set service specific data and report that the service is starting. */ | |
| 380 | + ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; | |
| 381 | + ssStatus.dwServiceSpecificExitCode = 0; | |
| 382 | + win32_report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000); | |
| 383 | + | |
| 384 | + /* Execute the http server */ | |
| 385 | + win32_http_server(hsData.port, hsData.port, | |
| 386 | + NULL, NULL, hsData.zNotFound, hsData.flags); | |
| 387 | + | |
| 388 | + /* Service has stopped now. */ | |
| 389 | + win32_report_service_status(SERVICE_STOPPED, NO_ERROR, 0); | |
| 390 | + return; | |
| 391 | +} | |
| 392 | + | |
| 393 | +/* | |
| 394 | +** When running as service, update the HttpService structure with the | |
| 395 | +** listener socket and update the service status. This procedure must be | |
| 396 | +** called from the http server when he is ready to accept connections. | |
| 397 | +*/ | |
| 398 | +LOCAL void win32_http_service_running(SOCKET s){ | |
| 399 | + if( hsData.isRunningAsService ){ | |
| 400 | + hsData.s = s; | |
| 401 | + win32_report_service_status(SERVICE_RUNNING, NO_ERROR, 0); | |
| 402 | + } | |
| 403 | +} | |
| 404 | + | |
| 405 | +/* | |
| 406 | +** Try to start the http server as a windows service. If we are running in | |
| 407 | +** a interactive console session, this routine fails and returns a non zero | |
| 408 | +** integer value. When running as service, this routine does not return until | |
| 409 | +** the service is stopped. In this case, the return value is zero. | |
| 410 | +*/ | |
| 411 | +int win32_http_service( | |
| 412 | + int nPort, /* TCP port number */ | |
| 413 | + const char *zNotFound, /* The --notfound option, or NULL */ | |
| 414 | + int flags /* One or more HTTP_SERVER_ flags */ | |
| 415 | +){ | |
| 416 | + /* Define the service table. */ | |
| 417 | + SERVICE_TABLE_ENTRY ServiceTable[] = | |
| 418 | + {{"", (LPSERVICE_MAIN_FUNCTION)win32_http_service_main}, {NULL, NULL}}; | |
| 419 | + | |
| 420 | + /* Initialize the HttpService structure. */ | |
| 421 | + hsData.port = nPort; | |
| 422 | + hsData.zNotFound = zNotFound; | |
| 423 | + hsData.flags = flags; | |
| 424 | + | |
| 425 | + /* Try to start the control dispatcher thread for the service. */ | |
| 426 | + if( !StartServiceCtrlDispatcher(ServiceTable) ){ | |
| 427 | + if( GetLastError()==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ){ | |
| 428 | + return 1; | |
| 429 | + }else{ | |
| 430 | + fossil_fatal("error from StartServiceCtrlDispatcher()"); | |
| 431 | + } | |
| 432 | + } | |
| 433 | + return 0; | |
| 434 | +} | |
| 435 | + | |
| 436 | +/* | |
| 437 | +** COMMAND: winsrv | |
| 438 | +** Usage: fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS? | |
| 439 | +** | |
| 440 | +** Where METHOD is one of: create delete show start stop. | |
| 441 | +** | |
| 442 | +** The winsrv command manages Fossil as a Windows service. This allows | |
| 443 | +** (for example) Fossil to be running in the background when no user | |
| 444 | +** is logged in. | |
| 445 | +** | |
| 446 | +** In the following description of the methods, "Fossil-DSCM" will be | |
| 447 | +** used as the default SERVICE-NAME: | |
| 448 | +** | |
| 449 | +** fossil service create ?SERVICE-NAME? ?OPTIONS? | |
| 450 | +** | |
| 451 | +** Creates a service. Available options include: | |
| 452 | +** | |
| 453 | +** -D|--display DISPLAY-NAME | |
| 454 | +** | |
| 455 | +** Sets the display name of the service. This name is shown | |
| 456 | +** by graphical interface programs. By default, the display name | |
| 457 | +** equals to the service name. | |
| 458 | +** | |
| 459 | +** -S|--start TYPE | |
| 460 | +** | |
| 461 | +** Sets the start type of the service. TYPE can be "manual", | |
| 462 | +** which means you need to start the service yourself with the | |
| 463 | +** 'fossil service start' command or with the "net start" command | |
| 464 | +** from the operating system. If TYPE is set to "auto", the service | |
| 465 | +** will be started automatically by the system during startup. | |
| 466 | +** | |
| 467 | +** -U|--username USERNAME | |
| 468 | +** | |
| 469 | +** Specifies the user account which will be used to run the | |
| 470 | +** service. The account needs the "Logon as a service" right | |
| 471 | +** enabled in its profile. Specify local accounts as follows: | |
| 472 | +** ".\\USERNAME". By default, the "LocalSystem" account will be | |
| 473 | +** used. | |
| 474 | +** | |
| 475 | +** -W|--password PASSWORD | |
| 476 | +** | |
| 477 | +** Password for the user account. | |
| 478 | +** | |
| 479 | +** The following options are more or less the same as for the "server" | |
| 480 | +** command and influence the behaviour of the http server: | |
| 481 | +** | |
| 482 | +** -p|--port TCPPORT | |
| 483 | +** | |
| 484 | +** Specifies the TCP port (default port is 8080) on which the | |
| 485 | +** server should listen. | |
| 486 | +** | |
| 487 | +** -R|--repository REPOSITORY | |
| 488 | +** | |
| 489 | +** Specifies the name of the repository to be served. | |
| 490 | +** The repository option may be omitted if the working directory | |
| 491 | +** is within an open checkout. | |
| 492 | +** The REPOSITORY can be a directory (aka folder) that contains | |
| 493 | +** one or more respositories with names ending in ".fossil". | |
| 494 | +** In that case, the first element of the URL is used to select | |
| 495 | +** among the various repositories. | |
| 496 | +** | |
| 497 | +** --notfound URL | |
| 498 | +** | |
| 499 | +** If REPOSITORY is a directory that contains one or more | |
| 500 | +** respositories with names of the form "*.fossil" then the | |
| 501 | +** first element of the URL pathname selects among the various | |
| 502 | +** repositories. If the pathname does not select a valid | |
| 503 | +** repository and the --notfound option is available, | |
| 504 | +** then the server redirects (HTTP code 302) to the URL of | |
| 505 | +** --notfound. | |
| 506 | +** | |
| 507 | +** --localauth | |
| 508 | +** | |
| 509 | +** Enables automatic login if the --localauth option is present | |
| 510 | +** and the "localauth" setting is off and the connection is from | |
| 511 | +** localhost. | |
| 512 | +** | |
| 513 | +** | |
| 514 | +** fossil service delete ?SERVICE-NAME? | |
| 515 | +** | |
| 516 | +** Deletes a service. If the service is currently running, it will be | |
| 517 | +** stopped first and then deleted. | |
| 518 | +** | |
| 519 | +** | |
| 520 | +** fossil service show ?SERVICE-NAME? | |
| 521 | +** | |
| 522 | +** Shows how the service is configured and its current state. | |
| 523 | +** | |
| 524 | +** | |
| 525 | +** fossil service start ?SERVICE-NAME? | |
| 526 | +** | |
| 527 | +** Start the service. | |
| 528 | +** | |
| 529 | +** | |
| 530 | +** fossil service stop ?SERVICE-NAME? | |
| 531 | +** | |
| 532 | +** Stop the service. | |
| 533 | +** | |
| 534 | +** | |
| 535 | +** NOTE: This command is available on Windows operating systems only and | |
| 536 | +** requires administrative rights on the machine executed. | |
| 537 | +** | |
| 538 | +*/ | |
| 539 | +void cmd_win32_service(void){ | |
| 540 | + int n; | |
| 541 | + const char *zMethod; | |
| 542 | + const char *zSvcName = "Fossil-DSCM"; /* Default service name */ | |
| 543 | + | |
| 544 | + if( g.argc<3 ){ | |
| 545 | + usage("create|delete|show|start|stop ..."); | |
| 546 | + } | |
| 547 | + zMethod = g.argv[2]; | |
| 548 | + n = strlen(zMethod); | |
| 549 | + if( g.argc==4 ){ | |
| 550 | + zSvcName = g.argv[3]; | |
| 551 | + } | |
| 552 | + | |
| 553 | + if( strncmp(zMethod, "create", n)==0 ){ | |
| 554 | + SC_HANDLE hScm; | |
| 555 | + SC_HANDLE hSvc; | |
| 556 | + SERVICE_DESCRIPTION | |
| 557 | + svcDescr = {"Fossil - Distributed Software Configuration Management"}; | |
| 558 | + char *zErrFmt = "unable to create service '%s': %s"; | |
| 559 | + DWORD dwStartType = SERVICE_DEMAND_START; | |
| 560 | + const char *zDisplay; | |
| 561 | + const char *zStart; | |
| 562 | + const char *zUsername; | |
| 563 | + const char *zPassword; | |
| 564 | + const char *zPort; | |
| 565 | + const char *zNotFound; | |
| 566 | + const char *zLocalAuth; | |
| 567 | + const char *zRepository; | |
| 568 | + Blob binPath; | |
| 569 | + | |
| 570 | + /* Process service creation specific options. */ | |
| 571 | + zDisplay = find_option("display", "D", 1); | |
| 572 | + if( !zDisplay ){ | |
| 573 | + zDisplay = zSvcName; | |
| 574 | + } | |
| 575 | + zStart = find_option("start", "S", 1); | |
| 576 | + if( zStart ){ | |
| 577 | + if( strncmp(zStart, "auto", strlen(zStart))==0 ){ | |
| 578 | + dwStartType = SERVICE_AUTO_START; | |
| 579 | + }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ | |
| 580 | + dwStartType = SERVICE_DEMAND_START; | |
| 581 | + }else{ | |
| 582 | + fossil_fatal(zErrFmt, zSvcName, | |
| 583 | + "specify 'auto' or 'manual' for the '-S|--start' option"); | |
| 584 | + } | |
| 585 | + } | |
| 586 | + zUsername = find_option("username", "U", 1); | |
| 587 | + zPassword = find_option("password", "W", 1); | |
| 588 | + /* Process options for Fossil running as server. */ | |
| 589 | + zPort = find_option("port", "P", 1); | |
| 590 | + if( zPort && (atoi(zPort)<=0) ){ | |
| 591 | + fossil_fatal(zErrFmt, zSvcName, | |
| 592 | + "port number must be in the range 1 - 65535."); | |
| 593 | + } | |
| 594 | + zNotFound = find_option("notfound", 0, 1); | |
| 595 | + zLocalAuth = find_option("localauth", 0, 0); | |
| 596 | + zRepository = find_option("repository", "R", 1); | |
| 597 | + if( !zRepository ){ | |
| 598 | + db_must_be_within_tree(); | |
| 599 | + }else if( file_isdir(zRepository)==1 ){ | |
| 600 | + g.zRepositoryName = mprintf("%s", zRepository); | |
| 601 | + file_simplify_name(g.zRepositoryName, -1); | |
| 602 | + }else{ | |
| 603 | + db_open_repository(zRepository); | |
| 604 | + } | |
| 605 | + db_close(0); | |
| 606 | + verify_all_options(); | |
| 607 | + if( g.argc>4 ) fossil_fatal("to much arguments for create method."); | |
| 608 | + /* Build the fully-qualified path to the service binary file. */ | |
| 609 | + blob_zero(&binPath); | |
| 610 | + blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe()); | |
| 611 | + if( zPort ) blob_appendf(&binPath, " --port %s", zPort); | |
| 612 | + if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); | |
| 613 | + if( zLocalAuth ) blob_append(&binPath, " --localauth", -1); | |
| 614 | + blob_appendf(&binPath, " \"%s\"", g.zRepositoryName); | |
| 615 | + /* Create the service. */ | |
| 616 | + hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); | |
| 617 | + if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 618 | + hSvc = CreateService( | |
| 619 | + hScm, /* Handle to the SCM */ | |
| 620 | + fossil_utf8_to_mbcs(zSvcName), /* Name of the service */ | |
| 621 | + fossil_utf8_to_mbcs(zDisplay), /* Display name */ | |
| 622 | + SERVICE_ALL_ACCESS, /* Desired access */ | |
| 623 | + SERVICE_WIN32_OWN_PROCESS, /* Service type */ | |
| 624 | + dwStartType, /* Start type */ | |
| 625 | + SERVICE_ERROR_NORMAL, /* Error control */ | |
| 626 | + fossil_utf8_to_mbcs(blob_str(&binPath)), /* Binary path */ | |
| 627 | + NULL, /* Load ordering group */ | |
| 628 | + NULL, /* Tag value */ | |
| 629 | + NULL, /* Service dependencies */ | |
| 630 | + fossil_utf8_to_mbcs(zUsername), /* Service account */ | |
| 631 | + fossil_utf8_to_mbcs(zPassword) /* Account password */ | |
| 632 | + ); | |
| 633 | + if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 634 | + /* Set the service description. */ | |
| 635 | + ChangeServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); | |
| 636 | + fossil_print("Service '%s' successfully created.\n", zSvcName); | |
| 637 | + CloseServiceHandle(hSvc); | |
| 638 | + CloseServiceHandle(hScm); | |
| 639 | + }else | |
| 640 | + if( strncmp(zMethod, "delete", n)==0 ){ | |
| 641 | + SC_HANDLE hScm; | |
| 642 | + SC_HANDLE hSvc; | |
| 643 | + SERVICE_STATUS sstat; | |
| 644 | + char *zErrFmt = "unable to delete service '%s': %s"; | |
| 645 | + | |
| 646 | + verify_all_options(); | |
| 647 | + if( g.argc>4 ) fossil_fatal("to much arguments for delete method."); | |
| 648 | + hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); | |
| 649 | + if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 650 | + hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); | |
| 651 | + if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 652 | + QueryServiceStatus(hSvc, &sstat); | |
| 653 | + if( sstat.dwCurrentState!=SERVICE_STOPPED ){ | |
| 654 | + fossil_print("Stopping service '%s'", zSvcName); | |
| 655 | + if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ | |
| 656 | + if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ | |
| 657 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 658 | + } | |
| 659 | + } | |
| 660 | + while( sstat.dwCurrentState!=SERVICE_STOPPED ){ | |
| 661 | + Sleep(100); | |
| 662 | + fossil_print("."); | |
| 663 | + QueryServiceStatus(hSvc, &sstat); | |
| 664 | + } | |
| 665 | + fossil_print("\nService '%s' stopped.\n", zSvcName); | |
| 666 | + } | |
| 667 | + if( !DeleteService(hSvc) ){ | |
| 668 | + if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){ | |
| 669 | + fossil_warning("Service '%s' already marked for delete.\n", zSvcName); | |
| 670 | + }else{ | |
| 671 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 672 | + } | |
| 673 | + }else{ | |
| 674 | + fossil_print("Service '%s' successfully deleted.\n", zSvcName); | |
| 675 | + } | |
| 676 | + CloseServiceHandle(hSvc); | |
| 677 | + CloseServiceHandle(hScm); | |
| 678 | + }else | |
| 679 | + if( strncmp(zMethod, "show", n)==0 ){ | |
| 680 | + SC_HANDLE hScm; | |
| 681 | + SC_HANDLE hSvc; | |
| 682 | + SERVICE_STATUS sstat; | |
| 683 | + LPQUERY_SERVICE_CONFIG pSvcConfig; | |
| 684 | + LPSERVICE_DESCRIPTION pSvcDescr; | |
| 685 | + BOOL bStatus; | |
| 686 | + DWORD nRequired; | |
| 687 | + char *zErrFmt = "unable to show service '%s': %s"; | |
| 688 | + static const char *zSvcTypes[] = { | |
| 689 | + "Driver service", | |
| 690 | + "File system driver service", | |
| 691 | + "Service runs in its own process", | |
| 692 | + "Service shares a process with other services", | |
| 693 | + "Service can interact with the desktop" | |
| 694 | + }; | |
| 695 | + const char *zSvcType = ""; | |
| 696 | + static char *zSvcStartTypes[] = { | |
| 697 | + "Started by the system loader", | |
| 698 | + "Started by the IoInitSystem function", | |
| 699 | + "Started automatically by the service control manager", | |
| 700 | + "Started manually", | |
| 701 | + "Service cannot be started" | |
| 702 | + }; | |
| 703 | + const char *zSvcStartType = ""; | |
| 704 | + static const char *zSvcStates[] = { | |
| 705 | + "Stopped", "Starting", "Stopping", "Running", | |
| 706 | + "Continue pending", "Pause pending", "Paused" | |
| 707 | + }; | |
| 708 | + const char *zSvcState = ""; | |
| 709 | + | |
| 710 | + verify_all_options(); | |
| 711 | + if( g.argc>4 ) fossil_fatal("to much arguments for show method."); | |
| 712 | + hScm = OpenSCManager(NULL, NULL, GENERIC_READ); | |
| 713 | + if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 714 | + hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ); | |
| 715 | + if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 716 | + /* Get the service configuration */ | |
| 717 | + bStatus = QueryServiceConfig(hSvc, NULL, 0, &nRequired); | |
| 718 | + if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ | |
| 719 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 720 | + } | |
| 721 | + pSvcConfig = fossil_malloc(nRequired); | |
| 722 | + bStatus = QueryServiceConfig(hSvc, pSvcConfig, nRequired, &nRequired); | |
| 723 | + if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 724 | + /* Translate the service type */ | |
| 725 | + switch( pSvcConfig->dwServiceType ){ | |
| 726 | + case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break; | |
| 727 | + case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break; | |
| 728 | + case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break; | |
| 729 | + case SERVICE_WIN32_SHARE_PROCESS: zSvcType = zSvcTypes[3]; break; | |
| 730 | + case SERVICE_INTERACTIVE_PROCESS: zSvcType = zSvcTypes[4]; break; | |
| 731 | + } | |
| 732 | + /* Translate the service start type */ | |
| 733 | + switch( pSvcConfig->dwStartType ){ | |
| 734 | + case SERVICE_BOOT_START: zSvcStartType = zSvcStartTypes[0]; break; | |
| 735 | + case SERVICE_SYSTEM_START: zSvcStartType = zSvcStartTypes[1]; break; | |
| 736 | + case SERVICE_AUTO_START: zSvcStartType = zSvcStartTypes[2]; break; | |
| 737 | + case SERVICE_DEMAND_START: zSvcStartType = zSvcStartTypes[3]; break; | |
| 738 | + case SERVICE_DISABLED: zSvcStartType = zSvcStartTypes[4]; break; | |
| 739 | + } | |
| 740 | + /* Get the service description. */ | |
| 741 | + bStatus = QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, | |
| 742 | + NULL, 0, &nRequired); | |
| 743 | + if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ | |
| 744 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 745 | + } | |
| 746 | + pSvcDescr = fossil_malloc(nRequired); | |
| 747 | + bStatus = QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, | |
| 748 | + (LPBYTE)pSvcDescr, nRequired, &nRequired); | |
| 749 | + if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 750 | + /* Retrieves the current status of the specified service. */ | |
| 751 | + bStatus = QueryServiceStatus(hSvc, &sstat); | |
| 752 | + if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 753 | + /* Translate the current state. */ | |
| 754 | + switch( sstat.dwCurrentState ){ | |
| 755 | + case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break; | |
| 756 | + case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break; | |
| 757 | + case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break; | |
| 758 | + case SERVICE_RUNNING: zSvcState = zSvcStates[3]; break; | |
| 759 | + case SERVICE_CONTINUE_PENDING: zSvcState = zSvcStates[4]; break; | |
| 760 | + case SERVICE_PAUSE_PENDING: zSvcState = zSvcStates[5]; break; | |
| 761 | + case SERVICE_PAUSED: zSvcState = zSvcStates[6]; break; | |
| 762 | + } | |
| 763 | + /* Print service information to terminal */ | |
| 764 | + fossil_print("Service name .......: %s\n", zSvcName); | |
| 765 | + fossil_print("Display name .......: %s\n", | |
| 766 | + fossil_mbcs_to_utf8(pSvcConfig->lpDisplayName)); | |
| 767 | + fossil_print("Service description : %s\n", | |
| 768 | + fossil_mbcs_to_utf8(pSvcDescr->lpDescription)); | |
| 769 | + fossil_print("Service type .......: %s.\n", zSvcType); | |
| 770 | + fossil_print("Service start type .: %s.\n", zSvcStartType); | |
| 771 | + fossil_print("Binary path name ...: %s\n", | |
| 772 | + fossil_mbcs_to_utf8(pSvcConfig->lpBinaryPathName)); | |
| 773 | + fossil_print("Service username ...: %s\n", | |
| 774 | + fossil_mbcs_to_utf8(pSvcConfig->lpServiceStartName)); | |
| 775 | + fossil_print("Current state ......: %s.\n", zSvcState); | |
| 776 | + /* Cleanup */ | |
| 777 | + fossil_free(pSvcConfig); | |
| 778 | + fossil_free(pSvcDescr); | |
| 779 | + CloseServiceHandle(hSvc); | |
| 780 | + CloseServiceHandle(hScm); | |
| 781 | + }else | |
| 782 | + if( strncmp(zMethod, "start", n)==0 ){ | |
| 783 | + SC_HANDLE hScm; | |
| 784 | + SC_HANDLE hSvc; | |
| 785 | + SERVICE_STATUS sstat; | |
| 786 | + char *zErrFmt = "unable to start service '%s': %s"; | |
| 787 | + | |
| 788 | + verify_all_options(); | |
| 789 | + if( g.argc>4 ) fossil_fatal("to much arguments for start method."); | |
| 790 | + hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); | |
| 791 | + if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 792 | + hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); | |
| 793 | + if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 794 | + QueryServiceStatus(hSvc, &sstat); | |
| 795 | + if( sstat.dwCurrentState!=SERVICE_RUNNING ){ | |
| 796 | + fossil_print("Starting service '%s'", zSvcName); | |
| 797 | + if( sstat.dwCurrentState!=SERVICE_START_PENDING ){ | |
| 798 | + if( !StartService(hSvc, 0, NULL) ){ | |
| 799 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 800 | + } | |
| 801 | + } | |
| 802 | + while( sstat.dwCurrentState!=SERVICE_RUNNING ){ | |
| 803 | + Sleep(100); | |
| 804 | + fossil_print("."); | |
| 805 | + QueryServiceStatus(hSvc, &sstat); | |
| 806 | + } | |
| 807 | + fossil_print("\nService '%s' started.\n", zSvcName); | |
| 808 | + }else{ | |
| 809 | + fossil_print("Service '%s' is already started.\n", zSvcName); | |
| 810 | + } | |
| 811 | + CloseServiceHandle(hSvc); | |
| 812 | + CloseServiceHandle(hScm); | |
| 813 | + }else | |
| 814 | + if( strncmp(zMethod, "stop", n)==0 ){ | |
| 815 | + SC_HANDLE hScm; | |
| 816 | + SC_HANDLE hSvc; | |
| 817 | + SERVICE_STATUS sstat; | |
| 818 | + char *zErrFmt = "unable to stop service '%s': %s"; | |
| 819 | + | |
| 820 | + verify_all_options(); | |
| 821 | + if( g.argc>4 ) fossil_fatal("to much arguments for stop method."); | |
| 822 | + hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); | |
| 823 | + if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 824 | + hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); | |
| 825 | + if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 826 | + QueryServiceStatus(hSvc, &sstat); | |
| 827 | + if( sstat.dwCurrentState!=SERVICE_STOPPED ){ | |
| 828 | + fossil_print("Stopping service '%s'", zSvcName); | |
| 829 | + if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ | |
| 830 | + if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ | |
| 831 | + fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 832 | + } | |
| 833 | + } | |
| 834 | + while( sstat.dwCurrentState!=SERVICE_STOPPED ){ | |
| 835 | + Sleep(100); | |
| 836 | + fossil_print("."); | |
| 837 | + QueryServiceStatus(hSvc, &sstat); | |
| 838 | + } | |
| 839 | + fossil_print("\nService '%s' stopped.\n", zSvcName); | |
| 840 | + }else{ | |
| 841 | + fossil_print("Service '%s' is already stopped.\n", zSvcName); | |
| 842 | + } | |
| 843 | + CloseServiceHandle(hSvc); | |
| 844 | + CloseServiceHandle(hScm); | |
| 845 | + }else | |
| 846 | + { | |
| 847 | + fossil_fatal("METHOD should be one of:" | |
| 848 | + " create delete show start stop"); | |
| 849 | + } | |
| 850 | + return; | |
| 851 | +} | |
| 852 | + | |
| 853 | +#else /* _WIN32 -- This code is for win32 only */ | |
| 854 | +#include "winhttp.h" | |
| 855 | + | |
| 856 | +void cmd_win32_service(void){ | |
| 857 | + fossil_fatal("The service command is platform specific " | |
| 858 | + "and not available on this platform."); | |
| 859 | + return; | |
| 860 | +} | |
| 226 | 861 | |
| 227 | 862 | #endif /* _WIN32 -- This code is for win32 only */ |
| 228 | 863 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -14,17 +14,18 @@ | |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This file implements a very simple (and low-performance) HTTP server |
| 19 | ** for windows. |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #ifdef _WIN32 |
| 23 | /* This code is for win32 only */ |
| 24 | #include "winhttp.h" |
| 25 | #include <windows.h> |
| 26 | |
| 27 | /* |
| 28 | ** The HttpRequest structure holds information about each incoming |
| 29 | ** HTTP request. |
| 30 | */ |
| @@ -60,11 +61,11 @@ | |
| 60 | } |
| 61 | |
| 62 | /* |
| 63 | ** Process a single incoming HTTP request. |
| 64 | */ |
| 65 | void win32_process_one_http_request(void *pAppData){ |
| 66 | HttpRequest *p = (HttpRequest*)pAppData; |
| 67 | FILE *in = 0, *out = 0; |
| 68 | int amt, got; |
| 69 | int wanted = 0; |
| 70 | char *z; |
| @@ -145,10 +146,11 @@ | |
| 145 | SOCKET s = INVALID_SOCKET; |
| 146 | SOCKADDR_IN addr; |
| 147 | int idCnt = 0; |
| 148 | int iPort = mnPort; |
| 149 | Blob options; |
| 150 | |
| 151 | if( zStopper ) file_delete(zStopper); |
| 152 | blob_zero(&options); |
| 153 | if( zNotFound ){ |
| 154 | blob_appendf(&options, " --notfound %s", zNotFound); |
| @@ -189,31 +191,46 @@ | |
| 189 | }else{ |
| 190 | fossil_fatal("unable to open listening socket on any" |
| 191 | " port in the range %d..%d", mnPort, mxPort); |
| 192 | } |
| 193 | } |
| 194 | zTempPrefix = mprintf("fossil_server_P%d_", iPort); |
| 195 | fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); |
| 196 | if( zBrowser ){ |
| 197 | zBrowser = mprintf(zBrowser, iPort); |
| 198 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 199 | fossil_system(zBrowser); |
| 200 | } |
| 201 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 202 | for(;;){ |
| 203 | SOCKET client; |
| 204 | SOCKADDR_IN client_addr; |
| 205 | HttpRequest *p; |
| 206 | int len = sizeof(client_addr); |
| 207 | |
| 208 | client = accept(s, (struct sockaddr*)&client_addr, &len); |
| 209 | if( zStopper && file_size(zStopper)>=0 ){ |
| 210 | break; |
| 211 | } |
| 212 | if( client==INVALID_SOCKET ){ |
| 213 | closesocket(s); |
| 214 | fossil_fatal("error from accept()"); |
| 215 | } |
| 216 | p = fossil_malloc( sizeof(*p) ); |
| 217 | p->id = ++idCnt; |
| 218 | p->s = client; |
| 219 | p->addr = client_addr; |
| @@ -221,7 +238,625 @@ | |
| 221 | _beginthread(win32_process_one_http_request, 0, (void*)p); |
| 222 | } |
| 223 | closesocket(s); |
| 224 | WSACleanup(); |
| 225 | } |
| 226 | |
| 227 | #endif /* _WIN32 -- This code is for win32 only */ |
| 228 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -14,17 +14,18 @@ | |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This file implements a very simple (and low-performance) HTTP server |
| 19 | ** for windows. It also implements a Windows Service which allows the HTTP |
| 20 | ** server to be run without any user logged on. |
| 21 | */ |
| 22 | #include "config.h" |
| 23 | #ifdef _WIN32 |
| 24 | /* This code is for win32 only */ |
| 25 | #include <windows.h> |
| 26 | #include "winhttp.h" |
| 27 | |
| 28 | /* |
| 29 | ** The HttpRequest structure holds information about each incoming |
| 30 | ** HTTP request. |
| 31 | */ |
| @@ -60,11 +61,11 @@ | |
| 61 | } |
| 62 | |
| 63 | /* |
| 64 | ** Process a single incoming HTTP request. |
| 65 | */ |
| 66 | static void win32_process_one_http_request(void *pAppData){ |
| 67 | HttpRequest *p = (HttpRequest*)pAppData; |
| 68 | FILE *in = 0, *out = 0; |
| 69 | int amt, got; |
| 70 | int wanted = 0; |
| 71 | char *z; |
| @@ -145,10 +146,11 @@ | |
| 146 | SOCKET s = INVALID_SOCKET; |
| 147 | SOCKADDR_IN addr; |
| 148 | int idCnt = 0; |
| 149 | int iPort = mnPort; |
| 150 | Blob options; |
| 151 | char zTmpPath[MAX_PATH]; |
| 152 | |
| 153 | if( zStopper ) file_delete(zStopper); |
| 154 | blob_zero(&options); |
| 155 | if( zNotFound ){ |
| 156 | blob_appendf(&options, " --notfound %s", zNotFound); |
| @@ -189,31 +191,46 @@ | |
| 191 | }else{ |
| 192 | fossil_fatal("unable to open listening socket on any" |
| 193 | " port in the range %d..%d", mnPort, mxPort); |
| 194 | } |
| 195 | } |
| 196 | if( !GetTempPath(sizeof(zTmpPath), zTmpPath) ){ |
| 197 | fossil_fatal("unable to get path to the temporary directory."); |
| 198 | } |
| 199 | zTempPrefix = mprintf("%sfossil_server_P%d_", zTmpPath, iPort); |
| 200 | fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); |
| 201 | if( zBrowser ){ |
| 202 | zBrowser = mprintf(zBrowser, iPort); |
| 203 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 204 | fossil_system(zBrowser); |
| 205 | } |
| 206 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 207 | /* Set the service status to running and pass the listener socket to the |
| 208 | ** service handling procedures. */ |
| 209 | win32_http_service_running(s); |
| 210 | for(;;){ |
| 211 | SOCKET client; |
| 212 | SOCKADDR_IN client_addr; |
| 213 | HttpRequest *p; |
| 214 | int len = sizeof(client_addr); |
| 215 | int wsaError; |
| 216 | |
| 217 | client = accept(s, (struct sockaddr*)&client_addr, &len); |
| 218 | if( client==INVALID_SOCKET ){ |
| 219 | /* If the service control handler has closed the listener socket, |
| 220 | ** cleanup and return, otherwise report a fatal error. */ |
| 221 | wsaError = WSAGetLastError(); |
| 222 | if( (wsaError==WSAEINTR) || (wsaError==WSAENOTSOCK) ){ |
| 223 | WSACleanup(); |
| 224 | return; |
| 225 | }else{ |
| 226 | closesocket(s); |
| 227 | WSACleanup(); |
| 228 | fossil_fatal("error from accept()"); |
| 229 | } |
| 230 | }else if( zStopper && file_size(zStopper)>=0 ){ |
| 231 | break; |
| 232 | } |
| 233 | p = fossil_malloc( sizeof(*p) ); |
| 234 | p->id = ++idCnt; |
| 235 | p->s = client; |
| 236 | p->addr = client_addr; |
| @@ -221,7 +238,625 @@ | |
| 238 | _beginthread(win32_process_one_http_request, 0, (void*)p); |
| 239 | } |
| 240 | closesocket(s); |
| 241 | WSACleanup(); |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | ** The HttpService structure is used to pass information to the service main |
| 246 | ** function and to the service control handler function. |
| 247 | */ |
| 248 | typedef struct HttpService HttpService; |
| 249 | struct HttpService { |
| 250 | int port; /* Port on which the http server should run */ |
| 251 | const char *zNotFound; /* The --notfound option, or NULL */ |
| 252 | int flags; /* One or more HTTP_SERVER_ flags */ |
| 253 | int isRunningAsService; /* Are we running as a service ? */ |
| 254 | const char *zServiceName; /* Name of the service */ |
| 255 | SOCKET s; /* Socket on which the http server listens */ |
| 256 | }; |
| 257 | |
| 258 | /* |
| 259 | ** Variables used for running as windows service. |
| 260 | */ |
| 261 | static HttpService hsData = {8080, NULL, 0, 0, NULL, INVALID_SOCKET}; |
| 262 | static SERVICE_STATUS ssStatus; |
| 263 | static SERVICE_STATUS_HANDLE sshStatusHandle; |
| 264 | |
| 265 | /* |
| 266 | ** Get message string of the last system error. Return a pointer to the |
| 267 | ** message string. Call fossil_mbcs_free() to deallocate any memory used |
| 268 | ** to store the message string when done. |
| 269 | */ |
| 270 | static char *win32_get_last_errmsg(void){ |
| 271 | DWORD nMsg; |
| 272 | LPTSTR tmp = NULL; |
| 273 | char *zMsg = NULL; |
| 274 | |
| 275 | nMsg = FormatMessage( |
| 276 | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 277 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 278 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 279 | NULL, |
| 280 | GetLastError(), |
| 281 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), |
| 282 | (LPTSTR) &tmp, |
| 283 | 0, |
| 284 | NULL |
| 285 | ); |
| 286 | if( nMsg ){ |
| 287 | zMsg = fossil_mbcs_to_utf8(tmp); |
| 288 | }else{ |
| 289 | fossil_fatal("unable to get system error message."); |
| 290 | } |
| 291 | if( tmp ){ |
| 292 | LocalFree((HLOCAL) tmp); |
| 293 | } |
| 294 | return zMsg; |
| 295 | } |
| 296 | |
| 297 | /* |
| 298 | ** Report the current status of the service to the service control manager. |
| 299 | ** Make sure that during service startup no control codes are accepted. |
| 300 | */ |
| 301 | static void win32_report_service_status( |
| 302 | DWORD dwCurrentState, /* The current state of the service */ |
| 303 | DWORD dwWin32ExitCode, /* The error code to report */ |
| 304 | DWORD dwWaitHint /* The estimated time for a pending operation */ |
| 305 | ){ |
| 306 | if( dwCurrentState==SERVICE_START_PENDING) { |
| 307 | ssStatus.dwControlsAccepted = 0; |
| 308 | }else{ |
| 309 | ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; |
| 310 | } |
| 311 | ssStatus.dwCurrentState = dwCurrentState; |
| 312 | ssStatus.dwWin32ExitCode = dwWin32ExitCode; |
| 313 | ssStatus.dwWaitHint = dwWaitHint; |
| 314 | |
| 315 | if( (dwCurrentState==SERVICE_RUNNING) || |
| 316 | (dwCurrentState==SERVICE_STOPPED) ){ |
| 317 | ssStatus.dwCheckPoint = 0; |
| 318 | }else{ |
| 319 | ssStatus.dwCheckPoint++; |
| 320 | } |
| 321 | SetServiceStatus(sshStatusHandle, &ssStatus); |
| 322 | return ; |
| 323 | } |
| 324 | |
| 325 | /* |
| 326 | ** Handle control codes sent from the service control manager. |
| 327 | ** The control dispatcher in the main thread of the service process invokes |
| 328 | ** this function whenever it receives a control request from the service |
| 329 | ** control manager. |
| 330 | */ |
| 331 | static void WINAPI win32_http_service_ctrl( |
| 332 | DWORD dwCtrlCode |
| 333 | ){ |
| 334 | switch( dwCtrlCode ){ |
| 335 | case SERVICE_CONTROL_STOP: { |
| 336 | win32_report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 0); |
| 337 | if( hsData.s != INVALID_SOCKET ){ |
| 338 | closesocket(hsData.s); |
| 339 | } |
| 340 | win32_report_service_status(ssStatus.dwCurrentState, NO_ERROR, 0); |
| 341 | break; |
| 342 | } |
| 343 | default: { |
| 344 | break; |
| 345 | } |
| 346 | } |
| 347 | return; |
| 348 | } |
| 349 | |
| 350 | /* |
| 351 | ** This is the main entry point for the service. |
| 352 | ** When the service control manager receives a request to start the service, |
| 353 | ** it starts the service process (if it is not already running). The main |
| 354 | ** thread of the service process calls the StartServiceCtrlDispatcher |
| 355 | ** function with a pointer to an array of SERVICE_TABLE_ENTRY structures. |
| 356 | ** Then the service control manager sends a start request to the service |
| 357 | ** control dispatcher for this service process. The service control dispatcher |
| 358 | ** creates a new thread to execute the ServiceMain function (this function) |
| 359 | ** of the service being started. |
| 360 | */ |
| 361 | static void WINAPI win32_http_service_main( |
| 362 | DWORD argc, /* Number of arguments in argv */ |
| 363 | LPTSTR *argv /* Arguments passed */ |
| 364 | ){ |
| 365 | |
| 366 | /* Update the service information. */ |
| 367 | hsData.isRunningAsService = 1; |
| 368 | if( argc>0 ){ |
| 369 | hsData.zServiceName = argv[0]; |
| 370 | } |
| 371 | |
| 372 | /* Register the service control handler function */ |
| 373 | sshStatusHandle = RegisterServiceCtrlHandler("", win32_http_service_ctrl); |
| 374 | if( !sshStatusHandle ){ |
| 375 | win32_report_service_status(SERVICE_STOPPED, NO_ERROR, 0); |
| 376 | return; |
| 377 | } |
| 378 | |
| 379 | /* Set service specific data and report that the service is starting. */ |
| 380 | ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; |
| 381 | ssStatus.dwServiceSpecificExitCode = 0; |
| 382 | win32_report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000); |
| 383 | |
| 384 | /* Execute the http server */ |
| 385 | win32_http_server(hsData.port, hsData.port, |
| 386 | NULL, NULL, hsData.zNotFound, hsData.flags); |
| 387 | |
| 388 | /* Service has stopped now. */ |
| 389 | win32_report_service_status(SERVICE_STOPPED, NO_ERROR, 0); |
| 390 | return; |
| 391 | } |
| 392 | |
| 393 | /* |
| 394 | ** When running as service, update the HttpService structure with the |
| 395 | ** listener socket and update the service status. This procedure must be |
| 396 | ** called from the http server when he is ready to accept connections. |
| 397 | */ |
| 398 | LOCAL void win32_http_service_running(SOCKET s){ |
| 399 | if( hsData.isRunningAsService ){ |
| 400 | hsData.s = s; |
| 401 | win32_report_service_status(SERVICE_RUNNING, NO_ERROR, 0); |
| 402 | } |
| 403 | } |
| 404 | |
| 405 | /* |
| 406 | ** Try to start the http server as a windows service. If we are running in |
| 407 | ** a interactive console session, this routine fails and returns a non zero |
| 408 | ** integer value. When running as service, this routine does not return until |
| 409 | ** the service is stopped. In this case, the return value is zero. |
| 410 | */ |
| 411 | int win32_http_service( |
| 412 | int nPort, /* TCP port number */ |
| 413 | const char *zNotFound, /* The --notfound option, or NULL */ |
| 414 | int flags /* One or more HTTP_SERVER_ flags */ |
| 415 | ){ |
| 416 | /* Define the service table. */ |
| 417 | SERVICE_TABLE_ENTRY ServiceTable[] = |
| 418 | {{"", (LPSERVICE_MAIN_FUNCTION)win32_http_service_main}, {NULL, NULL}}; |
| 419 | |
| 420 | /* Initialize the HttpService structure. */ |
| 421 | hsData.port = nPort; |
| 422 | hsData.zNotFound = zNotFound; |
| 423 | hsData.flags = flags; |
| 424 | |
| 425 | /* Try to start the control dispatcher thread for the service. */ |
| 426 | if( !StartServiceCtrlDispatcher(ServiceTable) ){ |
| 427 | if( GetLastError()==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ){ |
| 428 | return 1; |
| 429 | }else{ |
| 430 | fossil_fatal("error from StartServiceCtrlDispatcher()"); |
| 431 | } |
| 432 | } |
| 433 | return 0; |
| 434 | } |
| 435 | |
| 436 | /* |
| 437 | ** COMMAND: winsrv |
| 438 | ** Usage: fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS? |
| 439 | ** |
| 440 | ** Where METHOD is one of: create delete show start stop. |
| 441 | ** |
| 442 | ** The winsrv command manages Fossil as a Windows service. This allows |
| 443 | ** (for example) Fossil to be running in the background when no user |
| 444 | ** is logged in. |
| 445 | ** |
| 446 | ** In the following description of the methods, "Fossil-DSCM" will be |
| 447 | ** used as the default SERVICE-NAME: |
| 448 | ** |
| 449 | ** fossil service create ?SERVICE-NAME? ?OPTIONS? |
| 450 | ** |
| 451 | ** Creates a service. Available options include: |
| 452 | ** |
| 453 | ** -D|--display DISPLAY-NAME |
| 454 | ** |
| 455 | ** Sets the display name of the service. This name is shown |
| 456 | ** by graphical interface programs. By default, the display name |
| 457 | ** equals to the service name. |
| 458 | ** |
| 459 | ** -S|--start TYPE |
| 460 | ** |
| 461 | ** Sets the start type of the service. TYPE can be "manual", |
| 462 | ** which means you need to start the service yourself with the |
| 463 | ** 'fossil service start' command or with the "net start" command |
| 464 | ** from the operating system. If TYPE is set to "auto", the service |
| 465 | ** will be started automatically by the system during startup. |
| 466 | ** |
| 467 | ** -U|--username USERNAME |
| 468 | ** |
| 469 | ** Specifies the user account which will be used to run the |
| 470 | ** service. The account needs the "Logon as a service" right |
| 471 | ** enabled in its profile. Specify local accounts as follows: |
| 472 | ** ".\\USERNAME". By default, the "LocalSystem" account will be |
| 473 | ** used. |
| 474 | ** |
| 475 | ** -W|--password PASSWORD |
| 476 | ** |
| 477 | ** Password for the user account. |
| 478 | ** |
| 479 | ** The following options are more or less the same as for the "server" |
| 480 | ** command and influence the behaviour of the http server: |
| 481 | ** |
| 482 | ** -p|--port TCPPORT |
| 483 | ** |
| 484 | ** Specifies the TCP port (default port is 8080) on which the |
| 485 | ** server should listen. |
| 486 | ** |
| 487 | ** -R|--repository REPOSITORY |
| 488 | ** |
| 489 | ** Specifies the name of the repository to be served. |
| 490 | ** The repository option may be omitted if the working directory |
| 491 | ** is within an open checkout. |
| 492 | ** The REPOSITORY can be a directory (aka folder) that contains |
| 493 | ** one or more respositories with names ending in ".fossil". |
| 494 | ** In that case, the first element of the URL is used to select |
| 495 | ** among the various repositories. |
| 496 | ** |
| 497 | ** --notfound URL |
| 498 | ** |
| 499 | ** If REPOSITORY is a directory that contains one or more |
| 500 | ** respositories with names of the form "*.fossil" then the |
| 501 | ** first element of the URL pathname selects among the various |
| 502 | ** repositories. If the pathname does not select a valid |
| 503 | ** repository and the --notfound option is available, |
| 504 | ** then the server redirects (HTTP code 302) to the URL of |
| 505 | ** --notfound. |
| 506 | ** |
| 507 | ** --localauth |
| 508 | ** |
| 509 | ** Enables automatic login if the --localauth option is present |
| 510 | ** and the "localauth" setting is off and the connection is from |
| 511 | ** localhost. |
| 512 | ** |
| 513 | ** |
| 514 | ** fossil service delete ?SERVICE-NAME? |
| 515 | ** |
| 516 | ** Deletes a service. If the service is currently running, it will be |
| 517 | ** stopped first and then deleted. |
| 518 | ** |
| 519 | ** |
| 520 | ** fossil service show ?SERVICE-NAME? |
| 521 | ** |
| 522 | ** Shows how the service is configured and its current state. |
| 523 | ** |
| 524 | ** |
| 525 | ** fossil service start ?SERVICE-NAME? |
| 526 | ** |
| 527 | ** Start the service. |
| 528 | ** |
| 529 | ** |
| 530 | ** fossil service stop ?SERVICE-NAME? |
| 531 | ** |
| 532 | ** Stop the service. |
| 533 | ** |
| 534 | ** |
| 535 | ** NOTE: This command is available on Windows operating systems only and |
| 536 | ** requires administrative rights on the machine executed. |
| 537 | ** |
| 538 | */ |
| 539 | void cmd_win32_service(void){ |
| 540 | int n; |
| 541 | const char *zMethod; |
| 542 | const char *zSvcName = "Fossil-DSCM"; /* Default service name */ |
| 543 | |
| 544 | if( g.argc<3 ){ |
| 545 | usage("create|delete|show|start|stop ..."); |
| 546 | } |
| 547 | zMethod = g.argv[2]; |
| 548 | n = strlen(zMethod); |
| 549 | if( g.argc==4 ){ |
| 550 | zSvcName = g.argv[3]; |
| 551 | } |
| 552 | |
| 553 | if( strncmp(zMethod, "create", n)==0 ){ |
| 554 | SC_HANDLE hScm; |
| 555 | SC_HANDLE hSvc; |
| 556 | SERVICE_DESCRIPTION |
| 557 | svcDescr = {"Fossil - Distributed Software Configuration Management"}; |
| 558 | char *zErrFmt = "unable to create service '%s': %s"; |
| 559 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 560 | const char *zDisplay; |
| 561 | const char *zStart; |
| 562 | const char *zUsername; |
| 563 | const char *zPassword; |
| 564 | const char *zPort; |
| 565 | const char *zNotFound; |
| 566 | const char *zLocalAuth; |
| 567 | const char *zRepository; |
| 568 | Blob binPath; |
| 569 | |
| 570 | /* Process service creation specific options. */ |
| 571 | zDisplay = find_option("display", "D", 1); |
| 572 | if( !zDisplay ){ |
| 573 | zDisplay = zSvcName; |
| 574 | } |
| 575 | zStart = find_option("start", "S", 1); |
| 576 | if( zStart ){ |
| 577 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 578 | dwStartType = SERVICE_AUTO_START; |
| 579 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 580 | dwStartType = SERVICE_DEMAND_START; |
| 581 | }else{ |
| 582 | fossil_fatal(zErrFmt, zSvcName, |
| 583 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 584 | } |
| 585 | } |
| 586 | zUsername = find_option("username", "U", 1); |
| 587 | zPassword = find_option("password", "W", 1); |
| 588 | /* Process options for Fossil running as server. */ |
| 589 | zPort = find_option("port", "P", 1); |
| 590 | if( zPort && (atoi(zPort)<=0) ){ |
| 591 | fossil_fatal(zErrFmt, zSvcName, |
| 592 | "port number must be in the range 1 - 65535."); |
| 593 | } |
| 594 | zNotFound = find_option("notfound", 0, 1); |
| 595 | zLocalAuth = find_option("localauth", 0, 0); |
| 596 | zRepository = find_option("repository", "R", 1); |
| 597 | if( !zRepository ){ |
| 598 | db_must_be_within_tree(); |
| 599 | }else if( file_isdir(zRepository)==1 ){ |
| 600 | g.zRepositoryName = mprintf("%s", zRepository); |
| 601 | file_simplify_name(g.zRepositoryName, -1); |
| 602 | }else{ |
| 603 | db_open_repository(zRepository); |
| 604 | } |
| 605 | db_close(0); |
| 606 | verify_all_options(); |
| 607 | if( g.argc>4 ) fossil_fatal("to much arguments for create method."); |
| 608 | /* Build the fully-qualified path to the service binary file. */ |
| 609 | blob_zero(&binPath); |
| 610 | blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe()); |
| 611 | if( zPort ) blob_appendf(&binPath, " --port %s", zPort); |
| 612 | if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); |
| 613 | if( zLocalAuth ) blob_append(&binPath, " --localauth", -1); |
| 614 | blob_appendf(&binPath, " \"%s\"", g.zRepositoryName); |
| 615 | /* Create the service. */ |
| 616 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 617 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 618 | hSvc = CreateService( |
| 619 | hScm, /* Handle to the SCM */ |
| 620 | fossil_utf8_to_mbcs(zSvcName), /* Name of the service */ |
| 621 | fossil_utf8_to_mbcs(zDisplay), /* Display name */ |
| 622 | SERVICE_ALL_ACCESS, /* Desired access */ |
| 623 | SERVICE_WIN32_OWN_PROCESS, /* Service type */ |
| 624 | dwStartType, /* Start type */ |
| 625 | SERVICE_ERROR_NORMAL, /* Error control */ |
| 626 | fossil_utf8_to_mbcs(blob_str(&binPath)), /* Binary path */ |
| 627 | NULL, /* Load ordering group */ |
| 628 | NULL, /* Tag value */ |
| 629 | NULL, /* Service dependencies */ |
| 630 | fossil_utf8_to_mbcs(zUsername), /* Service account */ |
| 631 | fossil_utf8_to_mbcs(zPassword) /* Account password */ |
| 632 | ); |
| 633 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 634 | /* Set the service description. */ |
| 635 | ChangeServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| 636 | fossil_print("Service '%s' successfully created.\n", zSvcName); |
| 637 | CloseServiceHandle(hSvc); |
| 638 | CloseServiceHandle(hScm); |
| 639 | }else |
| 640 | if( strncmp(zMethod, "delete", n)==0 ){ |
| 641 | SC_HANDLE hScm; |
| 642 | SC_HANDLE hSvc; |
| 643 | SERVICE_STATUS sstat; |
| 644 | char *zErrFmt = "unable to delete service '%s': %s"; |
| 645 | |
| 646 | verify_all_options(); |
| 647 | if( g.argc>4 ) fossil_fatal("to much arguments for delete method."); |
| 648 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 649 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 650 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 651 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 652 | QueryServiceStatus(hSvc, &sstat); |
| 653 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 654 | fossil_print("Stopping service '%s'", zSvcName); |
| 655 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 656 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 657 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 658 | } |
| 659 | } |
| 660 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 661 | Sleep(100); |
| 662 | fossil_print("."); |
| 663 | QueryServiceStatus(hSvc, &sstat); |
| 664 | } |
| 665 | fossil_print("\nService '%s' stopped.\n", zSvcName); |
| 666 | } |
| 667 | if( !DeleteService(hSvc) ){ |
| 668 | if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){ |
| 669 | fossil_warning("Service '%s' already marked for delete.\n", zSvcName); |
| 670 | }else{ |
| 671 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 672 | } |
| 673 | }else{ |
| 674 | fossil_print("Service '%s' successfully deleted.\n", zSvcName); |
| 675 | } |
| 676 | CloseServiceHandle(hSvc); |
| 677 | CloseServiceHandle(hScm); |
| 678 | }else |
| 679 | if( strncmp(zMethod, "show", n)==0 ){ |
| 680 | SC_HANDLE hScm; |
| 681 | SC_HANDLE hSvc; |
| 682 | SERVICE_STATUS sstat; |
| 683 | LPQUERY_SERVICE_CONFIG pSvcConfig; |
| 684 | LPSERVICE_DESCRIPTION pSvcDescr; |
| 685 | BOOL bStatus; |
| 686 | DWORD nRequired; |
| 687 | char *zErrFmt = "unable to show service '%s': %s"; |
| 688 | static const char *zSvcTypes[] = { |
| 689 | "Driver service", |
| 690 | "File system driver service", |
| 691 | "Service runs in its own process", |
| 692 | "Service shares a process with other services", |
| 693 | "Service can interact with the desktop" |
| 694 | }; |
| 695 | const char *zSvcType = ""; |
| 696 | static char *zSvcStartTypes[] = { |
| 697 | "Started by the system loader", |
| 698 | "Started by the IoInitSystem function", |
| 699 | "Started automatically by the service control manager", |
| 700 | "Started manually", |
| 701 | "Service cannot be started" |
| 702 | }; |
| 703 | const char *zSvcStartType = ""; |
| 704 | static const char *zSvcStates[] = { |
| 705 | "Stopped", "Starting", "Stopping", "Running", |
| 706 | "Continue pending", "Pause pending", "Paused" |
| 707 | }; |
| 708 | const char *zSvcState = ""; |
| 709 | |
| 710 | verify_all_options(); |
| 711 | if( g.argc>4 ) fossil_fatal("to much arguments for show method."); |
| 712 | hScm = OpenSCManager(NULL, NULL, GENERIC_READ); |
| 713 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 714 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ); |
| 715 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 716 | /* Get the service configuration */ |
| 717 | bStatus = QueryServiceConfig(hSvc, NULL, 0, &nRequired); |
| 718 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 719 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 720 | } |
| 721 | pSvcConfig = fossil_malloc(nRequired); |
| 722 | bStatus = QueryServiceConfig(hSvc, pSvcConfig, nRequired, &nRequired); |
| 723 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 724 | /* Translate the service type */ |
| 725 | switch( pSvcConfig->dwServiceType ){ |
| 726 | case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break; |
| 727 | case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break; |
| 728 | case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break; |
| 729 | case SERVICE_WIN32_SHARE_PROCESS: zSvcType = zSvcTypes[3]; break; |
| 730 | case SERVICE_INTERACTIVE_PROCESS: zSvcType = zSvcTypes[4]; break; |
| 731 | } |
| 732 | /* Translate the service start type */ |
| 733 | switch( pSvcConfig->dwStartType ){ |
| 734 | case SERVICE_BOOT_START: zSvcStartType = zSvcStartTypes[0]; break; |
| 735 | case SERVICE_SYSTEM_START: zSvcStartType = zSvcStartTypes[1]; break; |
| 736 | case SERVICE_AUTO_START: zSvcStartType = zSvcStartTypes[2]; break; |
| 737 | case SERVICE_DEMAND_START: zSvcStartType = zSvcStartTypes[3]; break; |
| 738 | case SERVICE_DISABLED: zSvcStartType = zSvcStartTypes[4]; break; |
| 739 | } |
| 740 | /* Get the service description. */ |
| 741 | bStatus = QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 742 | NULL, 0, &nRequired); |
| 743 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 744 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 745 | } |
| 746 | pSvcDescr = fossil_malloc(nRequired); |
| 747 | bStatus = QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 748 | (LPBYTE)pSvcDescr, nRequired, &nRequired); |
| 749 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 750 | /* Retrieves the current status of the specified service. */ |
| 751 | bStatus = QueryServiceStatus(hSvc, &sstat); |
| 752 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 753 | /* Translate the current state. */ |
| 754 | switch( sstat.dwCurrentState ){ |
| 755 | case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break; |
| 756 | case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break; |
| 757 | case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break; |
| 758 | case SERVICE_RUNNING: zSvcState = zSvcStates[3]; break; |
| 759 | case SERVICE_CONTINUE_PENDING: zSvcState = zSvcStates[4]; break; |
| 760 | case SERVICE_PAUSE_PENDING: zSvcState = zSvcStates[5]; break; |
| 761 | case SERVICE_PAUSED: zSvcState = zSvcStates[6]; break; |
| 762 | } |
| 763 | /* Print service information to terminal */ |
| 764 | fossil_print("Service name .......: %s\n", zSvcName); |
| 765 | fossil_print("Display name .......: %s\n", |
| 766 | fossil_mbcs_to_utf8(pSvcConfig->lpDisplayName)); |
| 767 | fossil_print("Service description : %s\n", |
| 768 | fossil_mbcs_to_utf8(pSvcDescr->lpDescription)); |
| 769 | fossil_print("Service type .......: %s.\n", zSvcType); |
| 770 | fossil_print("Service start type .: %s.\n", zSvcStartType); |
| 771 | fossil_print("Binary path name ...: %s\n", |
| 772 | fossil_mbcs_to_utf8(pSvcConfig->lpBinaryPathName)); |
| 773 | fossil_print("Service username ...: %s\n", |
| 774 | fossil_mbcs_to_utf8(pSvcConfig->lpServiceStartName)); |
| 775 | fossil_print("Current state ......: %s.\n", zSvcState); |
| 776 | /* Cleanup */ |
| 777 | fossil_free(pSvcConfig); |
| 778 | fossil_free(pSvcDescr); |
| 779 | CloseServiceHandle(hSvc); |
| 780 | CloseServiceHandle(hScm); |
| 781 | }else |
| 782 | if( strncmp(zMethod, "start", n)==0 ){ |
| 783 | SC_HANDLE hScm; |
| 784 | SC_HANDLE hSvc; |
| 785 | SERVICE_STATUS sstat; |
| 786 | char *zErrFmt = "unable to start service '%s': %s"; |
| 787 | |
| 788 | verify_all_options(); |
| 789 | if( g.argc>4 ) fossil_fatal("to much arguments for start method."); |
| 790 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 791 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 792 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 793 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 794 | QueryServiceStatus(hSvc, &sstat); |
| 795 | if( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 796 | fossil_print("Starting service '%s'", zSvcName); |
| 797 | if( sstat.dwCurrentState!=SERVICE_START_PENDING ){ |
| 798 | if( !StartService(hSvc, 0, NULL) ){ |
| 799 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 800 | } |
| 801 | } |
| 802 | while( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 803 | Sleep(100); |
| 804 | fossil_print("."); |
| 805 | QueryServiceStatus(hSvc, &sstat); |
| 806 | } |
| 807 | fossil_print("\nService '%s' started.\n", zSvcName); |
| 808 | }else{ |
| 809 | fossil_print("Service '%s' is already started.\n", zSvcName); |
| 810 | } |
| 811 | CloseServiceHandle(hSvc); |
| 812 | CloseServiceHandle(hScm); |
| 813 | }else |
| 814 | if( strncmp(zMethod, "stop", n)==0 ){ |
| 815 | SC_HANDLE hScm; |
| 816 | SC_HANDLE hSvc; |
| 817 | SERVICE_STATUS sstat; |
| 818 | char *zErrFmt = "unable to stop service '%s': %s"; |
| 819 | |
| 820 | verify_all_options(); |
| 821 | if( g.argc>4 ) fossil_fatal("to much arguments for stop method."); |
| 822 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 823 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 824 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 825 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 826 | QueryServiceStatus(hSvc, &sstat); |
| 827 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 828 | fossil_print("Stopping service '%s'", zSvcName); |
| 829 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 830 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 831 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 832 | } |
| 833 | } |
| 834 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 835 | Sleep(100); |
| 836 | fossil_print("."); |
| 837 | QueryServiceStatus(hSvc, &sstat); |
| 838 | } |
| 839 | fossil_print("\nService '%s' stopped.\n", zSvcName); |
| 840 | }else{ |
| 841 | fossil_print("Service '%s' is already stopped.\n", zSvcName); |
| 842 | } |
| 843 | CloseServiceHandle(hSvc); |
| 844 | CloseServiceHandle(hScm); |
| 845 | }else |
| 846 | { |
| 847 | fossil_fatal("METHOD should be one of:" |
| 848 | " create delete show start stop"); |
| 849 | } |
| 850 | return; |
| 851 | } |
| 852 | |
| 853 | #else /* _WIN32 -- This code is for win32 only */ |
| 854 | #include "winhttp.h" |
| 855 | |
| 856 | void cmd_win32_service(void){ |
| 857 | fossil_fatal("The service command is platform specific " |
| 858 | "and not available on this platform."); |
| 859 | return; |
| 860 | } |
| 861 | |
| 862 | #endif /* _WIN32 -- This code is for win32 only */ |
| 863 |
+7
-1
| --- test/release-checklist.wiki | ||
| +++ test/release-checklist.wiki | ||
| @@ -21,10 +21,11 @@ | ||
| 21 | 21 | <li> Linux x86 |
| 22 | 22 | <li> Linux x86_64 |
| 23 | 23 | <li> Mac x86 |
| 24 | 24 | <li> Mac x86_64 |
| 25 | 25 | <li> Windows (mingw) |
| 26 | +<li> Windows (vc++) | |
| 26 | 27 | <li> OpenBSD |
| 27 | 28 | </ol> |
| 28 | 29 | |
| 29 | 30 | <li><p> |
| 30 | 31 | Run at least one occurrence of the the following commands on every |
| @@ -56,11 +57,16 @@ | ||
| 56 | 57 | |
| 57 | 58 | <li><p> |
| 58 | 59 | Use the release candidate version of fossil in production on the |
| 59 | 60 | [http://www.fossil-scm.org/] website for at least 48 hours (without |
| 60 | 61 | incident) prior to making the release official. |
| 62 | + | |
| 63 | +<li><p> | |
| 64 | +Verify that the [../www/changes.wiki | Change Log] is correct and | |
| 65 | +up-to-date. | |
| 61 | 66 | </ol> |
| 62 | 67 | |
| 63 | 68 | <hr> |
| 64 | 69 | |
| 65 | 70 | Upon successful completion of all tests above, tag the release candidate |
| 66 | -with the "release" tag and set its background color to "#d0c0ff". | |
| 71 | +with the "release" tag and set its background color to "#d0c0ff". Update | |
| 72 | +the www/changes.wiki file to show the date of the release. | |
| 67 | 73 |
| --- test/release-checklist.wiki | |
| +++ test/release-checklist.wiki | |
| @@ -21,10 +21,11 @@ | |
| 21 | <li> Linux x86 |
| 22 | <li> Linux x86_64 |
| 23 | <li> Mac x86 |
| 24 | <li> Mac x86_64 |
| 25 | <li> Windows (mingw) |
| 26 | <li> OpenBSD |
| 27 | </ol> |
| 28 | |
| 29 | <li><p> |
| 30 | Run at least one occurrence of the the following commands on every |
| @@ -56,11 +57,16 @@ | |
| 56 | |
| 57 | <li><p> |
| 58 | Use the release candidate version of fossil in production on the |
| 59 | [http://www.fossil-scm.org/] website for at least 48 hours (without |
| 60 | incident) prior to making the release official. |
| 61 | </ol> |
| 62 | |
| 63 | <hr> |
| 64 | |
| 65 | Upon successful completion of all tests above, tag the release candidate |
| 66 | with the "release" tag and set its background color to "#d0c0ff". |
| 67 |
| --- test/release-checklist.wiki | |
| +++ test/release-checklist.wiki | |
| @@ -21,10 +21,11 @@ | |
| 21 | <li> Linux x86 |
| 22 | <li> Linux x86_64 |
| 23 | <li> Mac x86 |
| 24 | <li> Mac x86_64 |
| 25 | <li> Windows (mingw) |
| 26 | <li> Windows (vc++) |
| 27 | <li> OpenBSD |
| 28 | </ol> |
| 29 | |
| 30 | <li><p> |
| 31 | Run at least one occurrence of the the following commands on every |
| @@ -56,11 +57,16 @@ | |
| 57 | |
| 58 | <li><p> |
| 59 | Use the release candidate version of fossil in production on the |
| 60 | [http://www.fossil-scm.org/] website for at least 48 hours (without |
| 61 | incident) prior to making the release official. |
| 62 | |
| 63 | <li><p> |
| 64 | Verify that the [../www/changes.wiki | Change Log] is correct and |
| 65 | up-to-date. |
| 66 | </ol> |
| 67 | |
| 68 | <hr> |
| 69 | |
| 70 | Upon successful completion of all tests above, tag the release candidate |
| 71 | with the "release" tag and set its background color to "#d0c0ff". Update |
| 72 | the www/changes.wiki file to show the date of the release. |
| 73 |
+2
-2
| --- win/Makefile.PellesCGMake | ||
| +++ win/Makefile.PellesCGMake | ||
| @@ -138,12 +138,12 @@ | ||
| 138 | 138 | # generate the index source, containing all web references,.. |
| 139 | 139 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 140 | 140 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 141 | 141 | |
| 142 | 142 | # extracting version info from manifest |
| 143 | -VERSION.h: version.exe ..\manifest.uuid ..\manifest | |
| 144 | - version.exe ..\manifest.uuid ..\manifest > $@ | |
| 143 | +VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION | |
| 144 | + version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ | |
| 145 | 145 | |
| 146 | 146 | # generate the simplified headers |
| 147 | 147 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 148 | 148 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 149 | 149 | echo Done >$@ |
| 150 | 150 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -138,12 +138,12 @@ | |
| 138 | # generate the index source, containing all web references,.. |
| 139 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 140 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 141 | |
| 142 | # extracting version info from manifest |
| 143 | VERSION.h: version.exe ..\manifest.uuid ..\manifest |
| 144 | version.exe ..\manifest.uuid ..\manifest > $@ |
| 145 | |
| 146 | # generate the simplified headers |
| 147 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 148 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 149 | echo Done >$@ |
| 150 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -138,12 +138,12 @@ | |
| 138 | # generate the index source, containing all web references,.. |
| 139 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 140 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 141 | |
| 142 | # extracting version info from manifest |
| 143 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 144 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 145 | |
| 146 | # generate the simplified headers |
| 147 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 148 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 149 | echo Done >$@ |
| 150 |
+1
-1
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -73,11 +73,11 @@ | ||
| 73 | 73 | $(TCC) -o$@ -c $** |
| 74 | 74 | |
| 75 | 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | 76 | $(TCC) -o$@ -c $** |
| 77 | 77 | |
| 78 | -VERSION.h : version$E $B\manifest.uuid $B\manifest | |
| 78 | +VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 79 | 79 | +$** > $@ |
| 80 | 80 | |
| 81 | 81 | page_index.h: mkindex$E $(SRC) |
| 82 | 82 | +$** > $@ |
| 83 | 83 | |
| 84 | 84 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -73,11 +73,11 @@ | |
| 73 | $(TCC) -o$@ -c $** |
| 74 | |
| 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | $(TCC) -o$@ -c $** |
| 77 | |
| 78 | VERSION.h : version$E $B\manifest.uuid $B\manifest |
| 79 | +$** > $@ |
| 80 | |
| 81 | page_index.h: mkindex$E $(SRC) |
| 82 | +$** > $@ |
| 83 | |
| 84 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -73,11 +73,11 @@ | |
| 73 | $(TCC) -o$@ -c $** |
| 74 | |
| 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | $(TCC) -o$@ -c $** |
| 77 | |
| 78 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 79 | +$** > $@ |
| 80 | |
| 81 | page_index.h: mkindex$E $(SRC) |
| 82 | +$** > $@ |
| 83 | |
| 84 |
+2
-2
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -361,11 +361,11 @@ | ||
| 361 | 361 | # the repository after running the tests. |
| 362 | 362 | test: $(APPNAME) |
| 363 | 363 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 364 | 364 | |
| 365 | 365 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 366 | - $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest >$(OBJDIR)/VERSION.h | |
| 366 | + $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 367 | 367 | |
| 368 | 368 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 369 | 369 | |
| 370 | 370 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 371 | 371 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| @@ -970,14 +970,14 @@ | ||
| 970 | 970 | |
| 971 | 971 | zip.h: $(OBJDIR)/headers |
| 972 | 972 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 973 | 973 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 974 | 974 | |
| 975 | -$(OBJDIR)/shell.o: $(SRCDIR)/shell.c | |
| 975 | +$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h | |
| 976 | 976 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 977 | 977 | |
| 978 | 978 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 979 | 979 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 980 | 980 | |
| 981 | 981 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 982 | 982 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 983 | 983 | |
| 984 | 984 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -361,11 +361,11 @@ | |
| 361 | # the repository after running the tests. |
| 362 | test: $(APPNAME) |
| 363 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 364 | |
| 365 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 366 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest >$(OBJDIR)/VERSION.h |
| 367 | |
| 368 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 369 | |
| 370 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 371 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| @@ -970,14 +970,14 @@ | |
| 970 | |
| 971 | zip.h: $(OBJDIR)/headers |
| 972 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 973 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 974 | |
| 975 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c |
| 976 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 977 | |
| 978 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 979 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 980 | |
| 981 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 982 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 983 | |
| 984 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -361,11 +361,11 @@ | |
| 361 | # the repository after running the tests. |
| 362 | test: $(APPNAME) |
| 363 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 364 | |
| 365 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 366 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 367 | |
| 368 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 369 | |
| 370 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 371 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| @@ -970,14 +970,14 @@ | |
| 970 | |
| 971 | zip.h: $(OBJDIR)/headers |
| 972 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 973 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 974 | |
| 975 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h |
| 976 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 977 | |
| 978 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 979 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 980 | |
| 981 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 982 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 983 | |
| 984 |
+3
-3
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -31,11 +31,11 @@ | ||
| 31 | 31 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 32 | 32 | |
| 33 | 33 | CFLAGS = -nologo -MT -O2 |
| 34 | 34 | BCC = $(CC) $(CFLAGS) |
| 35 | 35 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 36 | -LIBS = $(ZLIB) ws2_32.lib $(SSLLIB) | |
| 36 | +LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) | |
| 37 | 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | 38 | |
| 39 | 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT2 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | 40 | |
| 41 | 41 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c 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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| @@ -153,11 +153,11 @@ | ||
| 153 | 153 | $(BCC) $** |
| 154 | 154 | |
| 155 | 155 | mkindex$E: $(SRCDIR)\mkindex.c |
| 156 | 156 | $(BCC) $** |
| 157 | 157 | |
| 158 | -version$E: $B\src\mkversion.c | |
| 158 | +mkversion$E: $B\src\mkversion.c | |
| 159 | 159 | $(BCC) $** |
| 160 | 160 | |
| 161 | 161 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 162 | 162 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 163 | 163 | |
| @@ -168,11 +168,11 @@ | ||
| 168 | 168 | $(TCC) /Fo$@ -c $** |
| 169 | 169 | |
| 170 | 170 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 171 | 171 | $(TCC) /Fo$@ -c $** |
| 172 | 172 | |
| 173 | -VERSION.h : version$E $B\manifest.uuid $B\manifest | |
| 173 | +VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 174 | 174 | $** > $@ |
| 175 | 175 | |
| 176 | 176 | page_index.h: mkindex$E $(SRC) |
| 177 | 177 | $** > $@ |
| 178 | 178 | |
| 179 | 179 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -31,11 +31,11 @@ | |
| 31 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 32 | |
| 33 | CFLAGS = -nologo -MT -O2 |
| 34 | BCC = $(CC) $(CFLAGS) |
| 35 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 36 | LIBS = $(ZLIB) ws2_32.lib $(SSLLIB) |
| 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | |
| 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT2 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | |
| 41 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c 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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| @@ -153,11 +153,11 @@ | |
| 153 | $(BCC) $** |
| 154 | |
| 155 | mkindex$E: $(SRCDIR)\mkindex.c |
| 156 | $(BCC) $** |
| 157 | |
| 158 | version$E: $B\src\mkversion.c |
| 159 | $(BCC) $** |
| 160 | |
| 161 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 162 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 163 | |
| @@ -168,11 +168,11 @@ | |
| 168 | $(TCC) /Fo$@ -c $** |
| 169 | |
| 170 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 171 | $(TCC) /Fo$@ -c $** |
| 172 | |
| 173 | VERSION.h : version$E $B\manifest.uuid $B\manifest |
| 174 | $** > $@ |
| 175 | |
| 176 | page_index.h: mkindex$E $(SRC) |
| 177 | $** > $@ |
| 178 | |
| 179 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -31,11 +31,11 @@ | |
| 31 | INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR) |
| 32 | |
| 33 | CFLAGS = -nologo -MT -O2 |
| 34 | BCC = $(CC) $(CFLAGS) |
| 35 | TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL) |
| 36 | LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) |
| 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | |
| 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT2 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | |
| 41 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c 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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| @@ -153,11 +153,11 @@ | |
| 153 | $(BCC) $** |
| 154 | |
| 155 | mkindex$E: $(SRCDIR)\mkindex.c |
| 156 | $(BCC) $** |
| 157 | |
| 158 | mkversion$E: $B\src\mkversion.c |
| 159 | $(BCC) $** |
| 160 | |
| 161 | $(OX)\shell$O : $(SRCDIR)\shell.c |
| 162 | $(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c |
| 163 | |
| @@ -168,11 +168,11 @@ | |
| 168 | $(TCC) /Fo$@ -c $** |
| 169 | |
| 170 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 171 | $(TCC) /Fo$@ -c $** |
| 172 | |
| 173 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 174 | $** > $@ |
| 175 | |
| 176 | page_index.h: mkindex$E $(SRC) |
| 177 | $** > $@ |
| 178 | |
| 179 |
+24
-15
| --- www/build.wiki | ||
| +++ www/build.wiki | ||
| @@ -33,42 +33,51 @@ | ||
| 33 | 33 | |
| 34 | 34 | <li><p>Select a version of of fossil you want to download. Click on its |
| 35 | 35 | link. Note that you must successfully log in as "anonymous" in step 1 |
| 36 | 36 | above in order to see the link to the detailed version information.</p></li> |
| 37 | 37 | |
| 38 | -<li><p>Finally, click on the | |
| 39 | -"Zip Archive" link. This link will build a ZIP archive of the | |
| 38 | +<li><p>Finally, click on one of the | |
| 39 | +"Zip Archive" or "Tarball" links, according to your preference. | |
| 40 | +These link will build a ZIP archive or a gzip-compressed tarball of the | |
| 40 | 41 | complete source code and download it to your browser. |
| 41 | 42 | </ol> |
| 42 | 43 | |
| 43 | 44 | <h2>2.0 Compiling</h2> |
| 44 | 45 | |
| 45 | -<p>Follow these steps to compile on a unix platform | |
| 46 | -(Linux, *BSD, MacOS, etc):</p> | |
| 47 | - | |
| 48 | 46 | <ol> |
| 49 | 47 | <li value="6"> |
| 50 | -<p>Create a directory to hold the source code. Then unzip the | |
| 51 | -ZIP archive you downloaded into that directory. You should be | |
| 48 | +<p>Create a directory to hold the source code. Then unarchive the | |
| 49 | +ZIP or tarball you downloaded into that directory. You should be | |
| 52 | 50 | in the top-level folder of that directory</p></li> |
| 53 | 51 | |
| 54 | 52 | <li><p><b>(Optional:)</b> |
| 55 | 53 | Edit the Makefile to set it up like you want. You probably do not |
| 56 | 54 | need to do anything. Do not be intimidated: There are less than 10 |
| 57 | 55 | variables in the makefile that can be changed. The whole Makefile |
| 58 | 56 | is only a few dozen lines long and most of those lines are comments.</p> |
| 59 | 57 | |
| 60 | -<li><p>Type "<b>make</b>" | |
| 58 | +<li><p>Run make to build the "fossil" or "fossil.exe" executable. The | |
| 59 | +details depend on your platform and compiler: | |
| 60 | + | |
| 61 | +<ol type="a"> | |
| 62 | +<li><p><i>Unix</i> → the default Makefile works on most unix and | |
| 63 | +unix-like systems. Simply type "<b>make</b>". | |
| 64 | + | |
| 65 | +<li><p><i>Msys/MinGW</i> → Use the | |
| 66 | +mingw makefile: "<b>make -f win/Makefile.mingw</b>" | |
| 67 | + | |
| 68 | +<li><p><i>VC++</i> → Use the msc makefile. First | |
| 69 | +change to the "win/" subdirectory ("<b>cd win</b>") then run | |
| 70 | +"<b>nmake /f Makefile.msc</b>". | |
| 71 | +</ol> | |
| 61 | 72 | </ol> |
| 62 | 73 | |
| 63 | -<p>To build on windows, use an alternative makefile suitable for your | |
| 64 | -particular build environment. The alternative windows makefiles are | |
| 65 | -all found in the win/ subdirectory of the source tree. So, for example, | |
| 66 | -if you want build using the | |
| 67 | -[http://www.mingw.org/ | mingw/msys compiler package] for windows, then | |
| 68 | -run "<b>make -f win/Makefile.mingw</b>" instead of just "<b>make</b>" | |
| 69 | -in step 8 above.</p> | |
| 74 | +<p>Note that Fossil requires the "zlib" compression library. This library | |
| 75 | +is available by default on most unix systems, but it will typically have to | |
| 76 | +be installed separately on windows systems. For windows builds, you may | |
| 77 | +need to edit the makefile to tell it exactly where zlib is located on your | |
| 78 | +system.</p> | |
| 70 | 79 | |
| 71 | 80 | <h2>3.0 Installing</h2> |
| 72 | 81 | |
| 73 | 82 | <ol> |
| 74 | 83 | <li value="9"> |
| 75 | 84 | |
| 76 | 85 | ADDED www/changes.wiki |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -33,42 +33,51 @@ | |
| 33 | |
| 34 | <li><p>Select a version of of fossil you want to download. Click on its |
| 35 | link. Note that you must successfully log in as "anonymous" in step 1 |
| 36 | above in order to see the link to the detailed version information.</p></li> |
| 37 | |
| 38 | <li><p>Finally, click on the |
| 39 | "Zip Archive" link. This link will build a ZIP archive of the |
| 40 | complete source code and download it to your browser. |
| 41 | </ol> |
| 42 | |
| 43 | <h2>2.0 Compiling</h2> |
| 44 | |
| 45 | <p>Follow these steps to compile on a unix platform |
| 46 | (Linux, *BSD, MacOS, etc):</p> |
| 47 | |
| 48 | <ol> |
| 49 | <li value="6"> |
| 50 | <p>Create a directory to hold the source code. Then unzip the |
| 51 | ZIP archive you downloaded into that directory. You should be |
| 52 | in the top-level folder of that directory</p></li> |
| 53 | |
| 54 | <li><p><b>(Optional:)</b> |
| 55 | Edit the Makefile to set it up like you want. You probably do not |
| 56 | need to do anything. Do not be intimidated: There are less than 10 |
| 57 | variables in the makefile that can be changed. The whole Makefile |
| 58 | is only a few dozen lines long and most of those lines are comments.</p> |
| 59 | |
| 60 | <li><p>Type "<b>make</b>" |
| 61 | </ol> |
| 62 | |
| 63 | <p>To build on windows, use an alternative makefile suitable for your |
| 64 | particular build environment. The alternative windows makefiles are |
| 65 | all found in the win/ subdirectory of the source tree. So, for example, |
| 66 | if you want build using the |
| 67 | [http://www.mingw.org/ | mingw/msys compiler package] for windows, then |
| 68 | run "<b>make -f win/Makefile.mingw</b>" instead of just "<b>make</b>" |
| 69 | in step 8 above.</p> |
| 70 | |
| 71 | <h2>3.0 Installing</h2> |
| 72 | |
| 73 | <ol> |
| 74 | <li value="9"> |
| 75 | |
| 76 | DDED www/changes.wiki |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -33,42 +33,51 @@ | |
| 33 | |
| 34 | <li><p>Select a version of of fossil you want to download. Click on its |
| 35 | link. Note that you must successfully log in as "anonymous" in step 1 |
| 36 | above in order to see the link to the detailed version information.</p></li> |
| 37 | |
| 38 | <li><p>Finally, click on one of the |
| 39 | "Zip Archive" or "Tarball" links, according to your preference. |
| 40 | These link will build a ZIP archive or a gzip-compressed tarball of the |
| 41 | complete source code and download it to your browser. |
| 42 | </ol> |
| 43 | |
| 44 | <h2>2.0 Compiling</h2> |
| 45 | |
| 46 | <ol> |
| 47 | <li value="6"> |
| 48 | <p>Create a directory to hold the source code. Then unarchive the |
| 49 | ZIP or tarball you downloaded into that directory. You should be |
| 50 | in the top-level folder of that directory</p></li> |
| 51 | |
| 52 | <li><p><b>(Optional:)</b> |
| 53 | Edit the Makefile to set it up like you want. You probably do not |
| 54 | need to do anything. Do not be intimidated: There are less than 10 |
| 55 | variables in the makefile that can be changed. The whole Makefile |
| 56 | is only a few dozen lines long and most of those lines are comments.</p> |
| 57 | |
| 58 | <li><p>Run make to build the "fossil" or "fossil.exe" executable. The |
| 59 | details depend on your platform and compiler: |
| 60 | |
| 61 | <ol type="a"> |
| 62 | <li><p><i>Unix</i> → the default Makefile works on most unix and |
| 63 | unix-like systems. Simply type "<b>make</b>". |
| 64 | |
| 65 | <li><p><i>Msys/MinGW</i> → Use the |
| 66 | mingw makefile: "<b>make -f win/Makefile.mingw</b>" |
| 67 | |
| 68 | <li><p><i>VC++</i> → Use the msc makefile. First |
| 69 | change to the "win/" subdirectory ("<b>cd win</b>") then run |
| 70 | "<b>nmake /f Makefile.msc</b>". |
| 71 | </ol> |
| 72 | </ol> |
| 73 | |
| 74 | <p>Note that Fossil requires the "zlib" compression library. This library |
| 75 | is available by default on most unix systems, but it will typically have to |
| 76 | be installed separately on windows systems. For windows builds, you may |
| 77 | need to edit the makefile to tell it exactly where zlib is located on your |
| 78 | system.</p> |
| 79 | |
| 80 | <h2>3.0 Installing</h2> |
| 81 | |
| 82 | <ol> |
| 83 | <li value="9"> |
| 84 | |
| 85 | DDED www/changes.wiki |
+3
| --- a/www/changes.wiki | ||
| +++ b/www/changes.wiki | ||
| @@ -0,0 +1,3 @@ | ||
| 1 | +2-xxVarious minor bug fixependingAdded and options for status, | |
| 2 | + to optionally show pathnames | |
| 3 | + |
| --- a/www/changes.wiki | |
| +++ b/www/changes.wiki | |
| @@ -0,0 +1,3 @@ | |
| --- a/www/changes.wiki | |
| +++ b/www/changes.wiki | |
| @@ -0,0 +1,3 @@ | |
| 1 | 2-xxVarious minor bug fixependingAdded and options for status, |
| 2 | to optionally show pathnames |
| 3 |
+73
-16
| --- www/checkin.wiki | ||
| +++ www/checkin.wiki | ||
| @@ -1,21 +1,78 @@ | ||
| 1 | -<title>Checkin Checklist</title> | |
| 1 | +<title>Check-in Checklist</title> | |
| 2 | + | |
| 3 | +<h2><u>Always</u> run the following checklist prior to <u>every</u> | |
| 4 | +check-in or commit to the Fossil repository:</h2> | |
| 2 | 5 | |
| 3 | -Before every checkins: | |
| 6 | +Before every check-in: | |
| 4 | 7 | |
| 5 | - 1. <b>fossil diff</b> → no stray changes | |
| 8 | + 1. <b>fossil diff</b> → | |
| 9 | + <ol type="a"> | |
| 10 | + <li> No stray changes | |
| 11 | + <li> All changes comply with the license | |
| 12 | + <li> All inputs are scrubbed before use | |
| 13 | + <li> No injection attacks via %s formats | |
| 14 | + </ol> | |
| 6 | 15 | |
| 7 | 16 | 2. <b>fossil extra</b> → no unmanaged files need to be added. |
| 8 | 17 | |
| 9 | - 3. The checkin will go onto the desired branch. | |
| 10 | - | |
| 11 | - 4. "Autosync" is enabled → | |
| 12 | - <ol> | |
| 13 | - <li> The checkin will not cause a unintentional fork. | |
| 14 | - <li> The local system clock is set correctly. | |
| 15 | - </ol> | |
| 16 | - | |
| 17 | -Before every checkin to <b>trunk</b>: | |
| 18 | - | |
| 19 | - 5. No compiler warnings on the development machine. | |
| 20 | - | |
| 21 | - 6. Changes will not cause problems on a future <b>bisect</b>. | |
| 18 | + 3. The check-in will go onto the desired branch. | |
| 19 | + → Do <u>not</u> check into trunk without prior approval from | |
| 20 | + the lead programmer (drh)! | |
| 21 | + | |
| 22 | + 4. auto-sync is on, or the system clock is verified | |
| 23 | + | |
| 24 | + 5. If sources files have been added or removed, ensure all makefiles | |
| 25 | + and configure scripts have been updated accordingly. | |
| 26 | + | |
| 27 | +Before every check-in to <b>trunk</b>: | |
| 28 | + | |
| 29 | + 6. No compiler warnings on the development machine. | |
| 30 | + | |
| 31 | + 7. The fossil executable that results from a build actually works. | |
| 32 | + | |
| 33 | + | |
| 34 | +<hr> | |
| 35 | +<h2>Commentary</h2> | |
| 36 | + | |
| 37 | +Item 1 is the most important step. Consider using <b>gdiff</b> | |
| 38 | +instead of <b>diff</b> if you have a graphical differ configured. Or, | |
| 39 | +pipe the output of "<b>fossil diff</b>" into "<b>open -f</b>" (on a mac) to | |
| 40 | +get the diff output in a separate text window for easier viewing. | |
| 41 | +Look carefully at every changed line in item 1. | |
| 42 | +Make sure that you are not about to commit unrelated changes. | |
| 43 | +If there are two or more unrelated changes present, consider | |
| 44 | +breaking up the commit into two or more separate commits. | |
| 45 | +Always make 100% sure that all changes are compatible with the | |
| 46 | +BSD license, that you have the authority to commit the code in accordance | |
| 47 | +with the [/doc/trunk/www/copyright-release.html | CLA] that you have | |
| 48 | +signed and have on file, and that | |
| 49 | +no NDAs, copyrights, patents, or trademarks are infringed by the check-in. | |
| 50 | +Also check very carefully to make sure that | |
| 51 | +you are not introducing security vulnerabilities. Pay particular attention | |
| 52 | +to the possibility of SQL or HTML injection attacks. | |
| 53 | + | |
| 54 | +Item 2 verifies that you have not added source files but failed to | |
| 55 | +do the necessary "<b>fossil add</b>" to manage them. If you commit | |
| 56 | +without bringing the new file under source control, the check-in will | |
| 57 | +be broken. That, in turn, can cause complications far in the future | |
| 58 | +when we are bisecting for a bug. | |
| 59 | + | |
| 60 | +For item 3, Run "<b>fossil status</b>" or the equivalent to | |
| 61 | +make sure your changes are going into the branch you think they are. | |
| 62 | +Also double-check the branch name when entering change comments. | |
| 63 | +Never check into trunk unless you are expressly authorized to do so. | |
| 64 | + | |
| 65 | +For Item 4, if you are on-network, make sure auto-sync is enabled. This | |
| 66 | +will minimize the risk of an unintended fork. It will also give you a | |
| 67 | +warning if you system clock is set incorrectly. If you are off-network, | |
| 68 | +make sure that your system clock is correct or at least close to correct | |
| 69 | +so that your check-in does not appear out-of-sequence on timelines. | |
| 70 | +On-network commits are preferred, especially for trunk commits. | |
| 71 | + | |
| 72 | +Items 6 and 7 help to ensure that check-ins on the trunk always work. | |
| 73 | +Knowing that the trunk always works makes bisecting much easier. Items | |
| 74 | +6 and 7 are recommended for all check-ins, even those that are on a branch. | |
| 75 | +But they are especially important for trunk check-ins. We desire that | |
| 76 | +all trunk check-ins work at all times. Any experimental, unstable, or | |
| 77 | +questionable changes should go on a branch and be merged into trunk after | |
| 78 | +further testing. | |
| 22 | 79 | |
| 23 | 80 | ADDED www/foss-cklist.wiki |
| --- www/checkin.wiki | |
| +++ www/checkin.wiki | |
| @@ -1,21 +1,78 @@ | |
| 1 | <title>Checkin Checklist</title> |
| 2 | |
| 3 | Before every checkins: |
| 4 | |
| 5 | 1. <b>fossil diff</b> → no stray changes |
| 6 | |
| 7 | 2. <b>fossil extra</b> → no unmanaged files need to be added. |
| 8 | |
| 9 | 3. The checkin will go onto the desired branch. |
| 10 | |
| 11 | 4. "Autosync" is enabled → |
| 12 | <ol> |
| 13 | <li> The checkin will not cause a unintentional fork. |
| 14 | <li> The local system clock is set correctly. |
| 15 | </ol> |
| 16 | |
| 17 | Before every checkin to <b>trunk</b>: |
| 18 | |
| 19 | 5. No compiler warnings on the development machine. |
| 20 | |
| 21 | 6. Changes will not cause problems on a future <b>bisect</b>. |
| 22 | |
| 23 | DDED www/foss-cklist.wiki |
| --- www/checkin.wiki | |
| +++ www/checkin.wiki | |
| @@ -1,21 +1,78 @@ | |
| 1 | <title>Check-in Checklist</title> |
| 2 | |
| 3 | <h2><u>Always</u> run the following checklist prior to <u>every</u> |
| 4 | check-in or commit to the Fossil repository:</h2> |
| 5 | |
| 6 | Before every check-in: |
| 7 | |
| 8 | 1. <b>fossil diff</b> → |
| 9 | <ol type="a"> |
| 10 | <li> No stray changes |
| 11 | <li> All changes comply with the license |
| 12 | <li> All inputs are scrubbed before use |
| 13 | <li> No injection attacks via %s formats |
| 14 | </ol> |
| 15 | |
| 16 | 2. <b>fossil extra</b> → no unmanaged files need to be added. |
| 17 | |
| 18 | 3. The check-in will go onto the desired branch. |
| 19 | → Do <u>not</u> check into trunk without prior approval from |
| 20 | the lead programmer (drh)! |
| 21 | |
| 22 | 4. auto-sync is on, or the system clock is verified |
| 23 | |
| 24 | 5. If sources files have been added or removed, ensure all makefiles |
| 25 | and configure scripts have been updated accordingly. |
| 26 | |
| 27 | Before every check-in to <b>trunk</b>: |
| 28 | |
| 29 | 6. No compiler warnings on the development machine. |
| 30 | |
| 31 | 7. The fossil executable that results from a build actually works. |
| 32 | |
| 33 | |
| 34 | <hr> |
| 35 | <h2>Commentary</h2> |
| 36 | |
| 37 | Item 1 is the most important step. Consider using <b>gdiff</b> |
| 38 | instead of <b>diff</b> if you have a graphical differ configured. Or, |
| 39 | pipe the output of "<b>fossil diff</b>" into "<b>open -f</b>" (on a mac) to |
| 40 | get the diff output in a separate text window for easier viewing. |
| 41 | Look carefully at every changed line in item 1. |
| 42 | Make sure that you are not about to commit unrelated changes. |
| 43 | If there are two or more unrelated changes present, consider |
| 44 | breaking up the commit into two or more separate commits. |
| 45 | Always make 100% sure that all changes are compatible with the |
| 46 | BSD license, that you have the authority to commit the code in accordance |
| 47 | with the [/doc/trunk/www/copyright-release.html | CLA] that you have |
| 48 | signed and have on file, and that |
| 49 | no NDAs, copyrights, patents, or trademarks are infringed by the check-in. |
| 50 | Also check very carefully to make sure that |
| 51 | you are not introducing security vulnerabilities. Pay particular attention |
| 52 | to the possibility of SQL or HTML injection attacks. |
| 53 | |
| 54 | Item 2 verifies that you have not added source files but failed to |
| 55 | do the necessary "<b>fossil add</b>" to manage them. If you commit |
| 56 | without bringing the new file under source control, the check-in will |
| 57 | be broken. That, in turn, can cause complications far in the future |
| 58 | when we are bisecting for a bug. |
| 59 | |
| 60 | For item 3, Run "<b>fossil status</b>" or the equivalent to |
| 61 | make sure your changes are going into the branch you think they are. |
| 62 | Also double-check the branch name when entering change comments. |
| 63 | Never check into trunk unless you are expressly authorized to do so. |
| 64 | |
| 65 | For Item 4, if you are on-network, make sure auto-sync is enabled. This |
| 66 | will minimize the risk of an unintended fork. It will also give you a |
| 67 | warning if you system clock is set incorrectly. If you are off-network, |
| 68 | make sure that your system clock is correct or at least close to correct |
| 69 | so that your check-in does not appear out-of-sequence on timelines. |
| 70 | On-network commits are preferred, especially for trunk commits. |
| 71 | |
| 72 | Items 6 and 7 help to ensure that check-ins on the trunk always work. |
| 73 | Knowing that the trunk always works makes bisecting much easier. Items |
| 74 | 6 and 7 are recommended for all check-ins, even those that are on a branch. |
| 75 | But they are especially important for trunk check-ins. We desire that |
| 76 | all trunk check-ins work at all times. Any experimental, unstable, or |
| 77 | questionable changes should go on a branch and be merged into trunk after |
| 78 | further testing. |
| 79 | |
| 80 | DDED www/foss-cklist.wiki |
+60
| --- a/www/foss-cklist.wiki | ||
| +++ b/www/foss-cklist.wiki | ||
| @@ -0,0 +1,60 @@ | ||
| 1 | +<title>Checklist For Successful Open-Source Projects</title> | |
| 2 | +<nowiki> | |
| 3 | + | |
| 4 | +<p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score | |
| 5 | +blog post <a href="http://spot.livejournal.com/308370.html"> | |
| 6 | +http://spot.livejournal.com/308370.html</a> (see also | |
| 7 | +<a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and | |
| 8 | +<a href="https://wwwHow_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a>). | |
| 9 | +Tom's original post assigned point scores to the various elements and | |
| 10 | +by adding together the individual points, the reader is suposed to be able | |
| 11 | +to judge the likelihood that the project will fail. | |
| 12 | +The point scores, and the items on the list, clearly reflect Tom's | |
| 13 | +biases and are not necessarily those of the larger open-source community. | |
| 14 | +Nevertheless, the policy of the Fossil shall be to strive for a perfect | |
| 15 | +score.</p> | |
| 16 | + | |
| 17 | +<p>rive for a perfect | |
| 18 | +score. | |
| 19 | + | |
| 20 | +This checklist is an inversion of Tom's original post in that it strives to | |
| 21 | +say what the project should do in order to succeed rather than what it | |
| 22 | +should not do to avoid failure. Th</p> | |
| 23 | + | |
| 24 | +<p>point values are omitted. | |
| 25 | + | |
| 26 | +See also: | |
| 27 | +<ul> | |
| 28 | +<li><a href="http://offog.org/articles/packaging/"> | |
| 29 | +http://offog.org/articles/packaging/</a> | |
| 30 | +<li> | |
| 31 | +<a href="http://www.gnu.org/prep/standards/standards.html#Managing-Releases"> | |
| 32 | +http://www.gnu.org/prep/standards/standards.html#Managing-Releases<p>The source code size is less than <p>The project uses a Version Control System (VCS). | |
| 33 | +<ol type="a"> | |
| 34 | +<li>The VCS has a working web interface. | |
| 35 | +<li>There is documentation on how to use the VCS. | |
| 36 | +<li>The VCS is general-purpose, not something hacked together for this | |
| 37 | + <p>The project comes with documentation on how to build from source | |
| 38 | +and that documentation is lucid, correct, and up-to-date. | |
| 39 | + | |
| 40 | +<li><p>The project is configurable using an autoconf-generated configure | |
| 41 | +script, or the equivalent, and does not require: | |
| 42 | +<ol type="a"> | |
| 43 | +<li>Manually editing flat files | |
| 44 | +<li>Editing code header files | |
| 45 | +</ol> | |
| 46 | + | |
| 47 | +<li><pes a Version les | |
| 48 | +</ol> | |
| 49 | + | |
| 50 | +<li>The project should be buildable using commonly available and | |
| 51 | + standa<p Open-Source Projects</title> | |
| 52 | +<nowiki> | |
| 53 | + | |
| 54 | +This checklist is loosely derive<t>The project is configurable using an autoconf-generated configure | |
| 55 | +script, or the equivalent, and does not requir essful Open-Source Projects</title> | |
| 56 | +<nowiki> | |
| 57 | + | |
| 58 | +<p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score | |
| 59 | +blog post <a href="http://spot.livejournal.com/308370.html"> | |
| 60 | +http://sp |
| --- a/www/foss-cklist.wiki | |
| +++ b/www/foss-cklist.wiki | |
| @@ -0,0 +1,60 @@ | |
| --- a/www/foss-cklist.wiki | |
| +++ b/www/foss-cklist.wiki | |
| @@ -0,0 +1,60 @@ | |
| 1 | <title>Checklist For Successful Open-Source Projects</title> |
| 2 | <nowiki> |
| 3 | |
| 4 | <p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score |
| 5 | blog post <a href="http://spot.livejournal.com/308370.html"> |
| 6 | http://spot.livejournal.com/308370.html</a> (see also |
| 7 | <a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and |
| 8 | <a href="https://wwwHow_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a>). |
| 9 | Tom's original post assigned point scores to the various elements and |
| 10 | by adding together the individual points, the reader is suposed to be able |
| 11 | to judge the likelihood that the project will fail. |
| 12 | The point scores, and the items on the list, clearly reflect Tom's |
| 13 | biases and are not necessarily those of the larger open-source community. |
| 14 | Nevertheless, the policy of the Fossil shall be to strive for a perfect |
| 15 | score.</p> |
| 16 | |
| 17 | <p>rive for a perfect |
| 18 | score. |
| 19 | |
| 20 | This checklist is an inversion of Tom's original post in that it strives to |
| 21 | say what the project should do in order to succeed rather than what it |
| 22 | should not do to avoid failure. Th</p> |
| 23 | |
| 24 | <p>point values are omitted. |
| 25 | |
| 26 | See also: |
| 27 | <ul> |
| 28 | <li><a href="http://offog.org/articles/packaging/"> |
| 29 | http://offog.org/articles/packaging/</a> |
| 30 | <li> |
| 31 | <a href="http://www.gnu.org/prep/standards/standards.html#Managing-Releases"> |
| 32 | http://www.gnu.org/prep/standards/standards.html#Managing-Releases<p>The source code size is less than <p>The project uses a Version Control System (VCS). |
| 33 | <ol type="a"> |
| 34 | <li>The VCS has a working web interface. |
| 35 | <li>There is documentation on how to use the VCS. |
| 36 | <li>The VCS is general-purpose, not something hacked together for this |
| 37 | <p>The project comes with documentation on how to build from source |
| 38 | and that documentation is lucid, correct, and up-to-date. |
| 39 | |
| 40 | <li><p>The project is configurable using an autoconf-generated configure |
| 41 | script, or the equivalent, and does not require: |
| 42 | <ol type="a"> |
| 43 | <li>Manually editing flat files |
| 44 | <li>Editing code header files |
| 45 | </ol> |
| 46 | |
| 47 | <li><pes a Version les |
| 48 | </ol> |
| 49 | |
| 50 | <li>The project should be buildable using commonly available and |
| 51 | standa<p Open-Source Projects</title> |
| 52 | <nowiki> |
| 53 | |
| 54 | This checklist is loosely derive<t>The project is configurable using an autoconf-generated configure |
| 55 | script, or the equivalent, and does not requir essful Open-Source Projects</title> |
| 56 | <nowiki> |
| 57 | |
| 58 | <p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score |
| 59 | blog post <a href="http://spot.livejournal.com/308370.html"> |
| 60 | http://sp |
+2
| --- www/index.wiki | ||
| +++ www/index.wiki | ||
| @@ -20,10 +20,12 @@ | ||
| 20 | 20 | <li> [./quickstart.wiki | Quick Start] |
| 21 | 21 | <li> [./build.wiki | Install] |
| 22 | 22 | <li> [../COPYRIGHT-BSD2.txt | License] |
| 23 | 23 | <li> [/timeline | Recent changes] |
| 24 | 24 | <li> [./faq.wiki | FAQ] |
| 25 | +<li> [./contribute.wiki | Contributing] | |
| 26 | +<li> [./changes.wiki | Change Log] | |
| 25 | 27 | <li> [./permutedindex.wiki | Doc Index] |
| 26 | 28 | <li> Mailing list |
| 27 | 29 | <ul> |
| 28 | 30 | <li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up] |
| 29 | 31 | <li> [http://www.mail-archive.com/[email protected] | archives] |
| 30 | 32 |
| --- www/index.wiki | |
| +++ www/index.wiki | |
| @@ -20,10 +20,12 @@ | |
| 20 | <li> [./quickstart.wiki | Quick Start] |
| 21 | <li> [./build.wiki | Install] |
| 22 | <li> [../COPYRIGHT-BSD2.txt | License] |
| 23 | <li> [/timeline | Recent changes] |
| 24 | <li> [./faq.wiki | FAQ] |
| 25 | <li> [./permutedindex.wiki | Doc Index] |
| 26 | <li> Mailing list |
| 27 | <ul> |
| 28 | <li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up] |
| 29 | <li> [http://www.mail-archive.com/[email protected] | archives] |
| 30 |
| --- www/index.wiki | |
| +++ www/index.wiki | |
| @@ -20,10 +20,12 @@ | |
| 20 | <li> [./quickstart.wiki | Quick Start] |
| 21 | <li> [./build.wiki | Install] |
| 22 | <li> [../COPYRIGHT-BSD2.txt | License] |
| 23 | <li> [/timeline | Recent changes] |
| 24 | <li> [./faq.wiki | FAQ] |
| 25 | <li> [./contribute.wiki | Contributing] |
| 26 | <li> [./changes.wiki | Change Log] |
| 27 | <li> [./permutedindex.wiki | Doc Index] |
| 28 | <li> Mailing list |
| 29 | <ul> |
| 30 | <li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up] |
| 31 | <li> [http://www.mail-archive.com/[email protected] | archives] |
| 32 |
+20
-14
| --- www/makefile.wiki | ||
| +++ www/makefile.wiki | ||
| @@ -52,29 +52,34 @@ | ||
| 52 | 52 | 7. th.c |
| 53 | 53 | 8. th.h |
| 54 | 54 | |
| 55 | 55 | These two files are imports like the SQLite source files, |
| 56 | 56 | and so are not preprocessed. |
| 57 | + | |
| 58 | +The VERSION.h header file is generated from other information sources | |
| 59 | +using a small program called: | |
| 60 | + | |
| 61 | + 9. mkversion.c | |
| 57 | 62 | |
| 58 | 63 | The src/ subdirectory also contains documentation about the |
| 59 | 64 | makeheaders preprocessor program: |
| 60 | 65 | |
| 61 | - 9. [../src/makeheaders.html | makeheaders.html] | |
| 66 | + 10. [../src/makeheaders.html | makeheaders.html] | |
| 62 | 67 | |
| 63 | 68 | Click on the link to read this documentation. In addition there is |
| 64 | 69 | a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles: |
| 65 | 70 | |
| 66 | - 10. makemake.tcl | |
| 71 | + 11. makemake.tcl | |
| 67 | 72 | |
| 68 | 73 | Running this Tcl script will automatically regenerate all makefiles. |
| 69 | 74 | In order to add a new source file to the Fossil implementation, simply |
| 70 | 75 | edit makemake.tcl to add the new filename, then rerun the script, and |
| 71 | 76 | all of the makefiles for all targets will be rebuild. |
| 72 | 77 | |
| 73 | 78 | Finally, there is one of the makefiles generated by makemake.tcl: |
| 74 | 79 | |
| 75 | - 11. main.mk | |
| 80 | + 12. main.mk | |
| 76 | 81 | |
| 77 | 82 | The main.mk makefile is invoked from the Makefile in the top-level |
| 78 | 83 | directory. The main.mk is generated by makemake.tcl and should not |
| 79 | 84 | be hand edited. Other makefiles generated by makemake.tcl are in |
| 80 | 85 | other subdirectories (currently all in the win/ subdirectory). |
| @@ -89,31 +94,32 @@ | ||
| 89 | 94 | |
| 90 | 95 | <h1>3.0 Automatically generated files</h1> |
| 91 | 96 | |
| 92 | 97 | The "VERSION.h" header file contains some C preprocessor macros that |
| 93 | 98 | identify the version of Fossil that is to be build. The VERSION.h file is |
| 94 | -generated automatically from information extracted from the "manifest" | |
| 95 | -and "manifest.uuid" source files in the root directory of the source tree. | |
| 99 | +generated automatically from information extracted from the "manifest", | |
| 100 | +"manifest.uuid", and "VERSION" source files in the root directory of the | |
| 101 | +source tree. | |
| 96 | 102 | (The "manifest" and "manifest.uuid" files are automatically generated and |
| 97 | 103 | updated by Fossil itself. See the [/help/setting | fossil set manifest] |
| 98 | 104 | command for additional information.) |
| 99 | 105 | |
| 100 | -Under unix, there is an AWK script that converts manifest and manifest.uuid | |
| 101 | -into VERSION.h. For windows, there is a C program: win/version.c. | |
| 102 | -(Unix builds could also used the version.c convert, if desired, but AWK | |
| 103 | -seems easier there.) To run the VERSION.h generator, first compile | |
| 104 | -the win/version.c source file into a command-line program (named "version.exe") | |
| 106 | +The VERSION.h header file is generated by | |
| 107 | +a C program: src/mkversion.c. | |
| 108 | +To run the VERSION.h generator, first compile the src/mkversion.c | |
| 109 | + source file into a command-line program (named "mkversion.exe") | |
| 105 | 110 | than run: |
| 106 | 111 | |
| 107 | 112 | <blockquote><pre> |
| 108 | -version.exe manifest.uuid manifest VERSION.h | |
| 113 | +mkversion.exe manifest.uuid manifest VERSION >VERSION.h | |
| 109 | 114 | </pre></blockquote> |
| 110 | 115 | |
| 111 | 116 | The pathnames in the above command might need to be adjusted to get the |
| 112 | -directories right. The point is that the manifest.uuid and manifest files | |
| 113 | -in the root of the source tree are the first two arguments and the name of | |
| 114 | -the generated VERSION.h file is the third and final argument. | |
| 117 | +directories right. The point is that the manifest.uuid, manifest, and | |
| 118 | +VERSION files | |
| 119 | +in the root of the source tree are the three arguments and | |
| 120 | +the generated VERSION.h file appears on standard output. | |
| 115 | 121 | |
| 116 | 122 | <h1>4.0 Preprocessing</h1> |
| 117 | 123 | |
| 118 | 124 | There are three preprocessors for the Fossil sources. The mkindex |
| 119 | 125 | and translate preprocessors can be run in any order. The makeheaders |
| 120 | 126 |
| --- www/makefile.wiki | |
| +++ www/makefile.wiki | |
| @@ -52,29 +52,34 @@ | |
| 52 | 7. th.c |
| 53 | 8. th.h |
| 54 | |
| 55 | These two files are imports like the SQLite source files, |
| 56 | and so are not preprocessed. |
| 57 | |
| 58 | The src/ subdirectory also contains documentation about the |
| 59 | makeheaders preprocessor program: |
| 60 | |
| 61 | 9. [../src/makeheaders.html | makeheaders.html] |
| 62 | |
| 63 | Click on the link to read this documentation. In addition there is |
| 64 | a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles: |
| 65 | |
| 66 | 10. makemake.tcl |
| 67 | |
| 68 | Running this Tcl script will automatically regenerate all makefiles. |
| 69 | In order to add a new source file to the Fossil implementation, simply |
| 70 | edit makemake.tcl to add the new filename, then rerun the script, and |
| 71 | all of the makefiles for all targets will be rebuild. |
| 72 | |
| 73 | Finally, there is one of the makefiles generated by makemake.tcl: |
| 74 | |
| 75 | 11. main.mk |
| 76 | |
| 77 | The main.mk makefile is invoked from the Makefile in the top-level |
| 78 | directory. The main.mk is generated by makemake.tcl and should not |
| 79 | be hand edited. Other makefiles generated by makemake.tcl are in |
| 80 | other subdirectories (currently all in the win/ subdirectory). |
| @@ -89,31 +94,32 @@ | |
| 89 | |
| 90 | <h1>3.0 Automatically generated files</h1> |
| 91 | |
| 92 | The "VERSION.h" header file contains some C preprocessor macros that |
| 93 | identify the version of Fossil that is to be build. The VERSION.h file is |
| 94 | generated automatically from information extracted from the "manifest" |
| 95 | and "manifest.uuid" source files in the root directory of the source tree. |
| 96 | (The "manifest" and "manifest.uuid" files are automatically generated and |
| 97 | updated by Fossil itself. See the [/help/setting | fossil set manifest] |
| 98 | command for additional information.) |
| 99 | |
| 100 | Under unix, there is an AWK script that converts manifest and manifest.uuid |
| 101 | into VERSION.h. For windows, there is a C program: win/version.c. |
| 102 | (Unix builds could also used the version.c convert, if desired, but AWK |
| 103 | seems easier there.) To run the VERSION.h generator, first compile |
| 104 | the win/version.c source file into a command-line program (named "version.exe") |
| 105 | than run: |
| 106 | |
| 107 | <blockquote><pre> |
| 108 | version.exe manifest.uuid manifest VERSION.h |
| 109 | </pre></blockquote> |
| 110 | |
| 111 | The pathnames in the above command might need to be adjusted to get the |
| 112 | directories right. The point is that the manifest.uuid and manifest files |
| 113 | in the root of the source tree are the first two arguments and the name of |
| 114 | the generated VERSION.h file is the third and final argument. |
| 115 | |
| 116 | <h1>4.0 Preprocessing</h1> |
| 117 | |
| 118 | There are three preprocessors for the Fossil sources. The mkindex |
| 119 | and translate preprocessors can be run in any order. The makeheaders |
| 120 |
| --- www/makefile.wiki | |
| +++ www/makefile.wiki | |
| @@ -52,29 +52,34 @@ | |
| 52 | 7. th.c |
| 53 | 8. th.h |
| 54 | |
| 55 | These two files are imports like the SQLite source files, |
| 56 | and so are not preprocessed. |
| 57 | |
| 58 | The VERSION.h header file is generated from other information sources |
| 59 | using a small program called: |
| 60 | |
| 61 | 9. mkversion.c |
| 62 | |
| 63 | The src/ subdirectory also contains documentation about the |
| 64 | makeheaders preprocessor program: |
| 65 | |
| 66 | 10. [../src/makeheaders.html | makeheaders.html] |
| 67 | |
| 68 | Click on the link to read this documentation. In addition there is |
| 69 | a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles: |
| 70 | |
| 71 | 11. makemake.tcl |
| 72 | |
| 73 | Running this Tcl script will automatically regenerate all makefiles. |
| 74 | In order to add a new source file to the Fossil implementation, simply |
| 75 | edit makemake.tcl to add the new filename, then rerun the script, and |
| 76 | all of the makefiles for all targets will be rebuild. |
| 77 | |
| 78 | Finally, there is one of the makefiles generated by makemake.tcl: |
| 79 | |
| 80 | 12. main.mk |
| 81 | |
| 82 | The main.mk makefile is invoked from the Makefile in the top-level |
| 83 | directory. The main.mk is generated by makemake.tcl and should not |
| 84 | be hand edited. Other makefiles generated by makemake.tcl are in |
| 85 | other subdirectories (currently all in the win/ subdirectory). |
| @@ -89,31 +94,32 @@ | |
| 94 | |
| 95 | <h1>3.0 Automatically generated files</h1> |
| 96 | |
| 97 | The "VERSION.h" header file contains some C preprocessor macros that |
| 98 | identify the version of Fossil that is to be build. The VERSION.h file is |
| 99 | generated automatically from information extracted from the "manifest", |
| 100 | "manifest.uuid", and "VERSION" source files in the root directory of the |
| 101 | source tree. |
| 102 | (The "manifest" and "manifest.uuid" files are automatically generated and |
| 103 | updated by Fossil itself. See the [/help/setting | fossil set manifest] |
| 104 | command for additional information.) |
| 105 | |
| 106 | The VERSION.h header file is generated by |
| 107 | a C program: src/mkversion.c. |
| 108 | To run the VERSION.h generator, first compile the src/mkversion.c |
| 109 | source file into a command-line program (named "mkversion.exe") |
| 110 | than run: |
| 111 | |
| 112 | <blockquote><pre> |
| 113 | mkversion.exe manifest.uuid manifest VERSION >VERSION.h |
| 114 | </pre></blockquote> |
| 115 | |
| 116 | The pathnames in the above command might need to be adjusted to get the |
| 117 | directories right. The point is that the manifest.uuid, manifest, and |
| 118 | VERSION files |
| 119 | in the root of the source tree are the three arguments and |
| 120 | the generated VERSION.h file appears on standard output. |
| 121 | |
| 122 | <h1>4.0 Preprocessing</h1> |
| 123 | |
| 124 | There are three preprocessors for the Fossil sources. The mkindex |
| 125 | and translate preprocessors can be run in any order. The makeheaders |
| 126 |
+8
-6
| --- www/mkindex.tcl | ||
| +++ www/mkindex.tcl | ||
| @@ -19,10 +19,11 @@ | ||
| 19 | 19 | delta_format.wiki {Fossil Delta Format} |
| 20 | 20 | embeddeddoc.wiki {Embedded Project Documentation} |
| 21 | 21 | event.wiki {Events} |
| 22 | 22 | faq.wiki {Frequently Asked Questions} |
| 23 | 23 | fileformat.wiki {Fossil File Format} |
| 24 | + foss-cklist.wiki {Checklist For Successful Open-Source Projects} | |
| 24 | 25 | fossil-v-git.wiki {Fossil Versus Git} |
| 25 | 26 | index.wiki {Home Page} |
| 26 | 27 | inout.wiki {Import And Export To And From Git} |
| 27 | 28 | makefile.wiki {The Fossil Build Process} |
| 28 | 29 | password.wiki {Password Management And Authentication} |
| @@ -47,11 +48,11 @@ | ||
| 47 | 48 | webui.wiki {The Fossil Web Interface} |
| 48 | 49 | wikitheory.wiki {Wiki In Fossil} |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | 52 | set permindex {} |
| 52 | -set stopwords {fossil and a in of on the to are about used by} | |
| 53 | +set stopwords {fossil and a in of on the to are about used by for or} | |
| 53 | 54 | foreach {file title} $doclist { |
| 54 | 55 | set n [llength $title] |
| 55 | 56 | lappend permindex [list $title $file] |
| 56 | 57 | for {set i 0} {$i<$n-1} {incr i} { |
| 57 | 58 | set prefix [lrange $title 0 $i] |
| @@ -61,13 +62,14 @@ | ||
| 61 | 62 | lappend permindex [list "$suffix — $prefix" $file] |
| 62 | 63 | } |
| 63 | 64 | } |
| 64 | 65 | } |
| 65 | 66 | set permindex [lsort -dict $permindex] |
| 66 | -puts "<title>Permuted Index Of Fossil Documentation</title>" | |
| 67 | -puts "<nowiki>" | |
| 68 | -puts "<ul>" | |
| 67 | +set out [open permutedindex.wiki w] | |
| 68 | +puts $out "<title>Permuted Index Of Fossil Documentation</title>" | |
| 69 | +puts $out "<nowiki>" | |
| 70 | +puts $out "<ul>" | |
| 69 | 71 | foreach entry $permindex { |
| 70 | 72 | foreach {title file} $entry break |
| 71 | - puts "<li><a href=\"$file\">$title</a></li>" | |
| 73 | + puts $out "<li><a href=\"$file\">$title</a></li>" | |
| 72 | 74 | } |
| 73 | -puts "</ul>" | |
| 75 | +puts $out "</ul>" | |
| 74 | 76 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -19,10 +19,11 @@ | |
| 19 | delta_format.wiki {Fossil Delta Format} |
| 20 | embeddeddoc.wiki {Embedded Project Documentation} |
| 21 | event.wiki {Events} |
| 22 | faq.wiki {Frequently Asked Questions} |
| 23 | fileformat.wiki {Fossil File Format} |
| 24 | fossil-v-git.wiki {Fossil Versus Git} |
| 25 | index.wiki {Home Page} |
| 26 | inout.wiki {Import And Export To And From Git} |
| 27 | makefile.wiki {The Fossil Build Process} |
| 28 | password.wiki {Password Management And Authentication} |
| @@ -47,11 +48,11 @@ | |
| 47 | webui.wiki {The Fossil Web Interface} |
| 48 | wikitheory.wiki {Wiki In Fossil} |
| 49 | } |
| 50 | |
| 51 | set permindex {} |
| 52 | set stopwords {fossil and a in of on the to are about used by} |
| 53 | foreach {file title} $doclist { |
| 54 | set n [llength $title] |
| 55 | lappend permindex [list $title $file] |
| 56 | for {set i 0} {$i<$n-1} {incr i} { |
| 57 | set prefix [lrange $title 0 $i] |
| @@ -61,13 +62,14 @@ | |
| 61 | lappend permindex [list "$suffix — $prefix" $file] |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | set permindex [lsort -dict $permindex] |
| 66 | puts "<title>Permuted Index Of Fossil Documentation</title>" |
| 67 | puts "<nowiki>" |
| 68 | puts "<ul>" |
| 69 | foreach entry $permindex { |
| 70 | foreach {title file} $entry break |
| 71 | puts "<li><a href=\"$file\">$title</a></li>" |
| 72 | } |
| 73 | puts "</ul>" |
| 74 |
| --- www/mkindex.tcl | |
| +++ www/mkindex.tcl | |
| @@ -19,10 +19,11 @@ | |
| 19 | delta_format.wiki {Fossil Delta Format} |
| 20 | embeddeddoc.wiki {Embedded Project Documentation} |
| 21 | event.wiki {Events} |
| 22 | faq.wiki {Frequently Asked Questions} |
| 23 | fileformat.wiki {Fossil File Format} |
| 24 | foss-cklist.wiki {Checklist For Successful Open-Source Projects} |
| 25 | fossil-v-git.wiki {Fossil Versus Git} |
| 26 | index.wiki {Home Page} |
| 27 | inout.wiki {Import And Export To And From Git} |
| 28 | makefile.wiki {The Fossil Build Process} |
| 29 | password.wiki {Password Management And Authentication} |
| @@ -47,11 +48,11 @@ | |
| 48 | webui.wiki {The Fossil Web Interface} |
| 49 | wikitheory.wiki {Wiki In Fossil} |
| 50 | } |
| 51 | |
| 52 | set permindex {} |
| 53 | set stopwords {fossil and a in of on the to are about used by for or} |
| 54 | foreach {file title} $doclist { |
| 55 | set n [llength $title] |
| 56 | lappend permindex [list $title $file] |
| 57 | for {set i 0} {$i<$n-1} {incr i} { |
| 58 | set prefix [lrange $title 0 $i] |
| @@ -61,13 +62,14 @@ | |
| 62 | lappend permindex [list "$suffix — $prefix" $file] |
| 63 | } |
| 64 | } |
| 65 | } |
| 66 | set permindex [lsort -dict $permindex] |
| 67 | set out [open permutedindex.wiki w] |
| 68 | puts $out "<title>Permuted Index Of Fossil Documentation</title>" |
| 69 | puts $out "<nowiki>" |
| 70 | puts $out "<ul>" |
| 71 | foreach entry $permindex { |
| 72 | foreach {title file} $entry break |
| 73 | puts $out "<li><a href=\"$file\">$title</a></li>" |
| 74 | } |
| 75 | puts $out "</ul>" |
| 76 |
+4
-1
| --- www/permutedindex.wiki | ||
| +++ www/permutedindex.wiki | ||
| @@ -13,10 +13,11 @@ | ||
| 13 | 13 | <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li> |
| 14 | 14 | <li><a href="makefile.wiki">Build Process — The Fossil</a></li> |
| 15 | 15 | <li><a href="build.wiki">Building and Installing Fossil</a></li> |
| 16 | 16 | <li><a href="checkin_names.wiki">Checkin And Version Names</a></li> |
| 17 | 17 | <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> |
| 18 | +<li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li> | |
| 18 | 19 | <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> |
| 19 | 20 | <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> |
| 20 | 21 | <li><a href="style.wiki">Code Style Guidelines — Source</a></li> |
| 21 | 22 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 22 | 23 | <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> |
| @@ -73,12 +74,12 @@ | ||
| 73 | 74 | <li><a href="webui.wiki">Interface — The Fossil Web</a></li> |
| 74 | 75 | <li><a href="copyright-release.html">License Agreement — Contributor</a></li> |
| 75 | 76 | <li><a href="password.wiki">Management And Authentication — Password</a></li> |
| 76 | 77 | <li><a href="branching.wiki">Merging, and Tagging — Branching, Forking,</a></li> |
| 77 | 78 | <li><a href="checkin_names.wiki">Names — Checkin And Version</a></li> |
| 79 | +<li><a href="foss-cklist.wiki">Open-Source Projects — Checklist For Successful</a></li> | |
| 78 | 80 | <li><a href="pop.wiki">Operations — Principles Of</a></li> |
| 79 | -<li><a href="contribute.wiki">or Documentation To The Fossil Project — Contributing Code</a></li> | |
| 80 | 81 | <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil — A Technical</a></li> |
| 81 | 82 | <li><a href="index.wiki">Page — Home</a></li> |
| 82 | 83 | <li><a href="password.wiki">Password Management And Authentication</a></li> |
| 83 | 84 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 84 | 85 | <li><a href="stats.wiki">Performance Statistics</a></li> |
| @@ -86,10 +87,11 @@ | ||
| 86 | 87 | <li><a href="pop.wiki">Principles Of Operations</a></li> |
| 87 | 88 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| 88 | 89 | <li><a href="makefile.wiki">Process — The Fossil Build</a></li> |
| 89 | 90 | <li><a href="contribute.wiki">Project — Contributing Code or Documentation To The Fossil</a></li> |
| 90 | 91 | <li><a href="embeddeddoc.wiki">Project Documentation — Embedded</a></li> |
| 92 | +<li><a href="foss-cklist.wiki">Projects — Checklist For Successful Open-Source</a></li> | |
| 91 | 93 | <li><a href="sync.wiki">Protocol — The Fossil Sync</a></li> |
| 92 | 94 | <li><a href="faq.wiki">Questions — Frequently Asked</a></li> |
| 93 | 95 | <li><a href="qandc.wiki">Questions And Criticisms</a></li> |
| 94 | 96 | <li><a href="quickstart.wiki">Quick Start Guide — Fossil</a></li> |
| 95 | 97 | <li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li> |
| @@ -103,10 +105,11 @@ | ||
| 103 | 105 | <li><a href="style.wiki">Source Code Style Guidelines</a></li> |
| 104 | 106 | <li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li> |
| 105 | 107 | <li><a href="quickstart.wiki">Start Guide — Fossil Quick</a></li> |
| 106 | 108 | <li><a href="stats.wiki">Statistics — Performance</a></li> |
| 107 | 109 | <li><a href="style.wiki">Style Guidelines — Source Code</a></li> |
| 110 | +<li><a href="foss-cklist.wiki">Successful Open-Source Projects — Checklist For</a></li> | |
| 108 | 111 | <li><a href="sync.wiki">Sync Protocol — The Fossil</a></li> |
| 109 | 112 | <li><a href="private.wiki">Syncing, and Deleting Private Branches — Creating,</a></li> |
| 110 | 113 | <li><a href="custom_ticket.wiki">System — Customizing The Ticket</a></li> |
| 111 | 114 | <li><a href="branching.wiki">Tagging — Branching, Forking, Merging, and</a></li> |
| 112 | 115 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 113 | 116 |
| --- www/permutedindex.wiki | |
| +++ www/permutedindex.wiki | |
| @@ -13,10 +13,11 @@ | |
| 13 | <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li> |
| 14 | <li><a href="makefile.wiki">Build Process — The Fossil</a></li> |
| 15 | <li><a href="build.wiki">Building and Installing Fossil</a></li> |
| 16 | <li><a href="checkin_names.wiki">Checkin And Version Names</a></li> |
| 17 | <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> |
| 18 | <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> |
| 19 | <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> |
| 20 | <li><a href="style.wiki">Code Style Guidelines — Source</a></li> |
| 21 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 22 | <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> |
| @@ -73,12 +74,12 @@ | |
| 73 | <li><a href="webui.wiki">Interface — The Fossil Web</a></li> |
| 74 | <li><a href="copyright-release.html">License Agreement — Contributor</a></li> |
| 75 | <li><a href="password.wiki">Management And Authentication — Password</a></li> |
| 76 | <li><a href="branching.wiki">Merging, and Tagging — Branching, Forking,</a></li> |
| 77 | <li><a href="checkin_names.wiki">Names — Checkin And Version</a></li> |
| 78 | <li><a href="pop.wiki">Operations — Principles Of</a></li> |
| 79 | <li><a href="contribute.wiki">or Documentation To The Fossil Project — Contributing Code</a></li> |
| 80 | <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil — A Technical</a></li> |
| 81 | <li><a href="index.wiki">Page — Home</a></li> |
| 82 | <li><a href="password.wiki">Password Management And Authentication</a></li> |
| 83 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 84 | <li><a href="stats.wiki">Performance Statistics</a></li> |
| @@ -86,10 +87,11 @@ | |
| 86 | <li><a href="pop.wiki">Principles Of Operations</a></li> |
| 87 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| 88 | <li><a href="makefile.wiki">Process — The Fossil Build</a></li> |
| 89 | <li><a href="contribute.wiki">Project — Contributing Code or Documentation To The Fossil</a></li> |
| 90 | <li><a href="embeddeddoc.wiki">Project Documentation — Embedded</a></li> |
| 91 | <li><a href="sync.wiki">Protocol — The Fossil Sync</a></li> |
| 92 | <li><a href="faq.wiki">Questions — Frequently Asked</a></li> |
| 93 | <li><a href="qandc.wiki">Questions And Criticisms</a></li> |
| 94 | <li><a href="quickstart.wiki">Quick Start Guide — Fossil</a></li> |
| 95 | <li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li> |
| @@ -103,10 +105,11 @@ | |
| 103 | <li><a href="style.wiki">Source Code Style Guidelines</a></li> |
| 104 | <li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li> |
| 105 | <li><a href="quickstart.wiki">Start Guide — Fossil Quick</a></li> |
| 106 | <li><a href="stats.wiki">Statistics — Performance</a></li> |
| 107 | <li><a href="style.wiki">Style Guidelines — Source Code</a></li> |
| 108 | <li><a href="sync.wiki">Sync Protocol — The Fossil</a></li> |
| 109 | <li><a href="private.wiki">Syncing, and Deleting Private Branches — Creating,</a></li> |
| 110 | <li><a href="custom_ticket.wiki">System — Customizing The Ticket</a></li> |
| 111 | <li><a href="branching.wiki">Tagging — Branching, Forking, Merging, and</a></li> |
| 112 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 113 |
| --- www/permutedindex.wiki | |
| +++ www/permutedindex.wiki | |
| @@ -13,10 +13,11 @@ | |
| 13 | <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li> |
| 14 | <li><a href="makefile.wiki">Build Process — The Fossil</a></li> |
| 15 | <li><a href="build.wiki">Building and Installing Fossil</a></li> |
| 16 | <li><a href="checkin_names.wiki">Checkin And Version Names</a></li> |
| 17 | <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> |
| 18 | <li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li> |
| 19 | <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> |
| 20 | <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> |
| 21 | <li><a href="style.wiki">Code Style Guidelines — Source</a></li> |
| 22 | <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> |
| 23 | <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> |
| @@ -73,12 +74,12 @@ | |
| 74 | <li><a href="webui.wiki">Interface — The Fossil Web</a></li> |
| 75 | <li><a href="copyright-release.html">License Agreement — Contributor</a></li> |
| 76 | <li><a href="password.wiki">Management And Authentication — Password</a></li> |
| 77 | <li><a href="branching.wiki">Merging, and Tagging — Branching, Forking,</a></li> |
| 78 | <li><a href="checkin_names.wiki">Names — Checkin And Version</a></li> |
| 79 | <li><a href="foss-cklist.wiki">Open-Source Projects — Checklist For Successful</a></li> |
| 80 | <li><a href="pop.wiki">Operations — Principles Of</a></li> |
| 81 | <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil — A Technical</a></li> |
| 82 | <li><a href="index.wiki">Page — Home</a></li> |
| 83 | <li><a href="password.wiki">Password Management And Authentication</a></li> |
| 84 | <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> |
| 85 | <li><a href="stats.wiki">Performance Statistics</a></li> |
| @@ -86,10 +87,11 @@ | |
| 87 | <li><a href="pop.wiki">Principles Of Operations</a></li> |
| 88 | <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> |
| 89 | <li><a href="makefile.wiki">Process — The Fossil Build</a></li> |
| 90 | <li><a href="contribute.wiki">Project — Contributing Code or Documentation To The Fossil</a></li> |
| 91 | <li><a href="embeddeddoc.wiki">Project Documentation — Embedded</a></li> |
| 92 | <li><a href="foss-cklist.wiki">Projects — Checklist For Successful Open-Source</a></li> |
| 93 | <li><a href="sync.wiki">Protocol — The Fossil Sync</a></li> |
| 94 | <li><a href="faq.wiki">Questions — Frequently Asked</a></li> |
| 95 | <li><a href="qandc.wiki">Questions And Criticisms</a></li> |
| 96 | <li><a href="quickstart.wiki">Quick Start Guide — Fossil</a></li> |
| 97 | <li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li> |
| @@ -103,10 +105,11 @@ | |
| 105 | <li><a href="style.wiki">Source Code Style Guidelines</a></li> |
| 106 | <li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li> |
| 107 | <li><a href="quickstart.wiki">Start Guide — Fossil Quick</a></li> |
| 108 | <li><a href="stats.wiki">Statistics — Performance</a></li> |
| 109 | <li><a href="style.wiki">Style Guidelines — Source Code</a></li> |
| 110 | <li><a href="foss-cklist.wiki">Successful Open-Source Projects — Checklist For</a></li> |
| 111 | <li><a href="sync.wiki">Sync Protocol — The Fossil</a></li> |
| 112 | <li><a href="private.wiki">Syncing, and Deleting Private Branches — Creating,</a></li> |
| 113 | <li><a href="custom_ticket.wiki">System — Customizing The Ticket</a></li> |
| 114 | <li><a href="branching.wiki">Tagging — Branching, Forking, Merging, and</a></li> |
| 115 | <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil — A</a></li> |
| 116 |
+15
-7
| --- www/quickstart.wiki | ||
| +++ www/quickstart.wiki | ||
| @@ -9,11 +9,11 @@ | ||
| 9 | 9 | <p>Fossil is a single self-contained C program. You need to |
| 10 | 10 | either download a |
| 11 | 11 | <a href="http://www.fossil-scm.org/download.html">precompiled binary</a> |
| 12 | 12 | or <a href="build.wiki">build it yourself</a> from sources. |
| 13 | 13 | Install fossil by putting the fossil binary |
| 14 | - someplace on your PATH environment variable.</p> | |
| 14 | + someplace on your $PATH.</p> | |
| 15 | 15 | |
| 16 | 16 | <a name="fslclone"></a> |
| 17 | 17 | <h2>General Work Flow</h2> |
| 18 | 18 | |
| 19 | 19 | <p>Fossil works with repository files (a database with the project's |
| @@ -20,29 +20,27 @@ | ||
| 20 | 20 | complete history) and with checked-out local trees (the working directory |
| 21 | 21 | you use to do your work). |
| 22 | 22 | The workflow looks like this:</p> |
| 23 | 23 | |
| 24 | 24 | <ul> |
| 25 | - <li>Create or clone a repository file. ([/help/new|fossil new] or | |
| 25 | + <li>Create or clone a repository file. ([/help/init|fossil init] or | |
| 26 | 26 | [/help/clone | fossil clone]) |
| 27 | 27 | <li>Check out a local tree. ([/help/open | fossil open]) |
| 28 | 28 | <li>Perform operations on the repository (including repository |
| 29 | 29 | configuration). |
| 30 | - <li><em>Optionally</em> close the local tree. | |
| 31 | - ([/help/close | fossil close], but this is rarely used.) | |
| 32 | 30 | </ul> |
| 33 | 31 | |
| 34 | 32 | <p>The following sections will give you a brief overview of these |
| 35 | 33 | operations.</p> |
| 36 | 34 | |
| 37 | 35 | <h2>Starting A New Project</h2> |
| 38 | 36 | |
| 39 | 37 | <p>To start a new project with fossil, create a new empty repository |
| 40 | - this way: ([/help/new | more info]) </p> | |
| 38 | + this way: ([/help/init | more info]) </p> | |
| 41 | 39 | |
| 42 | 40 | <blockquote> |
| 43 | - <b>fossil new </b><i> repository-filename</i> | |
| 41 | + <b>fossil init </b><i> repository-filename</i> | |
| 44 | 42 | </blockquote> |
| 45 | 43 | |
| 46 | 44 | <h2>Cloning An Existing Repository</h2> |
| 47 | 45 | |
| 48 | 46 | <p>Most fossil operations interact with a repository that is on the |
| @@ -73,10 +71,19 @@ | ||
| 73 | 71 | You can name your repositories anything you want. The ".fossil" suffix |
| 74 | 72 | is not required.</p> |
| 75 | 73 | |
| 76 | 74 | <p>Note: If you are behind a restrictive firewall, you might need |
| 77 | 75 | to <a href="#proxy">specify an HTTP proxy</a> to use.</p> |
| 76 | + | |
| 77 | + <p>A Fossil repository is a single disk file. Instead of cloning, | |
| 78 | + you can just make a copy of the repository file (for example, using | |
| 79 | + "scp"). Note, however, that the repository file contains auxiliary | |
| 80 | + information above and beyond the versioned files, including some | |
| 81 | + sensitive information such as passwords and email addresses. If you | |
| 82 | + want to share Fossil repositories directly, consider running the | |
| 83 | + [/help/scrub|fossil scrub] command to remove sensitive information | |
| 84 | + before transmitting the file. | |
| 78 | 85 | |
| 79 | 86 | <h2>Importing From Another Version Control System</h2> |
| 80 | 87 | |
| 81 | 88 | <p>Rather than start a new project, or clone an existing Fossil project, |
| 82 | 89 | you might prefer to |
| @@ -147,11 +154,12 @@ | ||
| 147 | 154 | <p>To add new files to your project, or remove old files, use these |
| 148 | 155 | commands:</p> |
| 149 | 156 | |
| 150 | 157 | <blockquote> |
| 151 | 158 | <b>[/help/add | fossil add]</b> <i>file...</i><br> |
| 152 | - <b>[/help/rm | fossil rm]</b> <i>file...</i> | |
| 159 | + <b>[/help/rm | fossil rm]</b> <i>file...</i><br> | |
| 160 | + <b>[/help/addremove | fossil addremove]</b> <i>file...</i><br> | |
| 153 | 161 | </blockquote> |
| 154 | 162 | |
| 155 | 163 | <p>You can also edit files freely. Once you are ready to commit |
| 156 | 164 | your changes, type:</p> |
| 157 | 165 | |
| 158 | 166 |
| --- www/quickstart.wiki | |
| +++ www/quickstart.wiki | |
| @@ -9,11 +9,11 @@ | |
| 9 | <p>Fossil is a single self-contained C program. You need to |
| 10 | either download a |
| 11 | <a href="http://www.fossil-scm.org/download.html">precompiled binary</a> |
| 12 | or <a href="build.wiki">build it yourself</a> from sources. |
| 13 | Install fossil by putting the fossil binary |
| 14 | someplace on your PATH environment variable.</p> |
| 15 | |
| 16 | <a name="fslclone"></a> |
| 17 | <h2>General Work Flow</h2> |
| 18 | |
| 19 | <p>Fossil works with repository files (a database with the project's |
| @@ -20,29 +20,27 @@ | |
| 20 | complete history) and with checked-out local trees (the working directory |
| 21 | you use to do your work). |
| 22 | The workflow looks like this:</p> |
| 23 | |
| 24 | <ul> |
| 25 | <li>Create or clone a repository file. ([/help/new|fossil new] or |
| 26 | [/help/clone | fossil clone]) |
| 27 | <li>Check out a local tree. ([/help/open | fossil open]) |
| 28 | <li>Perform operations on the repository (including repository |
| 29 | configuration). |
| 30 | <li><em>Optionally</em> close the local tree. |
| 31 | ([/help/close | fossil close], but this is rarely used.) |
| 32 | </ul> |
| 33 | |
| 34 | <p>The following sections will give you a brief overview of these |
| 35 | operations.</p> |
| 36 | |
| 37 | <h2>Starting A New Project</h2> |
| 38 | |
| 39 | <p>To start a new project with fossil, create a new empty repository |
| 40 | this way: ([/help/new | more info]) </p> |
| 41 | |
| 42 | <blockquote> |
| 43 | <b>fossil new </b><i> repository-filename</i> |
| 44 | </blockquote> |
| 45 | |
| 46 | <h2>Cloning An Existing Repository</h2> |
| 47 | |
| 48 | <p>Most fossil operations interact with a repository that is on the |
| @@ -73,10 +71,19 @@ | |
| 73 | You can name your repositories anything you want. The ".fossil" suffix |
| 74 | is not required.</p> |
| 75 | |
| 76 | <p>Note: If you are behind a restrictive firewall, you might need |
| 77 | to <a href="#proxy">specify an HTTP proxy</a> to use.</p> |
| 78 | |
| 79 | <h2>Importing From Another Version Control System</h2> |
| 80 | |
| 81 | <p>Rather than start a new project, or clone an existing Fossil project, |
| 82 | you might prefer to |
| @@ -147,11 +154,12 @@ | |
| 147 | <p>To add new files to your project, or remove old files, use these |
| 148 | commands:</p> |
| 149 | |
| 150 | <blockquote> |
| 151 | <b>[/help/add | fossil add]</b> <i>file...</i><br> |
| 152 | <b>[/help/rm | fossil rm]</b> <i>file...</i> |
| 153 | </blockquote> |
| 154 | |
| 155 | <p>You can also edit files freely. Once you are ready to commit |
| 156 | your changes, type:</p> |
| 157 | |
| 158 |
| --- www/quickstart.wiki | |
| +++ www/quickstart.wiki | |
| @@ -9,11 +9,11 @@ | |
| 9 | <p>Fossil is a single self-contained C program. You need to |
| 10 | either download a |
| 11 | <a href="http://www.fossil-scm.org/download.html">precompiled binary</a> |
| 12 | or <a href="build.wiki">build it yourself</a> from sources. |
| 13 | Install fossil by putting the fossil binary |
| 14 | someplace on your $PATH.</p> |
| 15 | |
| 16 | <a name="fslclone"></a> |
| 17 | <h2>General Work Flow</h2> |
| 18 | |
| 19 | <p>Fossil works with repository files (a database with the project's |
| @@ -20,29 +20,27 @@ | |
| 20 | complete history) and with checked-out local trees (the working directory |
| 21 | you use to do your work). |
| 22 | The workflow looks like this:</p> |
| 23 | |
| 24 | <ul> |
| 25 | <li>Create or clone a repository file. ([/help/init|fossil init] or |
| 26 | [/help/clone | fossil clone]) |
| 27 | <li>Check out a local tree. ([/help/open | fossil open]) |
| 28 | <li>Perform operations on the repository (including repository |
| 29 | configuration). |
| 30 | </ul> |
| 31 | |
| 32 | <p>The following sections will give you a brief overview of these |
| 33 | operations.</p> |
| 34 | |
| 35 | <h2>Starting A New Project</h2> |
| 36 | |
| 37 | <p>To start a new project with fossil, create a new empty repository |
| 38 | this way: ([/help/init | more info]) </p> |
| 39 | |
| 40 | <blockquote> |
| 41 | <b>fossil init </b><i> repository-filename</i> |
| 42 | </blockquote> |
| 43 | |
| 44 | <h2>Cloning An Existing Repository</h2> |
| 45 | |
| 46 | <p>Most fossil operations interact with a repository that is on the |
| @@ -73,10 +71,19 @@ | |
| 71 | You can name your repositories anything you want. The ".fossil" suffix |
| 72 | is not required.</p> |
| 73 | |
| 74 | <p>Note: If you are behind a restrictive firewall, you might need |
| 75 | to <a href="#proxy">specify an HTTP proxy</a> to use.</p> |
| 76 | |
| 77 | <p>A Fossil repository is a single disk file. Instead of cloning, |
| 78 | you can just make a copy of the repository file (for example, using |
| 79 | "scp"). Note, however, that the repository file contains auxiliary |
| 80 | information above and beyond the versioned files, including some |
| 81 | sensitive information such as passwords and email addresses. If you |
| 82 | want to share Fossil repositories directly, consider running the |
| 83 | [/help/scrub|fossil scrub] command to remove sensitive information |
| 84 | before transmitting the file. |
| 85 | |
| 86 | <h2>Importing From Another Version Control System</h2> |
| 87 | |
| 88 | <p>Rather than start a new project, or clone an existing Fossil project, |
| 89 | you might prefer to |
| @@ -147,11 +154,12 @@ | |
| 154 | <p>To add new files to your project, or remove old files, use these |
| 155 | commands:</p> |
| 156 | |
| 157 | <blockquote> |
| 158 | <b>[/help/add | fossil add]</b> <i>file...</i><br> |
| 159 | <b>[/help/rm | fossil rm]</b> <i>file...</i><br> |
| 160 | <b>[/help/addremove | fossil addremove]</b> <i>file...</i><br> |
| 161 | </blockquote> |
| 162 | |
| 163 | <p>You can also edit files freely. Once you are ready to commit |
| 164 | your changes, type:</p> |
| 165 | |
| 166 |