Fossil SCM

Merge trunk with ben-testing

ben 2011-07-20 08:29 ben-testing merge
Commit 74d65bab28c8c27ba544df42a16c84342bc7b4d2
+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:
42
53
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.
614
715
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:
922
10
- make -f win/Makefile.w32
23
+ cd win; nmake /f Makefile.msc
1124
1225
If you have trouble, or you want to do something fancy, just look at
1326
top level makefile. There are 6 configuration options that are all well
1427
commented. Instead of editing the Makefile, consider copying the Makefile
1528
to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile"
1629
1730
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
--- 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
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-1.18
1
+1.19
22
33
ADDED auto.def
44
ADDED autosetup/LICENSE
55
ADDED autosetup/README.autosetup
66
ADDED autosetup/autosetup
77
ADDED autosetup/cc-lib.tcl
88
ADDED autosetup/cc-shared.tcl
99
ADDED autosetup/cc.tcl
1010
ADDED autosetup/config.guess
1111
ADDED autosetup/config.sub
1212
ADDED autosetup/find-tclsh
1313
ADDED autosetup/jimsh0.c
1414
ADDED autosetup/local.tcl
1515
ADDED autosetup/system.tcl
1616
ADDED autosetup/test-tclsh
1717
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
+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
--- 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
--- 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 {
--- 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 }
--- 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
--- 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
--- 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
--- 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/
--- 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
--- 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
--- 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
--- 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
--- 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 @@
176176
db_end_transaction(0);
177177
178178
/* Do an autosync push, if requested */
179179
autosync(AUTOSYNC_PUSH);
180180
}
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
+
181218
182219
/*
183220
** COMMAND: branch
184221
**
185222
** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE?
@@ -194,11 +231,12 @@
194231
** --private option makes the branch private.
195232
**
196233
** %fossil branch list
197234
** %fossil branch ls
198235
**
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.
200238
**
201239
*/
202240
void branch_cmd(void){
203241
int n;
204242
const char *zCmd = "list";
@@ -212,24 +250,19 @@
212250
branch_new();
213251
}else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
214252
Stmt q;
215253
int vid;
216254
char *zCurrent = 0;
255
+ int showAll = find_option("all",0,0)!=0;
256
+ int showClosed = find_option("closed",0,0)!=0;
217257
218258
if( g.localOpen ){
219259
vid = db_lget_int("checkout", 0);
220260
zCurrent = db_text(0, "SELECT value FROM tagxref"
221261
" WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
222262
}
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);
231264
while( db_step(&q)==SQLITE_ROW ){
232265
const char *zBr = db_column_text(&q, 0);
233266
int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
234267
fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
235268
}
@@ -247,19 +280,26 @@
247280
*/
248281
void brlist_page(void){
249282
Stmt q;
250283
int cnt;
251284
int showClosed = P("closed")!=0;
285
+ int showAll = P("all")!=0;
252286
253287
login_check_credentials();
254288
if( !g.okRead ){ login_needed(); return; }
255289
256
- style_header(showClosed ? "Closed Branches" : "Open Branches");
290
+ style_header(showClosed ? "Closed Branches" :
291
+ showAll ? "All Branches" : "Open Branches");
257292
style_submenu_element("Timeline", "Timeline", "brtimeline");
258293
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");
259298
style_submenu_element("Open","Open","brlist");
260299
}else{
300
+ style_submenu_element("All", "All", "brlist?all");
261301
style_submenu_element("Closed","Closed","brlist?closed");
262302
}
263303
login_anonymous_available();
264304
style_sidebox_begin("Nomenclature:", "33%");
265305
@ <ol>
@@ -275,33 +315,12 @@
275315
@ Closed branches are fixed and do not change (unless they are first
276316
@ reopened)</li>
277317
@ </ol>
278318
style_sidebox_end();
279319
320
+ prepareBranchQuery(&q, showAll, showClosed);
280321
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
- }
303322
while( db_step(&q)==SQLITE_ROW ){
304323
const char *zBr = db_column_text(&q, 0);
305324
if( cnt==0 ){
306325
if( showClosed ){
307326
@ <h2>Closed Branches:</h2>
308327
--- 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 @@
267267
if( zFN[0]=='/' ){
268268
zFN++;
269269
@ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li>
270270
}else if( zCI ){
271271
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>
273273
}else{
274274
@ <li><a href="%s(g.zTop)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
275275
@ </a></li>
276276
}
277277
}
278278
--- 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 @@
353353
if( size>0 ){
354354
fwrite(blob_buffer(&cgiContent[i]), 1, size, g.httpOut);
355355
}
356356
}
357357
}
358
+ fflush(g.httpOut);
358359
CGIDEBUG(("DONE\n"));
359360
}
360361
361362
/*
362363
** Do a redirect request to the URL given in the argument.
@@ -887,17 +888,26 @@
887888
}
888889
889890
/*
890891
** Print all query parameters on standard output. Format the
891892
** 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.
892895
*/
893896
void cgi_print_all(void){
894897
int i;
898
+ int showAll = 0;
899
+#ifdef FOSSIL_DEBUG
900
+ /* Show the values of cookies in debug mode. */
901
+ showAll = 1;
902
+#endif
895903
cgi_parameter("",""); /* Force the parameters into sorted order */
896904
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
+ }
899909
}
900910
}
901911
902912
/*
903913
** This routine works like "printf" except that it has the
904914
--- 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 @@
4343
**
4444
*/
4545
void clone_cmd(void){
4646
char *zPassword;
4747
const char *zDefaultUser; /* Optional name of the default user */
48
+ const char *zPw; /* The user clone password */
4849
int nErr = 0;
4950
int bPrivate; /* Also clone private branches */
5051
5152
bPrivate = find_option("private",0,0)!=0;
5253
url_proxy_options();
@@ -77,13 +78,15 @@
7778
"DELETE FROM blob WHERE rid IN private;"
7879
"DELETE FROM delta wHERE rid IN private;"
7980
"DELETE FROM private;"
8081
);
8182
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%%'");
8588
}
8689
fossil_print("Repository cloned into %s\n", g.argv[3]);
8790
}else{
8891
db_create_repository(g.argv[3]);
8992
db_open_repository(g.argv[3]);
@@ -125,7 +128,9 @@
125128
rebuild_db(0, 1, 0);
126129
fossil_print("project-id: %s\n", db_get("project-code", 0));
127130
fossil_print("server-id: %s\n", db_get("server-code", 0));
128131
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
129132
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);
130135
db_end_transaction(0);
131136
}
132137
--- 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 @@
4343
**
4444
*/
4545
void clone_cmd(void){
4646
char *zPassword;
4747
const char *zDefaultUser; /* Optional name of the default user */
48
+ const char *zPw; /* The user clone password */
4849
int nErr = 0;
4950
int bPrivate; /* Also clone private branches */
5051
5152
bPrivate = find_option("private",0,0)!=0;
5253
url_proxy_options();
@@ -77,13 +78,15 @@
7778
"DELETE FROM blob WHERE rid IN private;"
7879
"DELETE FROM delta wHERE rid IN private;"
7980
"DELETE FROM private;"
8081
);
8182
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%%'");
8588
}
8689
fossil_print("Repository cloned into %s\n", g.argv[3]);
8790
}else{
8891
db_create_repository(g.argv[3]);
8992
db_open_repository(g.argv[3]);
@@ -125,7 +128,9 @@
125128
rebuild_db(0, 1, 0);
126129
fossil_print("project-id: %s\n", db_get("project-code", 0));
127130
fossil_print("server-id: %s\n", db_get("server-code", 0));
128131
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
129132
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);
130135
db_end_transaction(0);
131136
}
132137
--- 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 @@
2424
#define _LARGE_FILE 1
2525
#ifndef _FILE_OFFSET_BITS
2626
# define _FILE_OFFSET_BITS 64
2727
#endif
2828
#define _LARGEFILE_SOURCE 1
29
+
30
+#ifdef HAVE_AUTOCONFIG_H
31
+#include "autoconfig.h"
32
+#endif
2933
3034
#ifndef _RC_COMPILE_
3135
3236
/*
3337
** System header files used by all modules
@@ -85,11 +89,11 @@
8589
#include "sqlite3.h"
8690
8791
/*
8892
** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257.
8993
*/
90
-#if defined(__sun__) || defined(sun)
94
+#if HAVE_GETPASSPHRASE
9195
#define getpass getpassphrase
9296
#endif
9397
9498
/*
9599
** Typedef for a 64-bit integer
96100
--- 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
+9 -6
--- src/db.c
+++ src/db.c
@@ -809,10 +809,11 @@
809809
static const char *aDbName[] = { "/_FOSSIL_", "/.fos" };
810810
811811
if( g.localOpen) return 1;
812812
file_getcwd(zPwd, sizeof(zPwd)-20);
813813
n = strlen(zPwd);
814
+ if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.';
814815
while( n>0 ){
815816
if( file_access(zPwd, W_OK) ) break;
816817
for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){
817818
sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]);
818819
if( isValidLocalDb(zPwd) ){
@@ -1058,14 +1059,13 @@
10581059
10591060
/*
10601061
** Create the default user accounts in the USER table.
10611062
*/
10621063
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;
10651065
if( zUser==0 ){
1066
- zUser = zDefaultUser;
1066
+ zUser = db_get("default-user", 0);
10671067
}
10681068
if( zUser==0 ){
10691069
#if defined(_WIN32)
10701070
zUser = getenv("USERNAME");
10711071
#else
@@ -1074,12 +1074,15 @@
10741074
}
10751075
if( zUser==0 ){
10761076
zUser = "root";
10771077
}
10781078
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
10811084
);
10821085
if( !setupUserOnly ){
10831086
db_multi_exec(
10841087
"INSERT INTO user(login,pw,cap,info)"
10851088
" VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');"
@@ -1928,11 +1931,11 @@
19281931
db_set(ctrlSettings[i].name, g.argv[3], globalFlag);
19291932
}else{
19301933
isManifest = 0;
19311934
print_setting(&ctrlSettings[i], db_open_local());
19321935
}
1933
- if( isManifest ){
1936
+ if( isManifest && g.localOpen ){
19341937
manifest_to_disk(db_lget_int("checkout", 0));
19351938
}
19361939
}else{
19371940
usage("?PROPERTY? ?VALUE?");
19381941
}
19391942
--- 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
+9 -6
--- src/db.c
+++ src/db.c
@@ -809,10 +809,11 @@
809809
static const char *aDbName[] = { "/_FOSSIL_", "/.fos" };
810810
811811
if( g.localOpen) return 1;
812812
file_getcwd(zPwd, sizeof(zPwd)-20);
813813
n = strlen(zPwd);
814
+ if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.';
814815
while( n>0 ){
815816
if( file_access(zPwd, W_OK) ) break;
816817
for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){
817818
sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]);
818819
if( isValidLocalDb(zPwd) ){
@@ -1058,14 +1059,13 @@
10581059
10591060
/*
10601061
** Create the default user accounts in the USER table.
10611062
*/
10621063
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;
10651065
if( zUser==0 ){
1066
- zUser = zDefaultUser;
1066
+ zUser = db_get("default-user", 0);
10671067
}
10681068
if( zUser==0 ){
10691069
#if defined(_WIN32)
10701070
zUser = getenv("USERNAME");
10711071
#else
@@ -1074,12 +1074,15 @@
10741074
}
10751075
if( zUser==0 ){
10761076
zUser = "root";
10771077
}
10781078
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
10811084
);
10821085
if( !setupUserOnly ){
10831086
db_multi_exec(
10841087
"INSERT INTO user(login,pw,cap,info)"
10851088
" VALUES('anonymous',hex(randomblob(8)),'hmncz','Anon');"
@@ -1928,11 +1931,11 @@
19281931
db_set(ctrlSettings[i].name, g.argv[3], globalFlag);
19291932
}else{
19301933
isManifest = 0;
19311934
print_setting(&ctrlSettings[i], db_open_local());
19321935
}
1933
- if( isManifest ){
1936
+ if( isManifest && g.localOpen ){
19341937
manifest_to_disk(db_lget_int("checkout", 0));
19351938
}
19361939
}else{
19371940
usage("?PROPERTY? ?VALUE?");
19381941
}
19391942
--- 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 @@
12131213
}
12141214
12151215
12161216
/*
12171217
** WEBPAGE: artifact
1218
-** URL: /artifact?name=ARTIFACTID
1218
+** URL: /artifact/ARTIFACTID
12191219
** 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
12201226
**
12211227
** Show the complete content of a file identified by ARTIFACTID
12221228
** as preformatted text.
12231229
*/
12241230
void artifact_page(void){
@@ -1260,24 +1266,24 @@
12601266
zMime = mimetype_from_name(blob_str(&downloadName));
12611267
if( zMime ){
12621268
if( fossil_strcmp(zMime, "text/html")==0 ){
12631269
if( P("txt") ){
12641270
style_submenu_element("Html", "Html",
1265
- "%s/artifact?name=%s", g.zTop, zUuid);
1271
+ "%s/artifact/%s", g.zTop, zUuid);
12661272
}else{
12671273
renderAsHtml = 1;
12681274
style_submenu_element("Text", "Text",
1269
- "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
1275
+ "%s/artifact/%s?txt=1", g.zTop, zUuid);
12701276
}
12711277
}else if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){
12721278
if( P("txt") ){
12731279
style_submenu_element("Wiki", "Wiki",
1274
- "%s/artifact?name=%s", g.zTop, zUuid);
1280
+ "%s/artifact/%s", g.zTop, zUuid);
12751281
}else{
12761282
renderAsWiki = 1;
12771283
style_submenu_element("Text", "Text",
1278
- "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
1284
+ "%s/artifact/%s?txt=1", g.zTop, zUuid);
12791285
}
12801286
}
12811287
}
12821288
@ </p></blockquote>
12831289
@ <hr />
12841290
--- 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&amp;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&amp;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 @@
11041104
if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
11051105
cgi_setenv("HOME", blob_str(&value));
11061106
blob_reset(&value);
11071107
continue;
11081108
}
1109
- if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){
1109
+ if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
1110
+ blob_trim(&value);
11101111
db_open_repository(blob_str(&value));
11111112
blob_reset(&value);
11121113
continue;
11131114
}
11141115
if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){
@@ -1439,11 +1440,14 @@
14391440
if( isUiCmd ){
14401441
zBrowser = db_get("web-browser", "start");
14411442
zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
14421443
}
14431444
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
+ }
14451449
#endif
14461450
}
14471451
14481452
/*
14491453
** COMMAND: test-echo
14501454
--- 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 @@
11041104
if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
11051105
cgi_setenv("HOME", blob_str(&value));
11061106
blob_reset(&value);
11071107
continue;
11081108
}
1109
- if( blob_eq(&key, "repository:") && blob_token(&line, &value) ){
1109
+ if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
1110
+ blob_trim(&value);
11101111
db_open_repository(blob_str(&value));
11111112
blob_reset(&value);
11121113
continue;
11131114
}
11141115
if( blob_eq(&key, "directory:") && blob_token(&line, &value) ){
@@ -1439,11 +1440,14 @@
14391440
if( isUiCmd ){
14401441
zBrowser = db_get("web-browser", "start");
14411442
zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
14421443
}
14431444
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
+ }
14451449
#endif
14461450
}
14471451
14481452
/*
14491453
** COMMAND: test-echo
14501454
--- 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 @@
293293
$(TCLSH) test/tester.tcl $(APPNAME)
294294
295295
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
296296
$(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
297297
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
299307
300308
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
301309
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
302310
303311
# This rule prevents make from using its default rules to try build
@@ -892,14 +900,14 @@
892900
893901
$(OBJDIR)/zip.h: $(OBJDIR)/headers
894902
$(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
895903
$(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
896904
897
-$(OBJDIR)/shell.o: $(SRCDIR)/shell.c
905
+$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
898906
$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
899907
900908
$(OBJDIR)/th.o: $(SRCDIR)/th.c
901909
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
902910
903911
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
904912
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
905913
906914
--- 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 @@
190190
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
191191
$(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \
192192
$(SRCDIR)/../manifest \
193193
$(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
194194
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
+
195203
EXTRAOBJ = \
196
- $(OBJDIR)/sqlite3.o \
204
+ $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
197205
$(OBJDIR)/shell.o \
198206
$(OBJDIR)/th.o \
199207
$(OBJDIR)/th_lang.o
200208
201209
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
@@ -246,11 +254,11 @@
246254
append opt " -Dlocaltime=fossil_localtime"
247255
append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0"
248256
set SQLITE_OPTIONS $opt
249257
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
250258
251
-writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c"
259
+writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
252260
set opt {-Dmain=sqlite3_shell}
253261
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
254262
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
255263
256264
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
@@ -398,11 +406,11 @@
398406
# the repository after running the tests.
399407
test: $(APPNAME)
400408
$(TCLSH) test/tester.tcl $(APPNAME)
401409
402410
$(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
404412
405413
EXTRAOBJ = \
406414
$(OBJDIR)/sqlite3.o \
407415
$(OBJDIR)/shell.o \
408416
$(OBJDIR)/th.o \
@@ -458,11 +466,11 @@
458466
459467
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
460468
set opt $SQLITE_OPTIONS
461469
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
462470
463
-writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c"
471
+writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
464472
set opt {-Dmain=sqlite3_shell}
465473
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
466474
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
467475
468476
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
@@ -570,11 +578,11 @@
570578
$(TCC) -o$@ -c $**
571579
572580
$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
573581
$(TCC) -o$@ -c $**
574582
575
-VERSION.h : version$E $B\manifest.uuid $B\manifest
583
+VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
576584
+$** > $@
577585
578586
page_index.h: mkindex$E $(SRC)
579587
+$** > $@
580588
@@ -645,11 +653,11 @@
645653
INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)
646654
647655
CFLAGS = -nologo -MT -O2
648656
BCC = $(CC) $(CFLAGS)
649657
TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL)
650
-LIBS = $(ZLIB) ws2_32.lib $(SSLLIB)
658
+LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
651659
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
652660
}
653661
regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS
654662
writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n"
655663
writeln -nonewline "SRC = "
@@ -692,11 +700,11 @@
692700
$(BCC) $**
693701
694702
mkindex$E: $(SRCDIR)\mkindex.c
695703
$(BCC) $**
696704
697
-version$E: $B\src\mkversion.c
705
+mkversion$E: $B\src\mkversion.c
698706
$(BCC) $**
699707
700708
$(OX)\shell$O : $(SRCDIR)\shell.c
701709
$(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c
702710
@@ -707,11 +715,11 @@
707715
$(TCC) /Fo$@ -c $**
708716
709717
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
710718
$(TCC) /Fo$@ -c $**
711719
712
-VERSION.h : version$E $B\manifest.uuid $B\manifest
720
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
713721
$** > $@
714722
715723
page_index.h: mkindex$E $(SRC)
716724
$** > $@
717725
@@ -891,12 +899,12 @@
891899
# generate the index source, containing all web references,..
892900
page_index.h: $(TRANSLATEDSRC) mkindex.exe
893901
mkindex.exe $(TRANSLATEDSRC) >$@
894902
895903
# 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 > $@
898906
899907
# generate the simplified headers
900908
headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
901909
makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
902910
echo Done >$@
903911
--- 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 @@
859859
int a, b;
860860
do{
861861
a = *zA++;
862862
b = *zB++;
863863
}while( a==b && a!=0 );
864
- return a - b;
864
+ return ((unsigned char)a) - (unsigned char)b;
865865
}
866866
}
867867
868868
/*
869869
** Case insensitive string comparison.
870870
--- 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 @@
882882
}
883883
884884
/*
885885
** COMMAND: deconstruct
886886
**
887
-** Usage %fossil deconstruct ?OPTIONS? DESTIONATION
887
+** Usage %fossil deconstruct ?OPTIONS? DESTINATION
888888
**
889889
** Options:
890890
** -R|--repository REPOSITORY
891891
** -L|--prefixlength N
892892
**
893893
--- 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 @@
650650
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651651
** [sqlite_version()] and [sqlite_source_id()].
652652
*/
653653
#define SQLITE_VERSION "3.7.7"
654654
#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"
656656
657657
/*
658658
** CAPI3REF: Run-Time Library Version Numbers
659659
** KEYWORDS: sqlite3_version, sqlite3_sourceid
660660
**
@@ -851,11 +851,11 @@
851851
** semicolon-separate SQL statements passed into its 2nd argument,
852852
** in the context of the [database connection] passed in as its 1st
853853
** argument. ^If the callback function of the 3rd argument to
854854
** sqlite3_exec() is not NULL, then it is invoked for each result row
855855
** 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
857857
** callback invocation. ^If the callback pointer to sqlite3_exec()
858858
** is NULL, then no callback is ever invoked and result rows are
859859
** ignored.
860860
**
861861
** ^If an error occurs while evaluating the SQL statements passed into
@@ -1443,11 +1443,11 @@
14431443
** The xSleep() method causes the calling thread to sleep for at
14441444
** least the number of microseconds given. ^The xCurrentTime()
14451445
** method returns a Julian Day Number for the current date and time as
14461446
** a floating point value.
14471447
** ^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
14491449
** a 24-hour day).
14501450
** ^SQLite will use the xCurrentTimeInt64() method to get the current
14511451
** date and time if that method is available (if iVersion is 2 or
14521452
** greater and the function pointer is not NULL) and will fall back
14531453
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
@@ -1881,11 +1881,11 @@
18811881
** scratch memory beyond what is provided by this configuration option, then
18821882
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
18831883
**
18841884
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
18851885
** <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.
18871887
** This configuration should not be used if an application-define page
18881888
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
18891889
** There are three arguments to this option: A pointer to 8-byte aligned
18901890
** memory, the size of each page buffer (sz), and the number of pages (N).
18911891
** The sz argument should be the size of the largest database page
@@ -2979,16 +2979,16 @@
29792979
** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
29802980
**
29812981
** ^If [URI filename] interpretation is enabled, and the filename argument
29822982
** begins with "file:", then the filename is interpreted as a URI. ^URI
29832983
** 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
29852985
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
29862986
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
29872987
** As of SQLite version 3.7.7, URI filename interpretation is turned off
29882988
** 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
29902990
** information.
29912991
**
29922992
** URI filenames are parsed according to RFC 3986. ^If the URI contains an
29932993
** authority, then it must be either an empty string or the string
29942994
** "localhost". ^If the authority is not an empty string or "localhost", an
@@ -3803,11 +3803,11 @@
38033803
** [extended result codes] might be returned as well.
38043804
**
38053805
** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
38063806
** database locks it needs to do its job. ^If the statement is a [COMMIT]
38073807
** 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
38093809
** explicit transaction then you should rollback the transaction before
38103810
** continuing.
38113811
**
38123812
** ^[SQLITE_DONE] means that the statement has finished executing
38133813
** successfully. sqlite3_step() should not be called again on this virtual
@@ -4082,11 +4082,11 @@
40824082
40834083
/*
40844084
** CAPI3REF: Destroy A Prepared Statement Object
40854085
**
40864086
** ^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
40884088
** or if the statement is never been evaluated, then sqlite3_finalize() returns
40894089
** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
40904090
** sqlite3_finalize(S) returns the appropriate [error code] or
40914091
** [extended error code].
40924092
**
@@ -5996,11 +5996,11 @@
59965996
** versions of these routines, it should at least provide stubs that always
59975997
** return true so that one does not get spurious assertion failures.
59985998
**
59995999
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
60006000
** 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
60026002
** the reason the mutex does not exist is because the build is not
60036003
** using mutexes. And we do not want the assert() containing the
60046004
** call to sqlite3_mutex_held() to fail, so a non-zero return is
60056005
** the appropriate thing to do. ^The sqlite3_mutex_notheld()
60066006
** interface should also return 1 when given a NULL pointer.
@@ -6119,11 +6119,12 @@
61196119
#define SQLITE_TESTCTRL_RESERVE 14
61206120
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
61216121
#define SQLITE_TESTCTRL_ISKEYWORD 16
61226122
#define SQLITE_TESTCTRL_PGHDRSZ 17
61236123
#define SQLITE_TESTCTRL_SCRATCHMALLOC 18
6124
-#define SQLITE_TESTCTRL_LAST 18
6124
+#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19
6125
+#define SQLITE_TESTCTRL_LAST 19
61256126
61266127
/*
61276128
** CAPI3REF: SQLite Runtime Status
61286129
**
61296130
** ^This interface is used to retrieve runtime status information
@@ -6505,11 +6506,11 @@
65056506
** [[the xFetch() page cache methods]]
65066507
** The xFetch() method locates a page in the cache and returns a pointer to
65076508
** the page, or a NULL pointer.
65086509
** A "page", in this context, means a buffer of szPage bytes aligned at an
65096510
** 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
65116512
** is considered to be "pinned".
65126513
**
65136514
** If the requested page is already in the page cache, then the page cache
65146515
** implementation must return a pointer to the page buffer with its content
65156516
** intact. If the requested page is not already in the cache, then the
@@ -9556,10 +9557,11 @@
95569557
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
95579558
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
95589559
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
95599560
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
95609561
#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */
9562
+#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */
95619563
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
95629564
95639565
/*
95649566
** Possible values for the sqlite.magic field.
95659567
** The numbers are obtained at random and have no special meaning, other
@@ -11053,10 +11055,11 @@
1105311055
int isPCacheInit; /* True after malloc is initialized */
1105411056
sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
1105511057
int nRefInitMutex; /* Number of users of pInitMutex */
1105611058
void (*xLog)(void*,int,const char*); /* Function for logging */
1105711059
void *pLogArg; /* First argument to xLog() */
11060
+ int bLocaltimeFault; /* True to fail localtime() calls */
1105811061
};
1105911062
1106011063
/*
1106111064
** Context pointer passed down through the tree-walk.
1106211065
*/
@@ -12013,10 +12016,11 @@
1201312016
0, /* isPCacheInit */
1201412017
0, /* pInitMutex */
1201512018
0, /* nRefInitMutex */
1201612019
0, /* xLog */
1201712020
0, /* pLogArg */
12021
+ 0, /* bLocaltimeFault */
1201812022
};
1201912023
1202012024
1202112025
/*
1202212026
** Hash table for global functions - functions common to all
@@ -13163,26 +13167,10 @@
1316313167
*/
1316413168
#include <time.h>
1316513169
1316613170
#ifndef SQLITE_OMIT_DATETIME_FUNCS
1316713171
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
1318413172
1318513173
/*
1318613174
** A structure for holding a single date and time.
1318713175
*/
1318813176
typedef struct DateTime DateTime;
@@ -13523,20 +13511,90 @@
1352313511
static void clearYMD_HMS_TZ(DateTime *p){
1352413512
p->validYMD = 0;
1352513513
p->validHMS = 0;
1352613514
p->validTZ = 0;
1352713515
}
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
+
1352813574
1352913575
#ifndef SQLITE_OMIT_LOCALTIME
1353013576
/*
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.
1353413583
*/
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
+){
1353613589
DateTime x, y;
1353713590
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
+
1353813596
x = *p;
1353913597
computeYMD_HMS(&x);
1354013598
if( x.Y<1971 || x.Y>=2038 ){
1354113599
x.Y = 2000;
1354213600
x.M = 1;
@@ -13550,51 +13608,27 @@
1355013608
}
1355113609
x.tz = 0;
1355213610
x.validJD = 0;
1355313611
computeJD(&x);
1355413612
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;
1359113624
y.validYMD = 1;
1359213625
y.validHMS = 1;
1359313626
y.validJD = 0;
1359413627
y.validTZ = 0;
1359513628
computeJD(&y);
13629
+ *pRc = SQLITE_OK;
1359613630
return y.iJD - x.iJD;
1359713631
}
1359813632
#endif /* SQLITE_OMIT_LOCALTIME */
1359913633
1360013634
/*
@@ -13614,13 +13648,16 @@
1361413648
** weekday N
1361513649
** unixepoch
1361613650
** localtime
1361713651
** utc
1361813652
**
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.
1362013657
*/
13621
-static int parseModifier(const char *zMod, DateTime *p){
13658
+static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
1362213659
int rc = 1;
1362313660
int n;
1362413661
double r;
1362513662
char *z, zBuf[30];
1362613663
z = zBuf;
@@ -13636,13 +13673,12 @@
1363613673
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
1363713674
** show local time.
1363813675
*/
1363913676
if( strcmp(z, "localtime")==0 ){
1364013677
computeJD(p);
13641
- p->iJD += localtimeOffset(p);
13678
+ p->iJD += localtimeOffset(p, pCtx, &rc);
1364213679
clearYMD_HMS_TZ(p);
13643
- rc = 0;
1364413680
}
1364513681
break;
1364613682
}
1364713683
#endif
1364813684
case 'u': {
@@ -13659,15 +13695,16 @@
1365913695
}
1366013696
#ifndef SQLITE_OMIT_LOCALTIME
1366113697
else if( strcmp(z, "utc")==0 ){
1366213698
sqlite3_int64 c1;
1366313699
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
+ }
1366913706
}
1367013707
#endif
1367113708
break;
1367213709
}
1367313710
case 'w': {
@@ -13844,13 +13881,12 @@
1384413881
if( !z || parseDateOrTime(context, (char*)z, p) ){
1384513882
return 1;
1384613883
}
1384713884
}
1384813885
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;
1385213888
}
1385313889
return 0;
1385413890
}
1385513891
1385613892
@@ -24364,10 +24400,14 @@
2436424400
2436524401
#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
2436624402
# include <sys/mount.h>
2436724403
#endif
2436824404
24405
+#ifdef HAVE_UTIME
24406
+# include <utime.h>
24407
+#endif
24408
+
2436924409
/*
2437024410
** Allowed values of unixFile.fsFlags
2437124411
*/
2437224412
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
2437324413
@@ -26369,12 +26409,14 @@
2636926409
/* If we have any lock, then the lock file already exists. All we have
2637026410
** to do is adjust our internal record of the lock level.
2637126411
*/
2637226412
if( pFile->eFileLock > NO_LOCK ){
2637326413
pFile->eFileLock = eFileLock;
26374
-#if !OS_VXWORKS
2637526414
/* Always update the timestamp on the old file */
26415
+#ifdef HAVE_UTIME
26416
+ utime(zLockFile, NULL);
26417
+#else
2637626418
utimes(zLockFile, NULL);
2637726419
#endif
2637826420
return SQLITE_OK;
2637926421
}
2638026422
@@ -28096,11 +28138,11 @@
2809628138
unixShmNode *p = pFd->pInode->pShmNode;
2809728139
assert( unixMutexHeld() );
2809828140
if( p && p->nRef==0 ){
2809928141
int i;
2810028142
assert( p->pInode==pFd->pInode );
28101
- if( p->mutex ) sqlite3_mutex_free(p->mutex);
28143
+ sqlite3_mutex_free(p->mutex);
2810228144
for(i=0; i<p->nRegion; i++){
2810328145
if( p->h>=0 ){
2810428146
munmap(p->apRegion[i], p->szRegion);
2810528147
}else{
2810628148
sqlite3_free(p->apRegion[i]);
@@ -32254,11 +32296,12 @@
3225432296
rc = 1;
3225532297
}
3225632298
}
3225732299
3225832300
if( rc ){
32259
- if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
32301
+ if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
32302
+ || ( pFile->lastErrno==ERROR_DISK_FULL )){
3226032303
return SQLITE_FULL;
3226132304
}
3226232305
return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
3226332306
}
3226432307
return SQLITE_OK;
@@ -61205,10 +61248,18 @@
6120561248
rc = db->errCode = p->rc;
6120661249
}
6120761250
return (rc&db->errMask);
6120861251
}
6120961252
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
+
6121061261
/*
6121161262
** This is the top-level implementation of sqlite3_step(). Call
6121261263
** sqlite3Step() to do most of the work. If a schema error occurs,
6121361264
** call sqlite3Reprepare() and try again.
6121461265
*/
@@ -61223,11 +61274,11 @@
6122361274
return SQLITE_MISUSE_BKPT;
6122461275
}
6122561276
db = v->db;
6122661277
sqlite3_mutex_enter(db->mutex);
6122761278
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
61228
- && cnt++ < 5
61279
+ && cnt++ < SQLITE_MAX_SCHEMA_RETRY
6122961280
&& (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
6123061281
sqlite3_reset(pStmt);
6123161282
v->expired = 0;
6123261283
}
6123361284
if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
@@ -63496,11 +63547,11 @@
6349663547
break;
6349763548
}
6349863549
6349963550
/* Opcode: HaltIfNull P1 P2 P3 P4 *
6350063551
**
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
6350263553
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
6350363554
** value in register P3 is not NULL, then this routine is a no-op.
6350463555
*/
6350563556
case OP_HaltIfNull: { /* in3 */
6350663557
pIn3 = &aMem[pOp->p3];
@@ -64433,11 +64484,11 @@
6443364484
** additional information.
6443464485
**
6443564486
** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
6443664487
** true or false and is never NULL. If both operands are NULL then the result
6443764488
** 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
6443964490
** the SQLITE_NULLEQ flag were omitted from P5.
6444064491
*/
6444164492
/* Opcode: Eq P1 P2 P3 P4 P5
6444264493
**
6444364494
** This works just like the Lt opcode except that the jump is taken if
@@ -64445,11 +64496,11 @@
6444564496
** See the Lt opcode for additional information.
6444664497
**
6444764498
** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
6444864499
** true or false and is never NULL. If both operands are NULL then the result
6444964500
** 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
6445164502
** the SQLITE_NULLEQ flag were omitted from P5.
6445264503
*/
6445364504
/* Opcode: Le P1 P2 P3 P4 P5
6445464505
**
6445564506
** This works just like the Lt opcode except that the jump is taken if
@@ -64730,17 +64781,17 @@
6473064781
break;
6473164782
}
6473264783
6473364784
/* Opcode: If P1 P2 P3 * *
6473464785
**
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
6473664787
** is considered true if it is numeric and non-zero. If the value
6473764788
** in P1 is NULL then take the jump if P3 is true.
6473864789
*/
6473964790
/* Opcode: IfNot P1 P2 P3 * *
6474064791
**
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
6474264793
** is considered true if it has a numeric value of zero. If the value
6474364794
** in P1 is NULL then take the jump if P3 is true.
6474464795
*/
6474564796
case OP_If: /* jump, in1 */
6474664797
case OP_IfNot: { /* jump, in1 */
@@ -66390,11 +66441,11 @@
6639066441
break;
6639166442
}
6639266443
6639366444
/* Opcode: NotExists P1 P2 P3 * *
6639466445
**
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
6639666447
** with that key does not exist in table of P1, then jump to P2.
6639766448
** If the record does exist, then fall through. The cursor is left
6639866449
** pointing to the record if it exists.
6639966450
**
6640066451
** The difference between this operation and NotFound is that this
@@ -66468,11 +66519,11 @@
6646866519
** written to register P2.
6646966520
**
6647066521
** If P3>0 then P3 is a register in the root frame of this VDBE that holds
6647166522
** the largest previously generated record number. No new record numbers are
6647266523
** 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 '
6647466525
** generated record number. This P3 mechanism is used to help implement the
6647566526
** AUTOINCREMENT feature.
6647666527
*/
6647766528
case OP_NewRowid: { /* out2-prerelease */
6647866529
#if 0 /* local variables moved into u.be */
@@ -67110,11 +67161,11 @@
6711067161
break;
6711167162
}
6711267163
6711367164
/* Opcode: IdxInsert P1 P2 P3 * P5
6711467165
**
67115
-** Register P2 holds a SQL index key made using the
67166
+** Register P2 holds an SQL index key made using the
6711667167
** MakeRecord instructions. This opcode writes that key
6711767168
** into the index P1. Data for the entry is nil.
6711867169
**
6711967170
** P3 is a flag that provides a hint to the b-tree layer that this
6712067171
** insert is likely to be an append.
@@ -82135,12 +82186,18 @@
8213582186
sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
8213682187
sqlite3ColumnDefault(v, pTab, idx, -1);
8213782188
}
8213882189
}
8213982190
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
+ }
8214082197
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
82141
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
82198
+ sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
8214282199
}
8214382200
sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
8214482201
return regBase;
8214582202
}
8214682203
@@ -110763,10 +110820,21 @@
110763110820
if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
110764110821
sqlite3ScratchFree(pFree);
110765110822
break;
110766110823
}
110767110824
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
+
110768110836
}
110769110837
va_end(ap);
110770110838
#endif /* SQLITE_OMIT_BUILTIN_TEST */
110771110839
return rc;
110772110840
}
@@ -111420,16 +111488,10 @@
111420111488
** TODO(shess) Provide a VACUUM type operation to clear out all
111421111489
** deletions and duplications. This would basically be a forced merge
111422111490
** into a single segment.
111423111491
*/
111424111492
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
-
111431111493
/************** Include fts3Int.h in the middle of fts3.c ********************/
111432111494
/************** Begin file fts3Int.h *****************************************/
111433111495
/*
111434111496
** 2009 Nov 12
111435111497
**
@@ -111441,18 +111503,27 @@
111441111503
** May you share freely, never taking more than you give.
111442111504
**
111443111505
******************************************************************************
111444111506
**
111445111507
*/
111446
-
111447111508
#ifndef _FTSINT_H
111448111509
#define _FTSINT_H
111449111510
111450111511
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
111451111512
# define NDEBUG 1
111452111513
#endif
111453111514
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
111454111525
/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
111455111526
/************** Begin file fts3_tokenizer.h **********************************/
111456111527
/*
111457111528
** 2006 July 10
111458111529
**
@@ -111940,11 +112011,11 @@
111940112011
char *aDoclist; /* List of docids for full-text queries */
111941112012
int nDoclist; /* Size of buffer at aDoclist */
111942112013
u8 bDesc; /* True to sort in descending order */
111943112014
int eEvalmode; /* An FTS3_EVAL_XX constant */
111944112015
int nRowAvg; /* Average size of database rows, in pages */
111945
- int nDoc; /* Documents in table */
112016
+ sqlite3_int64 nDoc; /* Documents in table */
111946112017
111947112018
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
111948112019
u32 *aMatchinfo; /* Information about most recent match */
111949112020
int nMatchinfo; /* Number of elements in aMatchinfo[] */
111950112021
char *zMatchinfo; /* Matchinfo specification */
@@ -111997,19 +112068,19 @@
111997112068
int isPrefix; /* True if token ends with a "*" character */
111998112069
111999112070
/* Variables above this point are populated when the expression is
112000112071
** parsed (by code in fts3_expr.c). Below this point the variables are
112001112072
** used when evaluating the expression. */
112002
- int bFulltext; /* True if full-text index was used */
112003112073
Fts3DeferredToken *pDeferred; /* Deferred token object for this token */
112004112074
Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */
112005112075
};
112006112076
112007112077
struct Fts3Phrase {
112008112078
/* Cache of doclist for this phrase. */
112009112079
Fts3Doclist doclist;
112010112080
int bIncr; /* True if doclist is loaded incrementally */
112081
+ int iDoclistToken;
112011112082
112012112083
/* Variables below this point are populated by fts3_expr.c when parsing
112013112084
** a MATCH expression. Everything above is part of the evaluation phase.
112014112085
*/
112015112086
int nToken; /* Number of tokens in the phrase */
@@ -112130,10 +112201,11 @@
112130112201
Fts3SegFilter *pFilter; /* Pointer to filter object */
112131112202
char *aBuffer; /* Buffer to merge doclists in */
112132112203
int nBuffer; /* Allocated size of aBuffer[] in bytes */
112133112204
112134112205
int iColFilter; /* If >=0, filter for this column */
112206
+ int bRestart;
112135112207
112136112208
/* Used by fts3.c only. */
112137112209
int nCost; /* Cost of running iterator */
112138112210
int bLookup; /* True if a lookup of a single entry. */
112139112211
@@ -112199,18 +112271,24 @@
112199112271
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
112200112272
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
112201112273
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
112202112274
SQLITE_PRIVATE char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol);
112203112275
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
112276
+SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
112204112277
112205112278
SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
112206112279
112207
-
112280
+#endif /* SQLITE_ENABLE_FTS3 */
112208112281
#endif /* _FTSINT_H */
112209112282
112210112283
/************** End of fts3Int.h *********************************************/
112211112284
/************** 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
112212112290
112213112291
112214112292
#ifndef SQLITE_CORE
112215112293
SQLITE_EXTENSION_INIT1
112216112294
#endif
@@ -112545,10 +112623,13 @@
112545112623
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
112546112624
if( rc==SQLITE_OK ){
112547112625
sqlite3_step(pStmt);
112548112626
p->nPgsz = sqlite3_column_int(pStmt, 0);
112549112627
rc = sqlite3_finalize(pStmt);
112628
+ }else if( rc==SQLITE_AUTH ){
112629
+ p->nPgsz = 1024;
112630
+ rc = SQLITE_OK;
112550112631
}
112551112632
}
112552112633
assert( p->nPgsz>0 || rc!=SQLITE_OK );
112553112634
sqlite3_free(zSql);
112554112635
*pRc = rc;
@@ -112995,11 +113076,11 @@
112995113076
zCsr += nDb;
112996113077
112997113078
/* Fill in the azColumn array */
112998113079
for(iCol=0; iCol<nCol; iCol++){
112999113080
char *z;
113000
- int n;
113081
+ int n = 0;
113001113082
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
113002113083
memcpy(zCsr, z, n);
113003113084
zCsr[n] = '\0';
113004113085
sqlite3Fts3Dequote(zCsr);
113005113086
p->azColumn[iCol] = zCsr;
@@ -114581,12 +114662,12 @@
114581114662
114582114663
/*
114583114664
** Implementation of xBegin() method. This is a no-op.
114584114665
*/
114585114666
static int fts3BeginMethod(sqlite3_vtab *pVtab){
114586
- UNUSED_PARAMETER(pVtab);
114587114667
TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
114668
+ UNUSED_PARAMETER(pVtab);
114588114669
assert( p->pSegments==0 );
114589114670
assert( p->nPendingData==0 );
114590114671
assert( p->inTransaction!=1 );
114591114672
TESTONLY( p->inTransaction = 1 );
114592114673
TESTONLY( p->mxSavepoint = -1; );
@@ -114597,12 +114678,12 @@
114597114678
** Implementation of xCommit() method. This is a no-op. The contents of
114598114679
** the pending-terms hash-table have already been flushed into the database
114599114680
** by fts3SyncMethod().
114600114681
*/
114601114682
static int fts3CommitMethod(sqlite3_vtab *pVtab){
114602
- UNUSED_PARAMETER(pVtab);
114603114683
TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
114684
+ UNUSED_PARAMETER(pVtab);
114604114685
assert( p->nPendingData==0 );
114605114686
assert( p->inTransaction!=0 );
114606114687
assert( p->pSegments==0 );
114607114688
TESTONLY( p->inTransaction = 0 );
114608114689
TESTONLY( p->mxSavepoint = -1; );
@@ -115083,75 +115164,105 @@
115083115164
if( rc!=SQLITE_OK ){
115084115165
*pRc = rc;
115085115166
return;
115086115167
}
115087115168
}
115169
+ assert( pExpr->pPhrase->iDoclistToken==0 );
115170
+ pExpr->pPhrase->iDoclistToken = -1;
115088115171
}else{
115089115172
*pnOr += (pExpr->eType==FTSQUERY_OR);
115090115173
fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc);
115091115174
fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc);
115092115175
}
115093115176
}
115094115177
}
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
+}
115095115232
115096115233
static int fts3EvalPhraseLoad(
115097115234
Fts3Cursor *pCsr,
115098115235
Fts3Phrase *p
115099115236
){
115100115237
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
115101115238
int iToken;
115102115239
int rc = SQLITE_OK;
115103115240
115104
- char *aDoclist = 0;
115105
- int nDoclist = 0;
115106
- int iPrev = -1;
115107
-
115108115241
for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){
115109115242
Fts3PhraseToken *pToken = &p->aToken[iToken];
115110
- assert( pToken->pSegcsr || pToken->pDeferred );
115243
+ assert( pToken->pDeferred==0 || pToken->pSegcsr==0 );
115111115244
115112
- if( pToken->pDeferred==0 ){
115245
+ if( pToken->pSegcsr ){
115113115246
int nThis = 0;
115114115247
char *pThis = 0;
115115115248
rc = fts3TermSelect(pTab, pToken, p->iColumn, 1, &nThis, &pThis);
115116115249
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
+
115145115256
return rc;
115146115257
}
115147115258
115148115259
static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
115149115260
int iToken;
115150115261
int rc = SQLITE_OK;
115151115262
115152
- int nMaxUndeferred = -1;
115263
+ int nMaxUndeferred = pPhrase->iDoclistToken;
115153115264
char *aPoslist = 0;
115154115265
int nPoslist = 0;
115155115266
int iPrev = -1;
115156115267
115157115268
assert( pPhrase->doclist.bFreeList==0 );
@@ -115192,12 +115303,10 @@
115192115303
pPhrase->doclist.nList = 0;
115193115304
return SQLITE_OK;
115194115305
}
115195115306
}
115196115307
iPrev = iToken;
115197
- }else{
115198
- nMaxUndeferred = iToken;
115199115308
}
115200115309
}
115201115310
115202115311
if( iPrev>=0 ){
115203115312
if( nMaxUndeferred<0 ){
@@ -115252,13 +115361,15 @@
115252115361
static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){
115253115362
int rc;
115254115363
Fts3PhraseToken *pFirst = &p->aToken[0];
115255115364
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
115256115365
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
115260115371
){
115261115372
/* Use the incremental approach. */
115262115373
int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
115263115374
rc = sqlite3Fts3MsrIncrStart(
115264115375
pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
@@ -115394,11 +115505,11 @@
115394115505
** with this case by advancing pIter past the zero-padding added by
115395115506
** fts3EvalNearTrim2(). */
115396115507
while( pIter<pEnd && *pIter==0 ) pIter++;
115397115508
115398115509
pDL->pNextDocid = pIter;
115399
- assert( *pIter || pIter>=&pDL->aAll[pDL->nAll] );
115510
+ assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter );
115400115511
*pbEof = 0;
115401115512
}
115402115513
}
115403115514
115404115515
return rc;
@@ -115425,17 +115536,18 @@
115425115536
pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
115426115537
}
115427115538
}
115428115539
}
115429115540
115430
-
115431115541
typedef struct Fts3TokenAndCost Fts3TokenAndCost;
115432115542
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;
115435115547
int nOvfl;
115436
- int iCol;
115548
+ int iCol; /* The column the token must match */
115437115549
};
115438115550
115439115551
static void fts3EvalTokenCosts(
115440115552
Fts3Cursor *pCsr,
115441115553
Fts3Expr *pRoot,
@@ -115448,10 +115560,12 @@
115448115560
if( pExpr->eType==FTSQUERY_PHRASE ){
115449115561
Fts3Phrase *pPhrase = pExpr->pPhrase;
115450115562
int i;
115451115563
for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
115452115564
Fts3TokenAndCost *pTC = (*ppTC)++;
115565
+ pTC->pPhrase = pPhrase;
115566
+ pTC->iToken = i;
115453115567
pTC->pRoot = pRoot;
115454115568
pTC->pToken = &pPhrase->aToken[i];
115455115569
pTC->iCol = pPhrase->iColumn;
115456115570
*pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
115457115571
}
@@ -115560,23 +115674,19 @@
115560115674
/* At this point pTC points to the cheapest remaining token. */
115561115675
if( ii==0 ){
115562115676
if( pTC->nOvfl ){
115563115677
nDocEst = (pTC->nOvfl * pTab->nPgsz + pTab->nPgsz) / 10;
115564115678
}else{
115565
- /* TODO: Fix this so that the doclist need not be read twice. */
115566115679
Fts3PhraseToken *pToken = pTC->pToken;
115567115680
int nList = 0;
115568115681
char *pList = 0;
115569115682
rc = fts3TermSelect(pTab, pToken, pTC->iCol, 1, &nList, &pList);
115683
+ assert( rc==SQLITE_OK || pList==0 );
115684
+
115570115685
if( rc==SQLITE_OK ){
115571115686
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);
115578115688
}
115579115689
}
115580115690
}else{
115581115691
if( pTC->nOvfl>=(nDocEst*nDocSize) ){
115582115692
Fts3PhraseToken *pToken = pTC->pToken;
@@ -116032,17 +116142,18 @@
116032116142
Fts3Phrase *pPhrase = pExpr->pPhrase;
116033116143
116034116144
if( pPhrase ){
116035116145
fts3EvalZeroPoslist(pPhrase);
116036116146
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);
116043116151
}
116152
+
116153
+ pPhrase->doclist.pNextDocid = 0;
116154
+ pPhrase->doclist.iDocid = 0;
116044116155
}
116045116156
116046116157
pExpr->iDocid = 0;
116047116158
pExpr->bEof = 0;
116048116159
pExpr->bStart = 0;
@@ -116225,12 +116336,12 @@
116225116336
int iCol;
116226116337
116227116338
if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){
116228116339
assert( pCsr->nDoc>0 );
116229116340
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;
116232116343
}
116233116344
}else{
116234116345
rc = fts3EvalGatherStats(pCsr, pExpr);
116235116346
if( rc==SQLITE_OK ){
116236116347
assert( pExpr->aMI );
@@ -116334,11 +116445,10 @@
116334116445
** May you share freely, never taking more than you give.
116335116446
**
116336116447
******************************************************************************
116337116448
**
116338116449
*/
116339
-
116340116450
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
116341116451
116342116452
116343116453
typedef struct Fts3auxTable Fts3auxTable;
116344116454
typedef struct Fts3auxCursor Fts3auxCursor;
@@ -118168,11 +118278,10 @@
118168118278
*/
118169118279
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
118170118280
118171118281
118172118282
118173
-
118174118283
/*
118175118284
** Class derived from sqlite3_tokenizer
118176118285
*/
118177118286
typedef struct porter_tokenizer {
118178118287
sqlite3_tokenizer base; /* Base class */
@@ -118808,15 +118917,15 @@
118808118917
** (in which case SQLITE_CORE is not defined), or
118809118918
**
118810118919
** * The FTS3 module is being built into the core of
118811118920
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
118812118921
*/
118813
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
118814
-
118815118922
#ifndef SQLITE_CORE
118816118923
SQLITE_EXTENSION_INIT1
118817118924
#endif
118925
+
118926
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
118818118927
118819118928
118820118929
/*
118821118930
** Implementation of the SQL scalar function for accessing the underlying
118822118931
** hash table. This function may be called as follows:
@@ -118937,11 +119046,11 @@
118937119046
sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */
118938119047
char **pzErr /* OUT: Set to malloced error message */
118939119048
){
118940119049
int rc;
118941119050
char *z = (char *)zArg;
118942
- int n;
119051
+ int n = 0;
118943119052
char *zCopy;
118944119053
char *zEnd; /* Pointer to nul-term of zCopy */
118945119054
sqlite3_tokenizer_module *m;
118946119055
118947119056
zCopy = sqlite3_mprintf("%s", zArg);
@@ -119299,11 +119408,10 @@
119299119408
**
119300119409
** * The FTS3 module is being built into the core of
119301119410
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
119302119411
*/
119303119412
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
119304
-
119305119413
119306119414
119307119415
119308119416
typedef struct simple_tokenizer {
119309119417
sqlite3_tokenizer base;
@@ -120750,10 +120858,11 @@
120750120858
pReader->pOffsetList = 0;
120751120859
}else{
120752120860
pReader->pOffsetList = p;
120753120861
}
120754120862
}else{
120863
+ char *pEnd = &pReader->aDoclist[pReader->nDoclist];
120755120864
120756120865
/* Pointer p currently points at the first byte of an offset list. The
120757120866
** following block advances it to point one byte past the end of
120758120867
** the same offset list. */
120759120868
while( 1 ){
@@ -120778,17 +120887,19 @@
120778120887
*/
120779120888
if( ppOffsetList ){
120780120889
*ppOffsetList = pReader->pOffsetList;
120781120890
*pnOffsetList = (int)(p - pReader->pOffsetList - 1);
120782120891
}
120892
+
120893
+ while( p<pEnd && *p==0 ) p++;
120783120894
120784120895
/* If there are no more entries in the doclist, set pOffsetList to
120785120896
** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and
120786120897
** Fts3SegReader.pOffsetList to point to the next offset list before
120787120898
** returning.
120788120899
*/
120789
- if( p>=&pReader->aDoclist[pReader->nDoclist] ){
120900
+ if( p>=pEnd ){
120790120901
pReader->pOffsetList = 0;
120791120902
}else{
120792120903
rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX);
120793120904
if( rc==SQLITE_OK ){
120794120905
sqlite3_int64 iDelta;
@@ -120823,11 +120934,11 @@
120823120934
for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){
120824120935
Fts3SegReader *pReader = pMsr->apSegment[ii];
120825120936
if( !fts3SegReaderIsPending(pReader)
120826120937
&& !fts3SegReaderIsRootOnly(pReader)
120827120938
){
120828
- int jj;
120939
+ sqlite3_int64 jj;
120829120940
for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){
120830120941
int nBlob;
120831120942
rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0);
120832120943
if( rc!=SQLITE_OK ) break;
120833120944
if( (nBlob+35)>pgsz ){
@@ -121768,55 +121879,31 @@
121768121879
121769121880
*ppList = pList;
121770121881
*pnList = nList;
121771121882
}
121772121883
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
121779121895
){
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);
121818121905
return SQLITE_OK;
121819121906
}
121820121907
121821121908
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
121822121909
Fts3Table *p, /* Virtual table handle */
@@ -121866,52 +121953,138 @@
121866121953
if( pMsr->iColFilter>=0 ){
121867121954
fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
121868121955
}
121869121956
121870121957
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
+ }
121871121966
*piDocid = iDocid;
121872
- *paPoslist = pList;
121873121967
*pnPoslist = nList;
121874121968
break;
121875121969
}
121876121970
}
121877
-
121878121971
}
121879121972
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
+
121880122000
return SQLITE_OK;
121881122001
}
121882122002
121883122003
SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(
121884122004
Fts3Table *p, /* Virtual table handle */
121885122005
Fts3MultiSegReader *pCsr, /* Cursor object */
121886122006
Fts3SegFilter *pFilter /* Restrictions on range of iteration */
121887122007
){
121888
- int i;
121889
-
121890
- /* Initialize the cursor object */
121891122008
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++){
121902122035
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
+ }
121907122039
}
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
+ }
121910122082
121911122083
return SQLITE_OK;
121912122084
}
122085
+
121913122086
121914122087
SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
121915122088
Fts3Table *p, /* Virtual table handle */
121916122089
Fts3MultiSegReader *pCsr /* Cursor object */
121917122090
){
@@ -121981,13 +122154,18 @@
121981122154
assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
121982122155
if( nMerge==1
121983122156
&& !isIgnoreEmpty
121984122157
&& (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
121985122158
){
121986
- pCsr->aDoclist = apSegment[0]->aDoclist;
121987122159
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;
121989122167
}else{
121990122168
int nDoclist = 0; /* Size of doclist */
121991122169
sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */
121992122170
121993122171
/* The current term of the first nMerge entries in the array
@@ -123725,11 +123903,11 @@
123725123903
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol;
123726123904
break;
123727123905
123728123906
case FTS3_MATCHINFO_NDOC:
123729123907
if( bGlobal ){
123730
- sqlite3_int64 nDoc;
123908
+ sqlite3_int64 nDoc = 0;
123731123909
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0);
123732123910
pInfo->aMatchinfo[0] = (u32)nDoc;
123733123911
}
123734123912
break;
123735123913
@@ -125620,11 +125798,11 @@
125620125798
*/
125621125799
static float cellArea(Rtree *pRtree, RtreeCell *p){
125622125800
float area = 1.0;
125623125801
int ii;
125624125802
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])));
125626125804
}
125627125805
return area;
125628125806
}
125629125807
125630125808
/*
@@ -125633,11 +125811,11 @@
125633125811
*/
125634125812
static float cellMargin(Rtree *pRtree, RtreeCell *p){
125635125813
float margin = 0.0;
125636125814
int ii;
125637125815
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]));
125639125817
}
125640125818
return margin;
125641125819
}
125642125820
125643125821
/*
@@ -125718,11 +125896,11 @@
125718125896
125719125897
if( x2<x1 ){
125720125898
o = 0.0;
125721125899
break;
125722125900
}else{
125723
- o = o * (x2-x1);
125901
+ o = o * (float)(x2-x1);
125724125902
}
125725125903
}
125726125904
overlap += o;
125727125905
}
125728125906
}
@@ -125737,16 +125915,16 @@
125737125915
RtreeCell *pInsert,
125738125916
RtreeCell *aCell,
125739125917
int nCell,
125740125918
int iExclude
125741125919
){
125742
- float before;
125743
- float after;
125920
+ double before;
125921
+ double after;
125744125922
before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
125745125923
cellUnion(pRtree, p, pInsert);
125746125924
after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
125747
- return after-before;
125925
+ return (float)(after-before);
125748125926
}
125749125927
#endif
125750125928
125751125929
125752125930
/*
@@ -125764,15 +125942,15 @@
125764125942
RtreeNode *pNode;
125765125943
rc = nodeAcquire(pRtree, 1, 0, &pNode);
125766125944
125767125945
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
125768125946
int iCell;
125769
- sqlite3_int64 iBest;
125947
+ sqlite3_int64 iBest = 0;
125770125948
125771
- float fMinGrowth;
125772
- float fMinArea;
125773
- float fMinOverlap;
125949
+ float fMinGrowth = 0.0;
125950
+ float fMinArea = 0.0;
125951
+ float fMinOverlap = 0.0;
125774125952
125775125953
int nCell = NCELL(pNode);
125776125954
RtreeCell cell;
125777125955
RtreeNode *pChild;
125778125956
@@ -126198,13 +126376,13 @@
126198126376
){
126199126377
int **aaSorted;
126200126378
int *aSpare;
126201126379
int ii;
126202126380
126203
- int iBestDim;
126204
- int iBestSplit;
126205
- float fBestMargin;
126381
+ int iBestDim = 0;
126382
+ int iBestSplit = 0;
126383
+ float fBestMargin = 0.0;
126206126384
126207126385
int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
126208126386
126209126387
aaSorted = (int **)sqlite3_malloc(nByte);
126210126388
if( !aaSorted ){
@@ -126222,13 +126400,13 @@
126222126400
SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
126223126401
}
126224126402
126225126403
for(ii=0; ii<pRtree->nDim; ii++){
126226126404
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;
126230126408
int nLeft;
126231126409
126232126410
for(
126233126411
nLeft=RTREE_MINCELLS(pRtree);
126234126412
nLeft<=(nCell-RTREE_MINCELLS(pRtree));
@@ -126539,11 +126717,11 @@
126539126717
static int deleteCell(Rtree *, RtreeNode *, int, int);
126540126718
126541126719
static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
126542126720
int rc;
126543126721
int rc2;
126544
- RtreeNode *pParent;
126722
+ RtreeNode *pParent = 0;
126545126723
int iCell;
126546126724
126547126725
assert( pNode->nRef==1 );
126548126726
126549126727
/* Remove the entry in the parent cell. */
@@ -126687,23 +126865,23 @@
126687126865
}else{
126688126866
nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
126689126867
}
126690126868
aOrder[ii] = ii;
126691126869
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]);
126694126872
}
126695126873
}
126696126874
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));
126698126876
}
126699126877
126700126878
for(ii=0; ii<nCell; ii++){
126701126879
aDistance[ii] = 0.0;
126702126880
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]));
126705126883
aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
126706126884
}
126707126885
}
126708126886
126709126887
SortByDistance(aOrder, nCell, aDistance, aSpare);
@@ -126798,14 +126976,14 @@
126798126976
nodeGetCell(pRtree, pNode, ii, &cell);
126799126977
126800126978
/* Find a node to store this cell in. pNode->iNode currently contains
126801126979
** the height of the sub-tree headed by the cell.
126802126980
*/
126803
- rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert);
126981
+ rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert);
126804126982
if( rc==SQLITE_OK ){
126805126983
int rc2;
126806
- rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode);
126984
+ rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode);
126807126985
rc2 = nodeRelease(pRtree, pInsert);
126808126986
if( rc==SQLITE_OK ){
126809126987
rc = rc2;
126810126988
}
126811126989
}
@@ -127190,11 +127368,11 @@
127190127368
int isCreate /* True for xCreate, false for xConnect */
127191127369
){
127192127370
int rc;
127193127371
char *zSql;
127194127372
if( isCreate ){
127195
- int iPageSize;
127373
+ int iPageSize = 0;
127196127374
zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb);
127197127375
rc = getIntFromStmt(db, zSql, &iPageSize);
127198127376
if( rc==SQLITE_OK ){
127199127377
pRtree->iNodeSize = iPageSize-64;
127200127378
if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
@@ -127993,14 +128171,11 @@
127993128171
** May you find forgiveness for yourself and forgive others.
127994128172
** May you share freely, never taking more than you give.
127995128173
**
127996128174
*************************************************************************
127997128175
** 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 $
128000128176
*/
128001
-
128002128177
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
128003128178
#ifdef SQLITE_ENABLE_ICU
128004128179
128005128180
128006128181
#include <unicode/ubrk.h>
128007128182
--- 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 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.7"
111111
#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"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -308,11 +308,11 @@
308308
** semicolon-separate SQL statements passed into its 2nd argument,
309309
** in the context of the [database connection] passed in as its 1st
310310
** argument. ^If the callback function of the 3rd argument to
311311
** sqlite3_exec() is not NULL, then it is invoked for each result row
312312
** 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
314314
** callback invocation. ^If the callback pointer to sqlite3_exec()
315315
** is NULL, then no callback is ever invoked and result rows are
316316
** ignored.
317317
**
318318
** ^If an error occurs while evaluating the SQL statements passed into
@@ -900,11 +900,11 @@
900900
** The xSleep() method causes the calling thread to sleep for at
901901
** least the number of microseconds given. ^The xCurrentTime()
902902
** method returns a Julian Day Number for the current date and time as
903903
** a floating point value.
904904
** ^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
906906
** a 24-hour day).
907907
** ^SQLite will use the xCurrentTimeInt64() method to get the current
908908
** date and time if that method is available (if iVersion is 2 or
909909
** greater and the function pointer is not NULL) and will fall back
910910
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
@@ -1338,11 +1338,11 @@
13381338
** scratch memory beyond what is provided by this configuration option, then
13391339
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
13401340
**
13411341
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
13421342
** <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.
13441344
** This configuration should not be used if an application-define page
13451345
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
13461346
** There are three arguments to this option: A pointer to 8-byte aligned
13471347
** memory, the size of each page buffer (sz), and the number of pages (N).
13481348
** The sz argument should be the size of the largest database page
@@ -2436,16 +2436,16 @@
24362436
** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
24372437
**
24382438
** ^If [URI filename] interpretation is enabled, and the filename argument
24392439
** begins with "file:", then the filename is interpreted as a URI. ^URI
24402440
** 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
24422442
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
24432443
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
24442444
** As of SQLite version 3.7.7, URI filename interpretation is turned off
24452445
** 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
24472447
** information.
24482448
**
24492449
** URI filenames are parsed according to RFC 3986. ^If the URI contains an
24502450
** authority, then it must be either an empty string or the string
24512451
** "localhost". ^If the authority is not an empty string or "localhost", an
@@ -3260,11 +3260,11 @@
32603260
** [extended result codes] might be returned as well.
32613261
**
32623262
** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
32633263
** database locks it needs to do its job. ^If the statement is a [COMMIT]
32643264
** 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
32663266
** explicit transaction then you should rollback the transaction before
32673267
** continuing.
32683268
**
32693269
** ^[SQLITE_DONE] means that the statement has finished executing
32703270
** successfully. sqlite3_step() should not be called again on this virtual
@@ -3539,11 +3539,11 @@
35393539
35403540
/*
35413541
** CAPI3REF: Destroy A Prepared Statement Object
35423542
**
35433543
** ^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
35453545
** or if the statement is never been evaluated, then sqlite3_finalize() returns
35463546
** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
35473547
** sqlite3_finalize(S) returns the appropriate [error code] or
35483548
** [extended error code].
35493549
**
@@ -5453,11 +5453,11 @@
54535453
** versions of these routines, it should at least provide stubs that always
54545454
** return true so that one does not get spurious assertion failures.
54555455
**
54565456
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
54575457
** 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
54595459
** the reason the mutex does not exist is because the build is not
54605460
** using mutexes. And we do not want the assert() containing the
54615461
** call to sqlite3_mutex_held() to fail, so a non-zero return is
54625462
** the appropriate thing to do. ^The sqlite3_mutex_notheld()
54635463
** interface should also return 1 when given a NULL pointer.
@@ -5576,11 +5576,12 @@
55765576
#define SQLITE_TESTCTRL_RESERVE 14
55775577
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
55785578
#define SQLITE_TESTCTRL_ISKEYWORD 16
55795579
#define SQLITE_TESTCTRL_PGHDRSZ 17
55805580
#define SQLITE_TESTCTRL_SCRATCHMALLOC 18
5581
-#define SQLITE_TESTCTRL_LAST 18
5581
+#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19
5582
+#define SQLITE_TESTCTRL_LAST 19
55825583
55835584
/*
55845585
** CAPI3REF: SQLite Runtime Status
55855586
**
55865587
** ^This interface is used to retrieve runtime status information
@@ -5962,11 +5963,11 @@
59625963
** [[the xFetch() page cache methods]]
59635964
** The xFetch() method locates a page in the cache and returns a pointer to
59645965
** the page, or a NULL pointer.
59655966
** A "page", in this context, means a buffer of szPage bytes aligned at an
59665967
** 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
59685969
** is considered to be "pinned".
59695970
**
59705971
** If the requested page is already in the page cache, then the page cache
59715972
** implementation must return a pointer to the page buffer with its content
59725973
** intact. If the requested page is not already in the cache, then the
59735974
--- 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
--- src/stash.c
+++ src/stash.c
@@ -100,10 +100,11 @@
100100
if( rid==0 ){
101101
/* A new file */
102102
blob_read_from_file(&content, zPath);
103103
db_bind_blob(&ins, ":content", &content);
104104
}else if( deleted ){
105
+ blob_zero(&content);
105106
db_bind_null(&ins, ":content");
106107
}else{
107108
/* A modified file */
108109
Blob orig;
109110
Blob disk;
110111
--- 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 @@
731731
zUuid = PD("name","");
732732
zTitle = mprintf("History Of Ticket %h", zUuid);
733733
style_submenu_element("Status", "Status",
734734
"%s/info/%s", g.zTop, zUuid);
735735
style_submenu_element("Check-ins", "Check-ins",
736
- "%s/tkttimeline?name=%s?y=ci", g.zTop, zUuid);
736
+ "%s/tkttimeline?name=%s&amp;y=ci", g.zTop, zUuid);
737737
style_submenu_element("Timeline", "Timeline",
738738
"%s/tkttimeline?name=%s", g.zTop, zUuid);
739739
style_header(zTitle);
740740
free(zTitle);
741741
742742
--- 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&amp;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 @@
182182
" ORDER BY mtime DESC", zTag
183183
);
184184
free(zTag);
185185
pWiki = manifest_get(rid, CFTYPE_WIKI);
186186
if( pWiki ){
187
- while( fossil_isspace(pWiki->zWiki[0]) ) pWiki->zWiki++;
188
- if( pWiki->zWiki[0] ) zBody = pWiki->zWiki;
187
+ zBody = pWiki->zWiki;
189188
}
190189
}
191190
if( !g.isHome ){
192191
if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){
193192
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
@@ -891,10 +890,11 @@
891890
char const *zPageName; /* Name of the wiki page to export */
892891
char const *zFile; /* Name of the output file (0=stdout) */
893892
int rid; /* Artifact ID of the wiki page */
894893
int i; /* Loop counter */
895894
char *zBody = 0; /* Wiki page content */
895
+ Blob body; /* Wiki page content */
896896
Manifest *pWiki = 0; /* Parsed wiki page content */
897897
898898
if( (g.argc!=4) && (g.argc!=5) ){
899899
usage("export PAGENAME ?FILE?");
900900
}
@@ -909,28 +909,16 @@
909909
}
910910
if( zBody==0 ){
911911
fossil_fatal("wiki page [%s] not found",zPageName);
912912
}
913913
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);
932920
manifest_destroy(pWiki);
933921
return;
934922
}else
935923
if( strncmp(g.argv[2],"commit",n)==0
936924
|| strncmp(g.argv[2],"create",n)==0 ){
937925
--- 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 @@
1414
** http://www.hwaci.com/drh/
1515
**
1616
*******************************************************************************
1717
**
1818
** 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.
2021
*/
2122
#include "config.h"
2223
#ifdef _WIN32
2324
/* This code is for win32 only */
24
-#include "winhttp.h"
2525
#include <windows.h>
26
+#include "winhttp.h"
2627
2728
/*
2829
** The HttpRequest structure holds information about each incoming
2930
** HTTP request.
3031
*/
@@ -60,11 +61,11 @@
6061
}
6162
6263
/*
6364
** Process a single incoming HTTP request.
6465
*/
65
-void win32_process_one_http_request(void *pAppData){
66
+static void win32_process_one_http_request(void *pAppData){
6667
HttpRequest *p = (HttpRequest*)pAppData;
6768
FILE *in = 0, *out = 0;
6869
int amt, got;
6970
int wanted = 0;
7071
char *z;
@@ -145,10 +146,11 @@
145146
SOCKET s = INVALID_SOCKET;
146147
SOCKADDR_IN addr;
147148
int idCnt = 0;
148149
int iPort = mnPort;
149150
Blob options;
151
+ char zTmpPath[MAX_PATH];
150152
151153
if( zStopper ) file_delete(zStopper);
152154
blob_zero(&options);
153155
if( zNotFound ){
154156
blob_appendf(&options, " --notfound %s", zNotFound);
@@ -189,31 +191,46 @@
189191
}else{
190192
fossil_fatal("unable to open listening socket on any"
191193
" port in the range %d..%d", mnPort, mxPort);
192194
}
193195
}
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);
195200
fossil_print("Listening for HTTP requests on TCP port %d\n", iPort);
196201
if( zBrowser ){
197202
zBrowser = mprintf(zBrowser, iPort);
198203
fossil_print("Launch webbrowser: %s\n", zBrowser);
199204
fossil_system(zBrowser);
200205
}
201206
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);
202210
for(;;){
203211
SOCKET client;
204212
SOCKADDR_IN client_addr;
205213
HttpRequest *p;
206214
int len = sizeof(client_addr);
215
+ int wsaError;
207216
208217
client = accept(s, (struct sockaddr*)&client_addr, &len);
209
- if( zStopper && file_size(zStopper)>=0 ){
210
- break;
211
- }
212218
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;
215232
}
216233
p = fossil_malloc( sizeof(*p) );
217234
p->id = ++idCnt;
218235
p->s = client;
219236
p->addr = client_addr;
@@ -221,7 +238,625 @@
221238
_beginthread(win32_process_one_http_request, 0, (void*)p);
222239
}
223240
closesocket(s);
224241
WSACleanup();
225242
}
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
+}
226861
227862
#endif /* _WIN32 -- This code is for win32 only */
228863
--- 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
--- test/release-checklist.wiki
+++ test/release-checklist.wiki
@@ -21,10 +21,11 @@
2121
<li> Linux x86
2222
<li> Linux x86_64
2323
<li> Mac x86
2424
<li> Mac x86_64
2525
<li> Windows (mingw)
26
+<li> Windows (vc++)
2627
<li> OpenBSD
2728
</ol>
2829
2930
<li><p>
3031
Run at least one occurrence of the the following commands on every
@@ -56,11 +57,16 @@
5657
5758
<li><p>
5859
Use the release candidate version of fossil in production on the
5960
[http://www.fossil-scm.org/] website for at least 48 hours (without
6061
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.
6166
</ol>
6267
6368
<hr>
6469
6570
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.
6773
--- 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
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -138,12 +138,12 @@
138138
# generate the index source, containing all web references,..
139139
page_index.h: $(TRANSLATEDSRC) mkindex.exe
140140
mkindex.exe $(TRANSLATEDSRC) >$@
141141
142142
# 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 > $@
145145
146146
# generate the simplified headers
147147
headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
148148
makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
149149
echo Done >$@
150150
--- 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
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -73,11 +73,11 @@
7373
$(TCC) -o$@ -c $**
7474
7575
$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
7676
$(TCC) -o$@ -c $**
7777
78
-VERSION.h : version$E $B\manifest.uuid $B\manifest
78
+VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
7979
+$** > $@
8080
8181
page_index.h: mkindex$E $(SRC)
8282
+$** > $@
8383
8484
--- 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
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -361,11 +361,11 @@
361361
# the repository after running the tests.
362362
test: $(APPNAME)
363363
$(TCLSH) test/tester.tcl $(APPNAME)
364364
365365
$(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
367367
368368
EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o
369369
370370
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
371371
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o
@@ -970,14 +970,14 @@
970970
971971
zip.h: $(OBJDIR)/headers
972972
$(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
973973
$(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
974974
975
-$(OBJDIR)/shell.o: $(SRCDIR)/shell.c
975
+$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
976976
$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
977977
978978
$(OBJDIR)/th.o: $(SRCDIR)/th.c
979979
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
980980
981981
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
982982
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
983983
984984
--- 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
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -31,11 +31,11 @@
3131
INCL = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)
3232
3333
CFLAGS = -nologo -MT -O2
3434
BCC = $(CC) $(CFLAGS)
3535
TCC = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL)
36
-LIBS = $(ZLIB) ws2_32.lib $(SSLLIB)
36
+LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
3737
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
3838
3939
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
4040
4141
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 @@
153153
$(BCC) $**
154154
155155
mkindex$E: $(SRCDIR)\mkindex.c
156156
$(BCC) $**
157157
158
-version$E: $B\src\mkversion.c
158
+mkversion$E: $B\src\mkversion.c
159159
$(BCC) $**
160160
161161
$(OX)\shell$O : $(SRCDIR)\shell.c
162162
$(TCC) /Fo$@ /Dmain=sqlite3_shell $(SQLITE_OPTIONS) -c $(SRCDIR)\shell.c
163163
@@ -168,11 +168,11 @@
168168
$(TCC) /Fo$@ -c $**
169169
170170
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
171171
$(TCC) /Fo$@ -c $**
172172
173
-VERSION.h : version$E $B\manifest.uuid $B\manifest
173
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
174174
$** > $@
175175
176176
page_index.h: mkindex$E $(SRC)
177177
$** > $@
178178
179179
--- 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 @@
3333
3434
<li><p>Select a version of of fossil you want to download. Click on its
3535
link. Note that you must successfully log in as "anonymous" in step 1
3636
above in order to see the link to the detailed version information.</p></li>
3737
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
4041
complete source code and download it to your browser.
4142
</ol>
4243
4344
<h2>2.0 Compiling</h2>
4445
45
-<p>Follow these steps to compile on a unix platform
46
-(Linux, *BSD, MacOS, etc):</p>
47
-
4846
<ol>
4947
<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
5250
in the top-level folder of that directory</p></li>
5351
5452
<li><p><b>(Optional:)</b>
5553
Edit the Makefile to set it up like you want. You probably do not
5654
need to do anything. Do not be intimidated: There are less than 10
5755
variables in the makefile that can be changed. The whole Makefile
5856
is only a few dozen lines long and most of those lines are comments.</p>
5957
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> &rarr; 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> &rarr; Use the
66
+mingw makefile: "<b>make -f win/Makefile.mingw</b>"
67
+
68
+<li><p><i>VC++</i> &rarr; 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>
6172
</ol>
6273
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>
7079
7180
<h2>3.0 Installing</h2>
7281
7382
<ol>
7483
<li value="9">
7584
7685
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> &rarr; 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> &rarr; Use the
66 mingw makefile: "<b>make -f win/Makefile.mingw</b>"
67
68 <li><p><i>VC++</i> &rarr; 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
--- 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>
25
3
-Before every checkins:
6
+Before every check-in:
47
5
- 1. <b>fossil diff</b> &rarr; no stray changes
8
+ 1. <b>fossil diff</b> &rarr;
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>
615
716
2. <b>fossil extra</b> &rarr; no unmanaged files need to be added.
817
9
- 3. The checkin will go onto the desired branch.
10
-
11
- 4. "Autosync" is enabled &rarr;
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
+ &rarr; 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.
2279
2380
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> &rarr; no stray changes
 
 
 
 
 
 
6
7 2. <b>fossil extra</b> &rarr; no unmanaged files need to be added.
8
9 3. The checkin will go onto the desired branch.
10
11 4. "Autosync" is enabled &rarr;
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> &rarr;
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> &rarr; no unmanaged files need to be added.
17
18 3. The check-in will go onto the desired branch.
19 &rarr; 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
--- 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
--- www/index.wiki
+++ www/index.wiki
@@ -20,10 +20,12 @@
2020
<li> [./quickstart.wiki | Quick Start]
2121
<li> [./build.wiki | Install]
2222
<li> [../COPYRIGHT-BSD2.txt | License]
2323
<li> [/timeline | Recent changes]
2424
<li> [./faq.wiki | FAQ]
25
+<li> [./contribute.wiki | Contributing]
26
+<li> [./changes.wiki | Change Log]
2527
<li> [./permutedindex.wiki | Doc Index]
2628
<li> Mailing list
2729
<ul>
2830
<li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up]
2931
<li> [http://www.mail-archive.com/[email protected] | archives]
3032
--- 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 @@
5252
7. th.c
5353
8. th.h
5454
5555
These two files are imports like the SQLite source files,
5656
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
5762
5863
The src/ subdirectory also contains documentation about the
5964
makeheaders preprocessor program:
6065
61
- 9. [../src/makeheaders.html | makeheaders.html]
66
+ 10. [../src/makeheaders.html | makeheaders.html]
6267
6368
Click on the link to read this documentation. In addition there is
6469
a [http://www.tcl.tk/ | Tcl] script used to build the various makefiles:
6570
66
- 10. makemake.tcl
71
+ 11. makemake.tcl
6772
6873
Running this Tcl script will automatically regenerate all makefiles.
6974
In order to add a new source file to the Fossil implementation, simply
7075
edit makemake.tcl to add the new filename, then rerun the script, and
7176
all of the makefiles for all targets will be rebuild.
7277
7378
Finally, there is one of the makefiles generated by makemake.tcl:
7479
75
- 11. main.mk
80
+ 12. main.mk
7681
7782
The main.mk makefile is invoked from the Makefile in the top-level
7883
directory. The main.mk is generated by makemake.tcl and should not
7984
be hand edited. Other makefiles generated by makemake.tcl are in
8085
other subdirectories (currently all in the win/ subdirectory).
@@ -89,31 +94,32 @@
8994
9095
<h1>3.0 Automatically generated files</h1>
9196
9297
The "VERSION.h" header file contains some C preprocessor macros that
9398
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.
96102
(The "manifest" and "manifest.uuid" files are automatically generated and
97103
updated by Fossil itself. See the [/help/setting | fossil set manifest]
98104
command for additional information.)
99105
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")
105110
than run:
106111
107112
<blockquote><pre>
108
-version.exe manifest.uuid manifest VERSION.h
113
+mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
109114
</pre></blockquote>
110115
111116
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.
115121
116122
<h1>4.0 Preprocessing</h1>
117123
118124
There are three preprocessors for the Fossil sources. The mkindex
119125
and translate preprocessors can be run in any order. The makeheaders
120126
--- 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 &gt;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 @@
1919
delta_format.wiki {Fossil Delta Format}
2020
embeddeddoc.wiki {Embedded Project Documentation}
2121
event.wiki {Events}
2222
faq.wiki {Frequently Asked Questions}
2323
fileformat.wiki {Fossil File Format}
24
+ foss-cklist.wiki {Checklist For Successful Open-Source Projects}
2425
fossil-v-git.wiki {Fossil Versus Git}
2526
index.wiki {Home Page}
2627
inout.wiki {Import And Export To And From Git}
2728
makefile.wiki {The Fossil Build Process}
2829
password.wiki {Password Management And Authentication}
@@ -47,11 +48,11 @@
4748
webui.wiki {The Fossil Web Interface}
4849
wikitheory.wiki {Wiki In Fossil}
4950
}
5051
5152
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}
5354
foreach {file title} $doclist {
5455
set n [llength $title]
5556
lappend permindex [list $title $file]
5657
for {set i 0} {$i<$n-1} {incr i} {
5758
set prefix [lrange $title 0 $i]
@@ -61,13 +62,14 @@
6162
lappend permindex [list "$suffix &#151; $prefix" $file]
6263
}
6364
}
6465
}
6566
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>"
6971
foreach entry $permindex {
7072
foreach {title file} $entry break
71
- puts "<li><a href=\"$file\">$title</a></li>"
73
+ puts $out "<li><a href=\"$file\">$title</a></li>"
7274
}
73
-puts "</ul>"
75
+puts $out "</ul>"
7476
--- 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 &#151; $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 &#151; $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
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -13,10 +13,11 @@
1313
<li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li>
1414
<li><a href="makefile.wiki">Build Process &#151; The Fossil</a></li>
1515
<li><a href="build.wiki">Building and Installing Fossil</a></li>
1616
<li><a href="checkin_names.wiki">Checkin And Version Names</a></li>
1717
<li><a href="../test/release-checklist.wiki">Checklist &#151; Pre-Release Testing</a></li>
18
+<li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li>
1819
<li><a href="selfcheck.wiki">Checks &#151; Fossil Repository Integrity Self</a></li>
1920
<li><a href="contribute.wiki">Code or Documentation To The Fossil Project &#151; Contributing</a></li>
2021
<li><a href="style.wiki">Code Style Guidelines &#151; Source</a></li>
2122
<li><a href="concepts.wiki">Concepts &#151; Fossil Core</a></li>
2223
<li><a href="server.wiki">Configure A Fossil Server &#151; How To</a></li>
@@ -73,12 +74,12 @@
7374
<li><a href="webui.wiki">Interface &#151; The Fossil Web</a></li>
7475
<li><a href="copyright-release.html">License Agreement &#151; Contributor</a></li>
7576
<li><a href="password.wiki">Management And Authentication &#151; Password</a></li>
7677
<li><a href="branching.wiki">Merging, and Tagging &#151; Branching, Forking,</a></li>
7778
<li><a href="checkin_names.wiki">Names &#151; Checkin And Version</a></li>
79
+<li><a href="foss-cklist.wiki">Open-Source Projects &#151; Checklist For Successful</a></li>
7880
<li><a href="pop.wiki">Operations &#151; Principles Of</a></li>
79
-<li><a href="contribute.wiki">or Documentation To The Fossil Project &#151; Contributing Code</a></li>
8081
<li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &#151; A Technical</a></li>
8182
<li><a href="index.wiki">Page &#151; Home</a></li>
8283
<li><a href="password.wiki">Password Management And Authentication</a></li>
8384
<li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General &#151; Quotes: What</a></li>
8485
<li><a href="stats.wiki">Performance Statistics</a></li>
@@ -86,10 +87,11 @@
8687
<li><a href="pop.wiki">Principles Of Operations</a></li>
8788
<li><a href="private.wiki">Private Branches &#151; Creating, Syncing, and Deleting</a></li>
8889
<li><a href="makefile.wiki">Process &#151; The Fossil Build</a></li>
8990
<li><a href="contribute.wiki">Project &#151; Contributing Code or Documentation To The Fossil</a></li>
9091
<li><a href="embeddeddoc.wiki">Project Documentation &#151; Embedded</a></li>
92
+<li><a href="foss-cklist.wiki">Projects &#151; Checklist For Successful Open-Source</a></li>
9193
<li><a href="sync.wiki">Protocol &#151; The Fossil Sync</a></li>
9294
<li><a href="faq.wiki">Questions &#151; Frequently Asked</a></li>
9395
<li><a href="qandc.wiki">Questions And Criticisms</a></li>
9496
<li><a href="quickstart.wiki">Quick Start Guide &#151; Fossil</a></li>
9597
<li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li>
@@ -103,10 +105,11 @@
103105
<li><a href="style.wiki">Source Code Style Guidelines</a></li>
104106
<li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li>
105107
<li><a href="quickstart.wiki">Start Guide &#151; Fossil Quick</a></li>
106108
<li><a href="stats.wiki">Statistics &#151; Performance</a></li>
107109
<li><a href="style.wiki">Style Guidelines &#151; Source Code</a></li>
110
+<li><a href="foss-cklist.wiki">Successful Open-Source Projects &#151; Checklist For</a></li>
108111
<li><a href="sync.wiki">Sync Protocol &#151; The Fossil</a></li>
109112
<li><a href="private.wiki">Syncing, and Deleting Private Branches &#151; Creating,</a></li>
110113
<li><a href="custom_ticket.wiki">System &#151; Customizing The Ticket</a></li>
111114
<li><a href="branching.wiki">Tagging &#151; Branching, Forking, Merging, and</a></li>
112115
<li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &#151; A</a></li>
113116
--- 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 &#151; 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 &#151; Pre-Release Testing</a></li>
 
18 <li><a href="selfcheck.wiki">Checks &#151; Fossil Repository Integrity Self</a></li>
19 <li><a href="contribute.wiki">Code or Documentation To The Fossil Project &#151; Contributing</a></li>
20 <li><a href="style.wiki">Code Style Guidelines &#151; Source</a></li>
21 <li><a href="concepts.wiki">Concepts &#151; Fossil Core</a></li>
22 <li><a href="server.wiki">Configure A Fossil Server &#151; How To</a></li>
@@ -73,12 +74,12 @@
73 <li><a href="webui.wiki">Interface &#151; The Fossil Web</a></li>
74 <li><a href="copyright-release.html">License Agreement &#151; Contributor</a></li>
75 <li><a href="password.wiki">Management And Authentication &#151; Password</a></li>
76 <li><a href="branching.wiki">Merging, and Tagging &#151; Branching, Forking,</a></li>
77 <li><a href="checkin_names.wiki">Names &#151; Checkin And Version</a></li>
 
78 <li><a href="pop.wiki">Operations &#151; Principles Of</a></li>
79 <li><a href="contribute.wiki">or Documentation To The Fossil Project &#151; Contributing Code</a></li>
80 <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &#151; A Technical</a></li>
81 <li><a href="index.wiki">Page &#151; 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 &#151; 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 &#151; Creating, Syncing, and Deleting</a></li>
88 <li><a href="makefile.wiki">Process &#151; The Fossil Build</a></li>
89 <li><a href="contribute.wiki">Project &#151; Contributing Code or Documentation To The Fossil</a></li>
90 <li><a href="embeddeddoc.wiki">Project Documentation &#151; Embedded</a></li>
 
91 <li><a href="sync.wiki">Protocol &#151; The Fossil Sync</a></li>
92 <li><a href="faq.wiki">Questions &#151; Frequently Asked</a></li>
93 <li><a href="qandc.wiki">Questions And Criticisms</a></li>
94 <li><a href="quickstart.wiki">Quick Start Guide &#151; 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 &#151; Fossil Quick</a></li>
106 <li><a href="stats.wiki">Statistics &#151; Performance</a></li>
107 <li><a href="style.wiki">Style Guidelines &#151; Source Code</a></li>
 
108 <li><a href="sync.wiki">Sync Protocol &#151; The Fossil</a></li>
109 <li><a href="private.wiki">Syncing, and Deleting Private Branches &#151; Creating,</a></li>
110 <li><a href="custom_ticket.wiki">System &#151; Customizing The Ticket</a></li>
111 <li><a href="branching.wiki">Tagging &#151; Branching, Forking, Merging, and</a></li>
112 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &#151; 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 &#151; 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 &#151; 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 &#151; Fossil Repository Integrity Self</a></li>
20 <li><a href="contribute.wiki">Code or Documentation To The Fossil Project &#151; Contributing</a></li>
21 <li><a href="style.wiki">Code Style Guidelines &#151; Source</a></li>
22 <li><a href="concepts.wiki">Concepts &#151; Fossil Core</a></li>
23 <li><a href="server.wiki">Configure A Fossil Server &#151; How To</a></li>
@@ -73,12 +74,12 @@
74 <li><a href="webui.wiki">Interface &#151; The Fossil Web</a></li>
75 <li><a href="copyright-release.html">License Agreement &#151; Contributor</a></li>
76 <li><a href="password.wiki">Management And Authentication &#151; Password</a></li>
77 <li><a href="branching.wiki">Merging, and Tagging &#151; Branching, Forking,</a></li>
78 <li><a href="checkin_names.wiki">Names &#151; Checkin And Version</a></li>
79 <li><a href="foss-cklist.wiki">Open-Source Projects &#151; Checklist For Successful</a></li>
80 <li><a href="pop.wiki">Operations &#151; Principles Of</a></li>
 
81 <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &#151; A Technical</a></li>
82 <li><a href="index.wiki">Page &#151; 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 &#151; 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 &#151; Creating, Syncing, and Deleting</a></li>
89 <li><a href="makefile.wiki">Process &#151; The Fossil Build</a></li>
90 <li><a href="contribute.wiki">Project &#151; Contributing Code or Documentation To The Fossil</a></li>
91 <li><a href="embeddeddoc.wiki">Project Documentation &#151; Embedded</a></li>
92 <li><a href="foss-cklist.wiki">Projects &#151; Checklist For Successful Open-Source</a></li>
93 <li><a href="sync.wiki">Protocol &#151; The Fossil Sync</a></li>
94 <li><a href="faq.wiki">Questions &#151; Frequently Asked</a></li>
95 <li><a href="qandc.wiki">Questions And Criticisms</a></li>
96 <li><a href="quickstart.wiki">Quick Start Guide &#151; 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 &#151; Fossil Quick</a></li>
108 <li><a href="stats.wiki">Statistics &#151; Performance</a></li>
109 <li><a href="style.wiki">Style Guidelines &#151; Source Code</a></li>
110 <li><a href="foss-cklist.wiki">Successful Open-Source Projects &#151; Checklist For</a></li>
111 <li><a href="sync.wiki">Sync Protocol &#151; The Fossil</a></li>
112 <li><a href="private.wiki">Syncing, and Deleting Private Branches &#151; Creating,</a></li>
113 <li><a href="custom_ticket.wiki">System &#151; Customizing The Ticket</a></li>
114 <li><a href="branching.wiki">Tagging &#151; Branching, Forking, Merging, and</a></li>
115 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &#151; A</a></li>
116
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -9,11 +9,11 @@
99
<p>Fossil is a single self-contained C program. You need to
1010
either download a
1111
<a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
1212
or <a href="build.wiki">build it yourself</a> from sources.
1313
Install fossil by putting the fossil binary
14
- someplace on your PATH environment variable.</p>
14
+ someplace on your $PATH.</p>
1515
1616
<a name="fslclone"></a>
1717
<h2>General Work Flow</h2>
1818
1919
<p>Fossil works with repository files (a database with the project's
@@ -20,29 +20,27 @@
2020
complete history) and with checked-out local trees (the working directory
2121
you use to do your work).
2222
The workflow looks like this:</p>
2323
2424
<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
2626
[/help/clone | fossil clone])
2727
<li>Check out a local tree. ([/help/open | fossil open])
2828
<li>Perform operations on the repository (including repository
2929
configuration).
30
- <li><em>Optionally</em> close the local tree.
31
- ([/help/close | fossil close], but this is rarely used.)
3230
</ul>
3331
3432
<p>The following sections will give you a brief overview of these
3533
operations.</p>
3634
3735
<h2>Starting A New Project</h2>
3836
3937
<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>
4139
4240
<blockquote>
43
- <b>fossil new </b><i> repository-filename</i>
41
+ <b>fossil init </b><i> repository-filename</i>
4442
</blockquote>
4543
4644
<h2>Cloning An Existing Repository</h2>
4745
4846
<p>Most fossil operations interact with a repository that is on the
@@ -73,10 +71,19 @@
7371
You can name your repositories anything you want. The ".fossil" suffix
7472
is not required.</p>
7573
7674
<p>Note: If you are behind a restrictive firewall, you might need
7775
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.
7885
7986
<h2>Importing From Another Version Control System</h2>
8087
8188
<p>Rather than start a new project, or clone an existing Fossil project,
8289
you might prefer to
@@ -147,11 +154,12 @@
147154
<p>To add new files to your project, or remove old files, use these
148155
commands:</p>
149156
150157
<blockquote>
151158
<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>
153161
</blockquote>
154162
155163
<p>You can also edit files freely. Once you are ready to commit
156164
your changes, type:</p>
157165
158166
--- 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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button