Index: Dockerfile
==================================================================
--- Dockerfile
+++ Dockerfile
@@ -5,11 +5,11 @@
### Now install some additional parts we will need for the build
RUN dnf update -y && dnf install -y gcc make zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
### If you want to build "trunk", change the next line accordingly.
-ENV FOSSIL_INSTALL_VERSION release
+ENV FOSSIL_INSTALL_VERSION branch-2.2
RUN curl "http://core.tcl.tk/tcl/tarball/tcl-src.tar.gz?name=tcl-src&uuid=release" | tar zx
RUN cd tcl-src/unix && ./configure --prefix=/usr --disable-load && make && make install
RUN curl "http://www.fossil-scm.org/index.html/tarball/fossil-src.tar.gz?name=fossil-src&uuid=${FOSSIL_INSTALL_VERSION}" | tar zx
RUN cd fossil-src && ./configure --disable-fusefs --json --with-th1-docs --with-th1-hooks --with-tcl --with-tcl-stubs --with-tcl-private-stubs
Index: VERSION
==================================================================
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
-2.3
+2.2.1
Index: auto.def
==================================================================
--- auto.def
+++ auto.def
@@ -11,11 +11,11 @@
with-exec-rel-paths=0
=> {Enable relative paths for external diff/gdiff}
with-legacy-mv-rm=0 => {Enable legacy behavior for mv/rm (skip checkout files)}
with-th1-docs=0 => {Enable TH1 for embedded documentation pages}
with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages}
- with-tcl=path => {Enable Tcl integration, with Tcl in the specified path}
+ with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
with-tcl-private-stubs=0
=> {Enable Tcl integration via private stubs mechanism}
with-see=0 => {Enable the SQLite Encryption Extension (SEE)}
internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
Index: autosetup/autosetup
==================================================================
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -59,34 +59,27 @@
if {[getenv WRAPPER ""] eq ""} {
# Invoked directly
set autosetup(srcdir) [pwd]
} else {
# Invoked via the configure wrapper
- set autosetup(srcdir) [file-normalize [file dirname $autosetup(exe)]]
+ set autosetup(srcdir) [file dirname $autosetup(exe)]
}
set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def]
# (c)
set autosetup(builddir) [pwd]
set autosetup(argv) $argv
set autosetup(cmdline) {}
- # options is a list of known options
set autosetup(options) {}
- # optset is a dictionary of option values set by the user based on getopt
- set autosetup(optset) {}
- # optdefault is a dictionary of default values for options
- set autosetup(optdefault) {}
set autosetup(optionhelp) {}
set autosetup(showhelp) 0
# Parse options
use getopt
- # At the is point we don't know what is a valid option
- # We simply parse anything that looks like an option
- set autosetup(getopt) [getopt argv]
+ array set ::useropts [getopt argv]
#"=Core Options:"
options-add {
help:=local => "display help and options. Optionally specify a module name, such as --help=system"
version => "display the version of autosetup"
@@ -101,10 +94,11 @@
quiet
timing
conf:
}
+ #parray ::useropts
if {[opt-bool version]} {
puts $autosetup(version)
exit 0
}
@@ -204,41 +198,20 @@
}
exit 0
}
-# @opt-bool ?-nodefault? option ...
+# @opt-bool option ...
#
-# Check each of the named, boolean options and if any have been explicitly enabled
-# or disabled by the user, return 1 or 0 accordingly.
-#
+# Check each of the named, boolean options and return 1 if any of them have
+# been set by the user.
# If the option was specified more than once, the last value wins.
# e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0
#
-# If no value was specified by the user, returns the default value for the
-# first option. If -nodefault is given, this behaviour changes and
-# -1 is returned instead.
-#
proc opt-bool {args} {
- set nodefault 0
- if {[lindex $args 0] eq "-nodefault"} {
- set nodefault 1
- set args [lrange $args 1 end]
- }
option-check-names {*}$args
-
- foreach opt $args {
- if {[dict exists $::autosetup(optset) $opt]} {
- return [dict get $::autosetup(optset) $opt]
- }
- }
-
- if {$nodefault} {
- return -1
- }
- # Default value is the default for the first option
- return [dict get $::autosetup(optdefault) [lindex $args 0]]
+ opt_bool ::useropts {*}$args
}
# @opt-val option-list ?default=""?
#
# Returns a list containing all the values given for the non-boolean options in 'option-list'.
@@ -250,20 +223,11 @@
#
# If no options were set, $default is returned (exactly, not as a list).
#
proc opt-val {names {default ""}} {
option-check-names {*}$names
-
- foreach opt $names {
- if {[dict exists $::autosetup(optset) $opt]} {
- lappend result {*}[dict get $::autosetup(optset) $opt]
- }
- }
- if {[info exists result]} {
- return $result
- }
- return $default
+ join [opt_val ::useropts $names $default]
}
proc option-check-names {args} {
foreach o $args {
if {$o ni $::autosetup(options)} {
@@ -271,14 +235,14 @@
}
}
}
# Parse the option definition in $opts and update
-# ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately
+# ::useropts() and ::autosetup(optionhelp) appropriately
#
proc options-add {opts {header ""}} {
- global autosetup
+ global useropts autosetup
# First weed out comment lines
set realopts {}
foreach line [split $opts \n] {
if {![string match "#*" [string trimleft $line]]} {
@@ -311,70 +275,34 @@
set opthelp $opt
} elseif {$colon eq ""} {
# Boolean option
lappend autosetup(options) $name
+ if {![info exists useropts($name)]} {
+ set useropts($name) $value
+ }
if {$value eq "1"} {
set opthelp "--disable-$name"
} else {
set opthelp "--$name"
}
-
- # Set the default
- if {$value eq ""} {
- set value 0
- }
- dict set autosetup(optdefault) $name $value
-
- if {[dict exists $autosetup(getopt) $name]} {
- # The option was specified by the user. Look at the last value.
- lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue
- if {$type eq "str"} {
- # Can we convert the value to a boolean?
- if {$setvalue in {1 enabled yes}} {
- set setvalue 1
- } elseif {$setvalue in {0 disabled no}} {
- set setvalue 0
- } else {
- user-error "Boolean option $name given as --$name=$setvalue"
- }
- }
- dict set autosetup(optset) $name $setvalue
- #puts "Found boolean option --$name=$setvalue"
- }
} else {
# String option.
lappend autosetup(options) $name
if {$equal eq "="} {
- # String option with optional value
+ if {[info exists useropts($name)]} {
+ # If the user specified the option with no value, the value will be "1"
+ # Replace with the default
+ if {$useropts($name) eq "1"} {
+ set useropts($name) $value
+ }
+ }
set opthelp "--$name?=$value?"
} else {
- # String option with required value
set opthelp "--$name=$value"
}
- dict set autosetup(optdefault) $name $value
-
- # Get the values specified by the user
- if {[dict exists $autosetup(getopt) $name]} {
- set listvalue {}
-
- foreach pair [dict get $autosetup(getopt) $name] {
- lassign $pair type setvalue
- if {$type eq "bool" && $setvalue} {
- if {$equal ne "="} {
- user-error "Option --$name requires a value"
- }
- # If given as a boolean, use the default value
- set setvalue $value
- }
- lappend listvalue $setvalue
- }
-
- #puts "Found string option --$name=$listvalue"
- dict set autosetup(optset) $name $listvalue
- }
}
# Now create the help for this option if appropriate
if {[lindex $opts $i+1] eq "=>"} {
set desc [lindex $opts $i+2]
@@ -502,11 +430,11 @@
exit 0
}
# Check for invalid options
if {[opt-bool option-checking]} {
- foreach o [dict keys $::autosetup(getopt)] {
+ foreach o [array names ::useropts] {
if {$o ni $::autosetup(options)} {
user-error "Unknown option --$o"
}
}
}
@@ -1168,23 +1096,17 @@
# All rights reserved
# Simple getopt module
# Parse everything out of the argv list which looks like an option
+# Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
# Everything which doesn't look like an option, or is after --, is left unchanged
-# Understands --enable-xxx as a synonym for --xxx to enable the boolean option xxx.
-# Understands --disable-xxx to disable the boolean option xxx.
#
-# The returned value is a dictionary keyed by option name
-# Each value is a list of {type value} ... where type is "bool" or "str".
-# The value for a boolean option is 0 or 1. The value of a string option is the value given.
proc getopt {argvname} {
upvar $argvname argv
set nargv {}
- set opts {}
-
for {set i 0} {$i < [llength $argv]} {incr i} {
set arg [lindex $argv $i]
#dputs arg=$arg
@@ -1194,31 +1116,64 @@
lappend nargv {*}[lrange $argv $i end]
break
}
if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} {
- # --name=value
- dict lappend opts $name [list str $value]
+ lappend opts($name) $value
} elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} {
- if {$prefix in {enable- with- ""}} {
+ if {$prefix eq "disable-"} {
+ set value 0
+ } else {
set value 1
- } else {
- set value 0
}
- dict lappend opts $name [list bool $value]
+ lappend opts($name) $value
} else {
lappend nargv $arg
}
}
#puts "getopt: argv=[join $argv] => [join $nargv]"
- #array set getopt $opts
- #parray getopt
+ #parray opts
set argv $nargv
- return $opts
+ return [array get opts]
+}
+
+proc opt_val {optarrayname options {default {}}} {
+ upvar $optarrayname opts
+
+ set result {}
+
+ foreach o $options {
+ if {[info exists opts($o)]} {
+ lappend result {*}$opts($o)
+ }
+ }
+ if {[llength $result] == 0} {
+ return $default
+ }
+ return $result
+}
+
+proc opt_bool {optarrayname args} {
+ upvar $optarrayname opts
+
+ # Support the args being passed as a list
+ if {[llength $args] == 1} {
+ set args [lindex $args 0]
+ }
+
+ foreach o $args {
+ if {[info exists opts($o)]} {
+ # For boolean options, the last value wins
+ if {[lindex $opts($o) end] in {"1" "yes"}} {
+ return 1
+ }
+ }
+ }
+ return 0
}
}
# ----- module help -----
Index: autosetup/cc-lib.tcl
==================================================================
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -10,11 +10,11 @@
module-options {}
# @cc-check-lfs
#
# The equivalent of the AC_SYS_LARGEFILE macro
-#
+#
# defines 'HAVE_LFS' if LFS is available,
# and defines '_FILE_OFFSET_BITS=64' if necessary
#
# Returns 1 if 'LFS' is available or 0 otherwise
#
@@ -36,11 +36,11 @@
}
# @cc-check-endian
#
# The equivalent of the AC_C_BIGENDIAN macro
-#
+#
# defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
#
# Returns 1 if determined, or 0 if not.
#
@@ -157,35 +157,5 @@
cctest_alignof _Alignof
cctest_alignof __alignof__
cctest_alignof __alignof
}
-
-# @cc-check-alloca
-#
-# The equivalent of the AC_FUNC_ALLOCA macro
-#
-# Checks for the existence of alloca
-# defines HAVE_ALLOCA and returns 1 if it exists
-proc cc-check-alloca {} {
- cc-check-some-feature alloca {
- cctest -includes alloca.h -code { alloca (2 * sizeof (int)); }
- }
-}
-
-# @cc-signal-return-type
-#
-# The equivalent of the AC_TYPE_SIGNAL macro
-#
-# defines RETSIGTYPE to int or void
-proc cc-signal-return-type {} {
- msg-checking "Checking return type of signal handlers..."
- cc-with {-includes {sys/types.h signal.h}} {
- if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} {
- set type int
- } else {
- set type void
- }
- define RETSIGTYPE $type
- msg-result $type
- }
-}
Index: autosetup/cc-shared.tcl
==================================================================
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -62,11 +62,11 @@
}
sparc* {
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
msg-result "Found sun stdio compiler"
# sun stdio compiler
- # XXX: These haven't been fully tested.
+ # XXX: These haven't been fully tested.
define SHOBJ_CFLAGS -KPIC
define SHOBJ_LDFLAGS "-G"
define SH_CFLAGS -KPIC
define SH_LINKFLAGS -Wl,-export-dynamic
define SH_SOPREFIX -Wl,-h,
@@ -78,11 +78,11 @@
}
*-*-solaris* {
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
msg-result "Found sun stdio compiler"
# sun stdio compiler
- # XXX: These haven't been fully tested.
+ # XXX: These haven't been fully tested.
define SHOBJ_CFLAGS -KPIC
define SHOBJ_LDFLAGS "-G"
define SH_CFLAGS -KPIC
define SH_LINKFLAGS -Wl,-export-dynamic
define SH_SOPREFIX -Wl,-h,
@@ -103,15 +103,10 @@
define SH_LDFLAGS -shared
define SH_LINKFLAGS ""
define SH_SOPREFIX ""
define LD_LIBRARY_PATH LIBRARY_PATH
}
- microblaze* {
- # Microblaze generally needs -fPIC rather than -fpic
- define SHOBJ_CFLAGS -fPIC
- define SH_CFLAGS -fPIC
- }
}
if {![is-defined SHOBJ_LDFLAGS_R]} {
define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
}
Index: autosetup/cc.tcl
==================================================================
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -47,12 +47,11 @@
}
# Checks for the existence of the given type/structure member.
# e.g. "struct stat.st_mtime"
proc cctest_member {struct_member} {
- # split at the first dot
- regexp {^([^.]+)[.](.*)$} $struct_member -> struct member
+ lassign [split $struct_member .] struct member
cctest -code "static $struct _s; return sizeof(_s.$member);"
}
# Checks for the existence of the given define by compiling
#
@@ -209,18 +208,18 @@
# First checks for no library required, then checks each of the libraries
# in turn.
#
# If the function is found, the feature is defined and lib_$function is defined
# to -l$lib where the function was found, or "" if no library required.
-# In addition, -l$lib is prepended to the LIBS define.
+# In addition, -l$lib is added to the LIBS define.
#
# If additional libraries may be needed for linking, they should be specified
# as $extralibs as "-lotherlib1 -lotherlib2".
# These libraries are not automatically added to LIBS.
#
# Returns 1 if found or 0 if not.
-#
+#
proc cc-check-function-in-lib {function libs {otherlibs {}}} {
msg-checking "Checking libs for $function..."
set found 0
cc-with [list -libs $otherlibs] {
if {[cctest_function $function]} {
@@ -231,12 +230,11 @@
foreach lib $libs {
cc-with [list -libs -l$lib] {
if {[cctest_function $function]} {
msg-result -l$lib
define lib_$function -l$lib
- # prepend to LIBS
- define LIBS "-l$lib [get-define LIBS]"
+ define-append LIBS -l$lib
incr found
break
}
}
}
@@ -415,11 +413,11 @@
return $result
}
}
# @cctest ?settings?
-#
+#
# Low level C compiler checker. Compiles and or links a small C program
# according to the arguments and returns 1 if OK, or 0 if not.
#
# Supported settings are:
#
@@ -498,21 +496,17 @@
default {
autosetup-error "cctest called with unknown language: $opts(-lang)"
}
}
- if {$opts(-link)} {
- lappend cmdline {*}[get-define LDFLAGS]
- } else {
+ if {!$opts(-link)} {
set tmp conftest__.o
lappend cmdline -c
}
lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
+
lappend cmdline $src -o $tmp {*}$opts(-libs)
- if {$opts(-link)} {
- lappend cmdline {*}[get-define LIBS]
- }
# At this point we have the complete command line and the
# complete source to be compiled. Get the result from cache if
# we can
if {[info exists ::cc_cache($cmdline,$lines)]} {
Index: autosetup/jimsh0.c
==================================================================
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,9 +1,7 @@
/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */
-#define _GNU_SOURCE
#define JIM_TCL_COMPAT
-#define JIM_REFERENCES
#define JIM_ANSIC
#define JIM_REGEXP
#define HAVE_NO_AUTOCONF
#define _JIMAUTOCONF_H
#define TCL_LIBRARY "."
@@ -35,20 +33,26 @@
#define HAVE_UNISTD_H
#else
#define TCL_PLATFORM_OS "unknown"
#define TCL_PLATFORM_PLATFORM "unix"
#define TCL_PLATFORM_PATH_SEPARATOR ":"
+#ifdef _MINIX
+#define vfork fork
+#define _POSIX_SOURCE
+#else
+#define _GNU_SOURCE
+#endif
#define HAVE_VFORK
#define HAVE_WAITPID
#define HAVE_ISATTY
#define HAVE_MKSTEMP
#define HAVE_LINK
#define HAVE_SYS_TIME_H
#define HAVE_DIRENT_H
#define HAVE_UNISTD_H
#endif
-#define JIM_VERSION 76
+#define JIM_VERSION 77
#ifndef JIM_WIN32COMPAT_H
#define JIM_WIN32COMPAT_H
@@ -105,14 +109,14 @@
struct dirent {
char *d_name;
};
typedef struct DIR {
- long handle;
+ long handle;
struct _finddata_t info;
- struct dirent result;
- char *name;
+ struct dirent result;
+ char *name;
} DIR;
DIR *opendir(const char *name);
int closedir(DIR *dir);
struct dirent *readdir(DIR *dir);
@@ -122,11 +126,11 @@
#include
#define strtod __strtod
#endif
-#endif
+#endif
#ifdef __cplusplus
}
#endif
@@ -175,13 +179,13 @@
extern "C" {
#endif
#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
#ifndef HAVE_NO_AUTOCONF
#endif
@@ -224,31 +228,31 @@
#define JIM_SIGNAL 5
#define JIM_EXIT 6
#define JIM_EVAL 7
-#define JIM_MAX_CALLFRAME_DEPTH 1000
-#define JIM_MAX_EVAL_DEPTH 2000
+#define JIM_MAX_CALLFRAME_DEPTH 1000
+#define JIM_MAX_EVAL_DEPTH 2000
#define JIM_PRIV_FLAG_SHIFT 20
-#define JIM_NONE 0
-#define JIM_ERRMSG 1
-#define JIM_ENUM_ABBREV 2
-#define JIM_UNSHARED 4
-#define JIM_MUSTEXIST 8
-
-
-#define JIM_SUBST_NOVAR 1
-#define JIM_SUBST_NOCMD 2
-#define JIM_SUBST_NOESC 4
-#define JIM_SUBST_FLAG 128
-
-
-#define JIM_CASESENS 0
-#define JIM_NOCASE 1
+#define JIM_NONE 0
+#define JIM_ERRMSG 1
+#define JIM_ENUM_ABBREV 2
+#define JIM_UNSHARED 4
+#define JIM_MUSTEXIST 8
+
+
+#define JIM_SUBST_NOVAR 1
+#define JIM_SUBST_NOCMD 2
+#define JIM_SUBST_NOESC 4
+#define JIM_SUBST_FLAG 128
+
+
+#define JIM_CASESENS 0
+#define JIM_NOCASE 1
#define JIM_PATH_LEN 1024
@@ -339,79 +343,79 @@
#define Jim_GetHashTableSize(ht) ((ht)->size)
#define Jim_GetHashTableUsed(ht) ((ht)->used)
typedef struct Jim_Obj {
- char *bytes;
- const struct Jim_ObjType *typePtr;
- int refCount;
- int length;
-
+ char *bytes;
+ const struct Jim_ObjType *typePtr;
+ int refCount;
+ int length;
+
union {
-
+
jim_wide wideValue;
-
+
int intValue;
-
+
double doubleValue;
-
+
void *ptr;
-
+
struct {
void *ptr1;
void *ptr2;
} twoPtrValue;
-
+
struct {
struct Jim_Var *varPtr;
- unsigned long callFrameId;
- int global;
+ unsigned long callFrameId;
+ int global;
} varValue;
-
+
struct {
struct Jim_Obj *nsObj;
struct Jim_Cmd *cmdPtr;
- unsigned long procEpoch;
+ unsigned long procEpoch;
} cmdValue;
-
+
struct {
- struct Jim_Obj **ele;
- int len;
- int maxLen;
+ struct Jim_Obj **ele;
+ int len;
+ int maxLen;
} listValue;
-
+
struct {
int maxLength;
- int charLength;
+ int charLength;
} strValue;
-
+
struct {
unsigned long id;
struct Jim_Reference *refPtr;
} refValue;
-
+
struct {
struct Jim_Obj *fileNameObj;
int lineNumber;
} sourceValue;
-
+
struct {
struct Jim_Obj *varNameObjPtr;
struct Jim_Obj *indexObjPtr;
} dictSubstValue;
-
+
struct {
- void *compre;
+ void *compre;
unsigned flags;
} regexpValue;
struct {
int line;
int argc;
} scriptLineValue;
} internalRep;
- struct Jim_Obj *prevObjPtr;
- struct Jim_Obj *nextObjPtr;
+ struct Jim_Obj *prevObjPtr;
+ struct Jim_Obj *nextObjPtr;
} Jim_Obj;
#define Jim_IncrRefCount(objPtr) \
++(objPtr)->refCount
@@ -442,40 +446,40 @@
typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
typedef struct Jim_ObjType {
- const char *name;
+ const char *name;
Jim_FreeInternalRepProc *freeIntRepProc;
Jim_DupInternalRepProc *dupIntRepProc;
Jim_UpdateStringProc *updateStringProc;
int flags;
} Jim_ObjType;
-#define JIM_TYPE_NONE 0
-#define JIM_TYPE_REFERENCES 1
+#define JIM_TYPE_NONE 0
+#define JIM_TYPE_REFERENCES 1
typedef struct Jim_CallFrame {
- unsigned long id;
- int level;
- struct Jim_HashTable vars;
- struct Jim_HashTable *staticVars;
- struct Jim_CallFrame *parent;
- Jim_Obj *const *argv;
- int argc;
- Jim_Obj *procArgsObjPtr;
- Jim_Obj *procBodyObjPtr;
- struct Jim_CallFrame *next;
- Jim_Obj *nsObj;
- Jim_Obj *fileNameObj;
+ unsigned long id;
+ int level;
+ struct Jim_HashTable vars;
+ struct Jim_HashTable *staticVars;
+ struct Jim_CallFrame *parent;
+ Jim_Obj *const *argv;
+ int argc;
+ Jim_Obj *procArgsObjPtr;
+ Jim_Obj *procBodyObjPtr;
+ struct Jim_CallFrame *next;
+ Jim_Obj *nsObj;
+ Jim_Obj *fileNameObj;
int line;
- Jim_Stack *localCommands;
- struct Jim_Obj *tailcallObj;
- struct Jim_Cmd *tailcallCmd;
+ Jim_Stack *localCommands;
+ struct Jim_Obj *tailcallObj;
+ struct Jim_Cmd *tailcallCmd;
} Jim_CallFrame;
typedef struct Jim_Var {
Jim_Obj *objPtr;
struct Jim_CallFrame *linkFramePtr;
@@ -487,35 +491,35 @@
typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
typedef struct Jim_Cmd {
- int inUse;
- int isproc;
- struct Jim_Cmd *prevCmd;
+ int inUse;
+ int isproc;
+ struct Jim_Cmd *prevCmd;
union {
struct {
-
- Jim_CmdProc *cmdProc;
- Jim_DelCmdProc *delProc;
- void *privData;
+
+ Jim_CmdProc *cmdProc;
+ Jim_DelCmdProc *delProc;
+ void *privData;
} native;
struct {
-
+
Jim_Obj *argListObjPtr;
Jim_Obj *bodyObjPtr;
- Jim_HashTable *staticVars;
- int argListLen;
- int reqArity;
- int optArity;
- int argsPos;
- int upcall;
+ Jim_HashTable *staticVars;
+ int argListLen;
+ int reqArity;
+ int optArity;
+ int argsPos;
+ int upcall;
struct Jim_ProcArg {
- Jim_Obj *nameObjPtr;
- Jim_Obj *defaultObjPtr;
+ Jim_Obj *nameObjPtr;
+ Jim_Obj *defaultObjPtr;
} *arglist;
- Jim_Obj *nsObj;
+ Jim_Obj *nsObj;
} proc;
} u;
} Jim_Cmd;
@@ -523,64 +527,64 @@
unsigned char sbox[256];
unsigned int i, j;
} Jim_PrngState;
typedef struct Jim_Interp {
- Jim_Obj *result;
- int errorLine;
- Jim_Obj *errorFileNameObj;
- int addStackTrace;
- int maxCallFrameDepth;
- int maxEvalDepth;
- int evalDepth;
- int returnCode;
- int returnLevel;
- int exitCode;
- long id;
- int signal_level;
- jim_wide sigmask;
- int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
- Jim_CallFrame *framePtr;
- Jim_CallFrame *topFramePtr;
- struct Jim_HashTable commands;
+ Jim_Obj *result;
+ int errorLine;
+ Jim_Obj *errorFileNameObj;
+ int addStackTrace;
+ int maxCallFrameDepth;
+ int maxEvalDepth;
+ int evalDepth;
+ int returnCode;
+ int returnLevel;
+ int exitCode;
+ long id;
+ int signal_level;
+ jim_wide sigmask;
+ int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
+ Jim_CallFrame *framePtr;
+ Jim_CallFrame *topFramePtr;
+ struct Jim_HashTable commands;
unsigned long procEpoch; /* Incremented every time the result
of procedures names lookup caching
may no longer be valid. */
unsigned long callFrameEpoch; /* Incremented every time a new
callframe is created. This id is used for the
'ID' field contained in the Jim_CallFrame
structure. */
- int local;
- Jim_Obj *liveList;
- Jim_Obj *freeList;
- Jim_Obj *currentScriptObj;
- Jim_Obj *nullScriptObj;
- Jim_Obj *emptyObj;
- Jim_Obj *trueObj;
- Jim_Obj *falseObj;
- unsigned long referenceNextId;
- struct Jim_HashTable references;
+ int local;
+ Jim_Obj *liveList;
+ Jim_Obj *freeList;
+ Jim_Obj *currentScriptObj;
+ Jim_Obj *nullScriptObj;
+ Jim_Obj *emptyObj;
+ Jim_Obj *trueObj;
+ Jim_Obj *falseObj;
+ unsigned long referenceNextId;
+ struct Jim_HashTable references;
unsigned long lastCollectId; /* reference max Id of the last GC
execution. It's set to -1 while the collection
is running as sentinel to avoid to recursive
calls via the [collect] command inside
finalizers. */
- time_t lastCollectTime;
- Jim_Obj *stackTrace;
- Jim_Obj *errorProc;
- Jim_Obj *unknown;
- int unknown_called;
- int errorFlag;
+ time_t lastCollectTime;
+ Jim_Obj *stackTrace;
+ Jim_Obj *errorProc;
+ Jim_Obj *unknown;
+ int unknown_called;
+ int errorFlag;
void *cmdPrivData; /* Used to pass the private data pointer to
a command. It is set to what the user specified
via Jim_CreateCommand(). */
- struct Jim_CallFrame *freeFramesList;
- struct Jim_HashTable assocData;
- Jim_PrngState *prngState;
- struct Jim_HashTable packages;
- Jim_Stack *loadHandles;
+ struct Jim_CallFrame *freeFramesList;
+ struct Jim_HashTable assocData;
+ Jim_PrngState *prngState;
+ struct Jim_HashTable packages;
+ Jim_Stack *loadHandles;
} Jim_Interp;
#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -831,10 +835,14 @@
JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
Jim_Obj *exprObjPtr, int *boolPtr);
+
+JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr,
+ int *booleanPtr);
+
JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
jim_wide *widePtr);
JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
long *longPtr);
@@ -904,11 +912,11 @@
#ifdef __cplusplus
}
#endif
-#endif
+#endif
#ifndef JIM_SUBCMD_H
#define JIM_SUBCMD_H
@@ -915,24 +923,24 @@
#ifdef __cplusplus
extern "C" {
#endif
-#define JIM_MODFLAG_HIDDEN 0x0001
-#define JIM_MODFLAG_FULLARGV 0x0002
+#define JIM_MODFLAG_HIDDEN 0x0001
+#define JIM_MODFLAG_FULLARGV 0x0002
typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
typedef struct {
- const char *cmd;
- const char *args;
- jim_subcmd_function *function;
- short minargs;
- short maxargs;
- unsigned short flags;
+ const char *cmd;
+ const char *args;
+ jim_subcmd_function *function;
+ short minargs;
+ short maxargs;
+ unsigned short flags;
} jim_subcmd_type;
const jim_subcmd_type *
Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv);
@@ -960,36 +968,36 @@
int rm_eo;
} regmatch_t;
typedef struct regexp {
-
- int re_nsub;
-
-
- int cflags;
- int err;
- int regstart;
- int reganch;
- int regmust;
- int regmlen;
- int *program;
-
-
- const char *regparse;
- int p;
- int proglen;
-
-
- int eflags;
- const char *start;
- const char *reginput;
- const char *regbol;
-
-
- regmatch_t *pmatch;
- int nmatch;
+
+ int re_nsub;
+
+
+ int cflags;
+ int err;
+ int regstart;
+ int reganch;
+ int regmust;
+ int regmlen;
+ int *program;
+
+
+ const char *regparse;
+ int p;
+ int proglen;
+
+
+ int eflags;
+ const char *start;
+ const char *reginput;
+ const char *regbol;
+
+
+ regmatch_t *pmatch;
+ int nmatch;
} regexp;
typedef regexp regex_t;
#define REG_EXTENDED 0
@@ -997,13 +1005,13 @@
#define REG_ICASE 2
#define REG_NOTBOL 16
enum {
- REG_NOERROR,
- REG_NOMATCH,
- REG_BADPAT,
+ REG_NOERROR,
+ REG_NOMATCH,
+ REG_BADPAT,
REG_ERR_NULL_ARGUMENT,
REG_ERR_UNKNOWN,
REG_ERR_TOO_BIG,
REG_ERR_NOMEM,
REG_ERR_TOO_MANY_PAREN,
@@ -1780,10 +1788,11 @@
"}\n"
);
}
+#define _GNU_SOURCE
#include
#include
#include
#include
#ifdef HAVE_UNISTD_H
@@ -1808,12 +1817,12 @@
#include
#include
#endif
-#define AIO_CMD_LEN 32
-#define AIO_BUF_LEN 256
+#define AIO_CMD_LEN 32
+#define AIO_BUF_LEN 256
#ifndef HAVE_FTELLO
#define ftello ftell
#endif
#ifndef HAVE_FSEEKO
@@ -1848,11 +1857,11 @@
typedef struct AioFile
{
FILE *fp;
Jim_Obj *filename;
int type;
- int openFlags;
+ int openFlags;
int fd;
Jim_Obj *rEvent;
Jim_Obj *wEvent;
Jim_Obj *eEvent;
int addr_family;
@@ -1879,11 +1888,11 @@
{
if (!ferror(af->fp)) {
return JIM_OK;
}
clearerr(af->fp);
-
+
if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
return JIM_OK;
}
#ifdef ECONNRESET
if (errno == ECONNRESET) {
@@ -1945,12 +1954,12 @@
JIM_NOTUSED(interp);
Jim_DecrRefCount(interp, af->filename);
#ifdef jim_ext_eventloop
-
- Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
+
+ Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
#endif
#if defined(JIM_SSL)
if (af->ssl != NULL) {
SSL_free(af->ssl);
@@ -1968,11 +1977,11 @@
{
AioFile *af = Jim_CmdPrivData(interp);
char buf[AIO_BUF_LEN];
Jim_Obj *objPtr;
int nonewline = 0;
- jim_wide neededLen = -1;
+ jim_wide neededLen = -1;
if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
nonewline = 1;
argv++;
argc--;
@@ -2007,11 +2016,11 @@
}
}
if (retval != readlen)
break;
}
-
+
if (JimCheckStreamError(interp, af)) {
Jim_FreeNewObj(interp, objPtr);
return JIM_ERR;
}
if (nonewline) {
@@ -2029,11 +2038,11 @@
AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command)
{
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
-
+
if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
return (AioFile *) cmdPtr->u.native.privData;
}
Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
return NULL;
@@ -2110,21 +2119,21 @@
}
else {
len = strlen(buf);
if (len && (buf[len - 1] == '\n')) {
-
+
len--;
}
Jim_AppendString(interp, objPtr, buf, len);
break;
}
}
if (JimCheckStreamError(interp, af)) {
-
+
Jim_FreeNewObj(interp, objPtr);
return JIM_ERR;
}
if (argc) {
@@ -2134,11 +2143,11 @@
}
len = Jim_Length(objPtr);
if (len == 0 && feof(af->fp)) {
-
+
len = -1;
}
Jim_SetResultInt(interp, len);
}
else {
@@ -2364,33 +2373,33 @@
static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
int argc, Jim_Obj * const *argv)
{
if (argc == 0) {
-
+
if (*scriptHandlerObj) {
Jim_SetResult(interp, *scriptHandlerObj);
}
return JIM_OK;
}
if (*scriptHandlerObj) {
-
- Jim_DeleteFileHandler(interp, af->fp, mask);
+
+ Jim_DeleteFileHandler(interp, af->fd, mask);
}
-
+
if (Jim_Length(argv[0]) == 0) {
-
+
return JIM_OK;
}
-
+
Jim_IncrRefCount(argv[0]);
*scriptHandlerObj = argv[0];
- Jim_CreateFileHandler(interp, af->fp, mask,
+ Jim_CreateFileHandler(interp, af->fd, mask,
JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
return JIM_OK;
}
@@ -2414,136 +2423,137 @@
return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
}
#endif
+
static const jim_subcmd_type aio_command_table[] = {
{ "read",
"?-nonewline? ?len?",
aio_cmd_read,
0,
2,
-
+
},
{ "copyto",
"handle ?size?",
aio_cmd_copy,
1,
2,
-
+
},
{ "gets",
"?var?",
aio_cmd_gets,
0,
1,
-
+
},
{ "puts",
"?-nonewline? str",
aio_cmd_puts,
1,
2,
-
+
},
{ "isatty",
NULL,
aio_cmd_isatty,
0,
0,
-
+
},
{ "flush",
NULL,
aio_cmd_flush,
0,
0,
-
+
},
{ "eof",
NULL,
aio_cmd_eof,
0,
0,
-
+
},
{ "close",
"?r(ead)|w(rite)?",
aio_cmd_close,
0,
1,
JIM_MODFLAG_FULLARGV,
-
+
},
{ "seek",
"offset ?start|current|end",
aio_cmd_seek,
1,
2,
-
+
},
{ "tell",
NULL,
aio_cmd_tell,
0,
0,
-
+
},
{ "filename",
NULL,
aio_cmd_filename,
0,
0,
-
+
},
#ifdef O_NDELAY
{ "ndelay",
"?0|1?",
aio_cmd_ndelay,
0,
1,
-
+
},
#endif
#ifdef HAVE_FSYNC
{ "sync",
NULL,
aio_cmd_sync,
0,
0,
-
+
},
#endif
{ "buffering",
"none|line|full",
aio_cmd_buffering,
1,
1,
-
+
},
#ifdef jim_ext_eventloop
{ "readable",
"?readable-script?",
aio_cmd_readable,
0,
1,
-
+
},
{ "writable",
"?writable-script?",
aio_cmd_writable,
0,
1,
-
+
},
{ "onexception",
"?exception-script?",
aio_cmd_onexception,
0,
1,
-
+
},
#endif
{ NULL }
};
@@ -2566,11 +2576,11 @@
#ifdef jim_ext_tclcompat
{
const char *filename = Jim_String(argv[1]);
-
+
if (*filename == '|') {
Jim_Obj *evalObj[3];
evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2623,11 +2633,11 @@
Jim_DecrRefCount(interp, filename);
return NULL;
}
}
-
+
af = Jim_Alloc(sizeof(*af));
memset(af, 0, sizeof(*af));
af->fp = fh;
af->fd = fileno(fh);
af->filename = filename;
@@ -2661,11 +2671,11 @@
Jim_SetResult(interp, objPtr);
return JIM_OK;
}
}
-
+
close(p[0]);
close(p[1]);
JimAioSetError(interp, NULL);
return JIM_ERR;
}
@@ -2695,15 +2705,15 @@
}
#if defined(S_IRWXG) && defined(S_IRWXO)
mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
#else
-
+
mask = umask(S_IXUSR);
#endif
-
+
fd = mkstemp(filenameObj->bytes);
umask(mask);
if (fd < 0) {
JimAioSetError(interp, filenameObj);
Jim_FreeNewObj(interp, filenameObj);
@@ -2731,11 +2741,11 @@
Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
#ifndef JIM_ANSIC
Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
#endif
-
+
JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
return JIM_OK;
@@ -2831,20 +2841,20 @@
{
regex_t *compre;
const char *pattern;
int ret;
-
+
if (objPtr->typePtr == ®expObjType &&
objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
-
+
return objPtr->internalRep.regexpValue.compre;
}
-
-
+
+
pattern = Jim_String(objPtr);
compre = Jim_Alloc(sizeof(regex_t));
if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
char buf[100];
@@ -3001,11 +3011,11 @@
}
num_matches++;
if (opt_all && !opt_inline) {
-
+
goto try_next_match;
}
j = 0;
@@ -3041,11 +3051,11 @@
if (opt_inline) {
Jim_ListAppendElement(interp, resultListObj, resultObj);
}
else {
-
+
result = Jim_SetVariable(interp, argv[i], resultObj);
if (result != JIM_OK) {
Jim_FreeObj(interp, resultObj);
break;
@@ -3168,11 +3178,11 @@
source_str = Jim_GetString(argv[i + 1], &source_len);
replace_str = Jim_GetString(argv[i + 2], &replace_len);
varname = argv[i + 3];
-
+
resultObj = Jim_NewStringObj(interp, "", 0);
if (offset) {
if (offset < 0) {
offset += source_len + 1;
@@ -3183,11 +3193,11 @@
else if (offset < 0) {
offset = 0;
}
}
-
+
Jim_AppendString(interp, resultObj, source_str, offset);
n = source_len - offset;
p = source_str + offset;
@@ -3242,23 +3252,23 @@
}
p += pmatch[0].rm_eo;
n -= pmatch[0].rm_eo;
-
+
if (!opt_all || n == 0) {
break;
}
-
+
if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
break;
}
-
+
if (pattern[0] == '\0' && n) {
-
+
Jim_AppendString(interp, resultObj, p, 1);
p++;
n--;
}
@@ -3265,11 +3275,11 @@
regexec_flags |= REG_NOTBOL;
} while (n);
Jim_AppendString(interp, resultObj, p, -1);
-
+
if (argc - i == 4) {
result = Jim_SetVariable(interp, varname, resultObj);
if (result == JIM_OK) {
Jim_SetResultInt(interp, num_matches);
@@ -3371,11 +3381,11 @@
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
}
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
{
-
+
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
AppendStatElement(interp, listObj, "dev", sb->st_dev);
AppendStatElement(interp, listObj, "ino", sb->st_ino);
AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3387,25 +3397,25 @@
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
-
+
if (varName) {
Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
if (objPtr) {
if (Jim_DictSize(interp, objPtr) < 0) {
-
+
Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
Jim_FreeNewObj(interp, listObj);
return JIM_ERR;
}
if (Jim_IsShared(objPtr))
objPtr = Jim_DuplicateObj(interp, objPtr);
-
+
Jim_ListAppendList(interp, objPtr, listObj);
Jim_DictSize(interp, objPtr);
Jim_InvalidateStringRep(objPtr);
Jim_FreeNewObj(interp, listObj);
@@ -3412,11 +3422,11 @@
listObj = objPtr;
}
Jim_SetVariable(interp, varName, listObj);
}
-
+
Jim_SetResult(interp, listObj);
return JIM_OK;
}
@@ -3432,11 +3442,11 @@
}
else if (p == path) {
Jim_SetResultString(interp, "/", -1);
}
else if (ISWINDOWS && p[-1] == ':') {
-
+
Jim_SetResultString(interp, path, p - path + 1);
}
else {
Jim_SetResultString(interp, path, p - path);
}
@@ -3512,35 +3522,35 @@
char *newname = Jim_Alloc(MAXPATHLEN + 1);
char *last = newname;
*newname = 0;
-
+
for (i = 0; i < argc; i++) {
int len;
const char *part = Jim_GetString(argv[i], &len);
if (*part == '/') {
-
+
last = newname;
}
else if (ISWINDOWS && strchr(part, ':')) {
-
+
last = newname;
}
else if (part[0] == '.') {
if (part[1] == '/') {
part += 2;
len -= 2;
}
else if (part[1] == 0 && last != newname) {
-
+
continue;
}
}
-
+
if (last != newname && last[-1] != '/') {
*last++ = '/';
}
if (len) {
@@ -3551,22 +3561,22 @@
}
memcpy(last, part, len);
last += len;
}
-
+
if (last > newname + 1 && last[-1] == '/') {
-
+
if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
*--last = 0;
}
}
}
*last = 0;
-
+
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
return JIM_OK;
}
@@ -3591,11 +3601,11 @@
static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
#ifdef X_OK
return file_access(interp, argv[0], X_OK);
#else
-
+
Jim_SetResultBool(interp, 1);
return JIM_OK;
#endif
}
@@ -3616,11 +3626,11 @@
while (argc--) {
const char *path = Jim_String(argv[0]);
if (unlink(path) == -1 && errno != ENOENT) {
if (rmdir(path) == -1) {
-
+
if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
strerror(errno));
return JIM_ERR;
}
@@ -3639,15 +3649,15 @@
static int mkdir_all(char *path)
{
int ok = 1;
-
+
goto first;
while (ok--) {
-
+
{
char *slash = strrchr(path, '/');
if (slash && slash != path) {
*slash = 0;
@@ -3660,24 +3670,24 @@
first:
if (MKDIR_DEFAULT(path) == 0) {
return 0;
}
if (errno == ENOENT) {
-
+
continue;
}
-
+
if (errno == EEXIST) {
struct stat sb;
if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
return 0;
}
-
+
errno = EEXIST;
}
-
+
break;
}
return -1;
}
@@ -3962,192 +3972,192 @@
{ "atime",
"name",
file_cmd_atime,
1,
1,
-
+
},
{ "mtime",
"name ?time?",
file_cmd_mtime,
1,
2,
-
+
},
{ "copy",
"?-force? source dest",
file_cmd_copy,
2,
3,
-
+
},
{ "dirname",
"name",
file_cmd_dirname,
1,
1,
-
+
},
{ "rootname",
"name",
file_cmd_rootname,
1,
1,
-
+
},
{ "extension",
"name",
file_cmd_extension,
1,
1,
-
+
},
{ "tail",
"name",
file_cmd_tail,
1,
1,
-
+
},
{ "normalize",
"name",
file_cmd_normalize,
1,
1,
-
+
},
{ "join",
"name ?name ...?",
file_cmd_join,
1,
-1,
-
+
},
{ "readable",
"name",
file_cmd_readable,
1,
1,
-
+
},
{ "writable",
"name",
file_cmd_writable,
1,
1,
-
+
},
{ "executable",
"name",
file_cmd_executable,
1,
1,
-
+
},
{ "exists",
"name",
file_cmd_exists,
1,
1,
-
+
},
{ "delete",
"?-force|--? name ...",
file_cmd_delete,
1,
-1,
-
+
},
{ "mkdir",
"dir ...",
file_cmd_mkdir,
1,
-1,
-
+
},
{ "tempfile",
"?template?",
file_cmd_tempfile,
0,
1,
-
+
},
{ "rename",
"?-force? source dest",
file_cmd_rename,
2,
3,
-
+
},
#if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
{ "link",
"?-symbolic|-hard? newname target",
file_cmd_link,
2,
3,
-
+
},
#endif
#if defined(HAVE_READLINK)
{ "readlink",
"name",
file_cmd_readlink,
1,
1,
-
+
},
#endif
{ "size",
"name",
file_cmd_size,
1,
1,
-
+
},
{ "stat",
"name ?var?",
file_cmd_stat,
1,
2,
-
+
},
{ "lstat",
"name ?var?",
file_cmd_lstat,
1,
2,
-
+
},
{ "type",
"name",
file_cmd_type,
1,
1,
-
+
},
#ifdef HAVE_GETEUID
{ "owned",
"name",
file_cmd_owned,
1,
1,
-
+
},
#endif
{ "isdirectory",
"name",
file_cmd_isdirectory,
1,
1,
-
+
},
{ "isfile",
"name",
file_cmd_isfile,
1,
1,
-
+
},
{
NULL
}
};
@@ -4179,11 +4189,11 @@
Jim_SetResultString(interp, "Failed to get pwd", -1);
Jim_Free(cwd);
return JIM_ERR;
}
else if (ISWINDOWS) {
-
+
char *p = cwd;
while ((p = strchr(p, '\\')) != NULL) {
*p++ = '/';
}
}
@@ -4203,10 +4213,11 @@
Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
return JIM_OK;
}
+#define _GNU_SOURCE
#include
#include
#if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4214,20 +4225,20 @@
{
Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
int i, j;
int rc;
-
+
for (i = 1; i < argc; i++) {
int len;
const char *arg = Jim_GetString(argv[i], &len);
if (i > 1) {
Jim_AppendString(interp, cmdlineObj, " ", 1);
}
if (strpbrk(arg, "\\\" ") == NULL) {
-
+
Jim_AppendString(interp, cmdlineObj, arg, len);
continue;
}
Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4268,11 +4279,11 @@
#include
#include
#if defined(__MINGW32__)
-
+
#ifndef STRICT
#define STRICT
#endif
#define WIN32_LEAN_AND_MEAN
#include
@@ -4394,14 +4405,14 @@
if (!objPtr) {
return Jim_GetEnviron();
}
-
+
num = Jim_ListLength(interp, objPtr);
if (num % 2) {
-
+
num--;
}
size = Jim_Length(objPtr) + 2;
envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4493,19 +4504,19 @@
}
struct WaitInfo
{
- pidtype pid;
- int status;
- int flags;
+ pidtype pid;
+ int status;
+ int flags;
};
struct WaitInfoTable {
- struct WaitInfo *info;
- int size;
- int used;
+ struct WaitInfo *info;
+ int size;
+ int used;
};
#define WI_DETACHED 2
@@ -4528,12 +4539,12 @@
return table;
}
static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- fdtype outputId;
- fdtype errorId;
+ fdtype outputId;
+ fdtype errorId;
pidtype *pidPtr;
int numPids, result;
int child_siginfo = 1;
Jim_Obj *childErrObj;
Jim_Obj *errStrObj;
@@ -4545,11 +4556,11 @@
argc--;
numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
if (numPids < 0) {
return JIM_ERR;
}
-
+
listObj = Jim_NewListObj(interp, NULL, 0);
for (i = 0; i < numPids; i++) {
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
}
Jim_SetResult(interp, listObj);
@@ -4567,19 +4578,19 @@
result = JIM_OK;
errStrObj = Jim_NewStringObj(interp, "", 0);
-
+
if (outputId != JIM_BAD_FD) {
if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
result = JIM_ERR;
Jim_SetResultErrno(interp, "error reading from output pipe");
}
}
-
+
childErrObj = Jim_NewStringObj(interp, "", 0);
Jim_IncrRefCount(childErrObj);
if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
result = JIM_ERR;
@@ -4592,25 +4603,25 @@
if (ret < 0) {
Jim_SetResultErrno(interp, "error reading from error pipe");
result = JIM_ERR;
}
else if (ret > 0) {
-
+
child_siginfo = 0;
}
}
if (child_siginfo) {
-
+
Jim_AppendObj(interp, errStrObj, childErrObj);
}
Jim_DecrRefCount(interp, childErrObj);
-
+
Jim_RemoveTrailingNewline(errStrObj);
-
+
Jim_SetResult(interp, errStrObj);
return result;
}
@@ -4629,11 +4640,11 @@
for (count = table->used; count > 0; waitPtr++, count--) {
if (waitPtr->flags & WI_DETACHED) {
int status;
pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
if (pid == waitPtr->pid) {
-
+
table->used--;
continue;
}
}
if (waitPtr != &table->info[dest]) {
@@ -4645,36 +4656,36 @@
static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
{
int i;
-
+
for (i = 0; i < table->used; i++) {
if (pid == table->info[i].pid) {
-
+
JimWaitPid(pid, statusPtr, 0);
-
+
if (i != table->used - 1) {
table->info[i] = table->info[table->used - 1];
}
table->used--;
return pid;
}
}
-
+
return JIM_BAD_PID;
}
static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
{
int j;
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
for (j = 0; j < numPids; j++) {
-
+
int i;
for (i = 0; i < table->used; i++) {
if (pidPtr[j] == table->info[i].pid) {
table->info[i].flags |= WI_DETACHED;
break;
@@ -4707,16 +4718,16 @@
int cmdCount; /* Count of number of distinct commands
* found in argc/argv. */
const char *input = NULL; /* Describes input for pipeline, depending
* on "inputFile". NULL means take input
* from stdin/pipe. */
- int input_len = 0;
+ int input_len = 0;
-#define FILE_NAME 0
-#define FILE_APPEND 1
-#define FILE_HANDLE 2
-#define FILE_TEXT 3
+#define FILE_NAME 0
+#define FILE_APPEND 1
+#define FILE_HANDLE 2
+#define FILE_TEXT 3
int inputFile = FILE_NAME; /* 1 means input is name of input file.
* 2 means input is filehandle name.
* 0 means input holds actual
* text to be input to command. */
@@ -4737,20 +4748,20 @@
* or NULL if stderr goes to stderr/pipe. */
fdtype inputId = JIM_BAD_FD;
fdtype outputId = JIM_BAD_FD;
fdtype errorId = JIM_BAD_FD;
fdtype lastOutputId = JIM_BAD_FD;
- fdtype pipeIds[2];
+ fdtype pipeIds[2];
int firstArg, lastArg; /* Indexes of first and last arguments in
* current command. */
int lastBar;
int i;
pidtype pid;
char **save_environ;
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
-
+
char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
int arg_count = 0;
JimReapDetachedPids(table);
@@ -4796,11 +4807,11 @@
if (*output == '>') {
outputFile = FILE_APPEND;
output++;
}
if (*output == '&') {
-
+
output++;
dup_error = 1;
}
if (*output == '@') {
outputFile = FILE_HANDLE;
@@ -4837,11 +4848,11 @@
goto badargs;
}
lastBar = i;
cmdCount++;
}
-
+
arg_array[arg_count++] = (char *)arg;
continue;
}
if (i >= argc) {
@@ -4855,11 +4866,11 @@
badargs:
Jim_Free(arg_array);
return -1;
}
-
+
save_environ = JimSaveEnv(JimBuildEnv(interp));
if (input != NULL) {
if (inputFile == FILE_TEXT) {
inputId = JimCreateTemp(interp, input, input_len);
@@ -4866,11 +4877,11 @@
if (inputId == JIM_BAD_FD) {
goto error;
}
}
else if (inputFile == FILE_HANDLE) {
-
+
FILE *fh = JimGetAioFilehandle(interp, input);
if (fh == NULL) {
goto error;
}
@@ -4918,20 +4929,20 @@
}
lastOutputId = pipeIds[1];
*outPipePtr = pipeIds[0];
pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
}
-
+
if (error != NULL) {
if (errorFile == FILE_HANDLE) {
if (strcmp(error, "1") == 0) {
-
+
if (lastOutputId != JIM_BAD_FD) {
errorId = JimDupFd(lastOutputId);
}
else {
-
+
error = "stdout";
}
}
if (errorId == JIM_BAD_FD) {
FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4973,11 +4984,11 @@
pipe_dup_err = 1;
}
break;
}
}
-
+
arg_array[lastArg] = NULL;
if (lastArg == arg_count) {
outputId = lastOutputId;
}
else {
@@ -4986,16 +4997,16 @@
goto error;
}
outputId = pipeIds[1];
}
-
+
if (pipe_dup_err) {
errorId = outputId;
}
-
+
#ifdef __MINGW32__
pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
if (pid == JIM_BAD_PID) {
Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -5006,32 +5017,32 @@
if (pid < 0) {
Jim_SetResultErrno(interp, "couldn't fork child process");
goto error;
}
if (pid == 0) {
-
+
if (inputId != -1) dup2(inputId, 0);
if (outputId != -1) dup2(outputId, 1);
if (errorId != -1) dup2(errorId, 2);
for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
close(i);
}
-
+
(void)signal(SIGPIPE, SIG_DFL);
execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
-
+
fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
_exit(127);
}
#endif
-
+
if (table->used == table->size) {
table->size += WAIT_TABLE_GROW_BY;
table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
}
@@ -5040,11 +5051,11 @@
table->info[table->used].flags = 0;
table->used++;
pidPtr[numPids] = pid;
-
+
errorId = origErrorId;
if (inputId != JIM_BAD_FD) {
JimCloseFd(inputId);
@@ -5111,11 +5122,11 @@
{
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
int result = JIM_OK;
int i;
-
+
for (i = 0; i < numPids; i++) {
int waitStatus = 0;
if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) {
result = JIM_ERR;
@@ -5284,17 +5295,21 @@
}
static fdtype JimOpenForRead(const char *filename)
{
return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
- JimStdSecAttrs(), OPEN_EXISTING, 0, NULL);
+ JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
static fdtype JimOpenForWrite(const char *filename, int append)
{
- return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL);
+ fdtype fd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
+ if (append && fd != JIM_BAD_FD) {
+ SetFilePointer(fd, 0, NULL, FILE_END);
+ }
+ return fd;
}
static FILE *JimFdOpenForWrite(fdtype fd)
{
return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5302,11 +5317,11 @@
static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
{
DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
-
+
return JIM_BAD_PID;
}
GetExitCodeProcess(pid, &ret);
*status = ret;
CloseHandle(pid);
@@ -5329,11 +5344,11 @@
if (handle == INVALID_HANDLE_VALUE) {
goto error;
}
if (contents != NULL) {
-
+
FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
if (fh == NULL) {
goto error;
}
@@ -5601,11 +5616,11 @@
#include
#endif
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
-
+
char buf[100];
time_t t;
long seconds;
const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5642,20 +5657,20 @@
if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
return -1;
}
-
+
localtime_r(&now, &tm);
pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
if (pt == 0 || *pt != 0) {
Jim_SetResultString(interp, "Failed to parse time according to format", -1);
return JIM_ERR;
}
-
+
Jim_SetResultInt(interp, mktime(&tm));
return JIM_OK;
}
#endif
@@ -5693,47 +5708,47 @@
{ "seconds",
NULL,
clock_cmd_seconds,
0,
0,
-
+
},
{ "clicks",
NULL,
clock_cmd_micros,
0,
0,
-
+
},
{ "microseconds",
NULL,
clock_cmd_micros,
0,
0,
-
+
},
{ "milliseconds",
NULL,
clock_cmd_millis,
0,
0,
-
+
},
{ "format",
"seconds ?-format format?",
clock_cmd_format,
1,
3,
-
+
},
#ifdef HAVE_STRPTIME
{ "scan",
"str -format format",
clock_cmd_scan,
3,
3,
-
+
},
#endif
{ NULL }
};
@@ -5753,11 +5768,11 @@
#include
static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
-
+
Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
return JIM_OK;
}
static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5769,20 +5784,20 @@
return JIM_OK;
}
patternObj = (argc == 1) ? NULL : argv[1];
-
+
if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
-
+
Jim_SetResult(interp, objPtr);
return JIM_OK;
}
}
-
+
return Jim_DictValues(interp, objPtr, patternObj);
}
static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -5802,27 +5817,27 @@
Jim_Obj *resultObj;
Jim_Obj *objPtr;
Jim_Obj **dictValuesObj;
if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
-
+
Jim_UnsetVariable(interp, argv[0], JIM_NONE);
return JIM_OK;
}
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
if (objPtr == NULL) {
-
+
return JIM_OK;
}
if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
return JIM_ERR;
}
-
+
resultObj = Jim_NewDictObj(interp, NULL, 0);
for (i = 0; i < len; i += 2) {
if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5837,11 +5852,11 @@
static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr;
int len = 0;
-
+
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
if (objPtr) {
len = Jim_DictSize(interp, objPtr);
if (len < 0) {
return JIM_ERR;
@@ -5876,11 +5891,11 @@
return JIM_ERR;
}
dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
if (!dictObj) {
-
+
return Jim_SetVariable(interp, argv[0], listObj);
}
else if (Jim_DictSize(interp, dictObj) < 0) {
return JIM_ERR;
}
@@ -5905,53 +5920,53 @@
{ "exists",
"arrayName",
array_cmd_exists,
1,
1,
-
+
},
{ "get",
"arrayName ?pattern?",
array_cmd_get,
1,
2,
-
+
},
{ "names",
"arrayName ?pattern?",
array_cmd_names,
1,
2,
-
+
},
{ "set",
"arrayName list",
array_cmd_set,
2,
2,
-
+
},
{ "size",
"arrayName",
array_cmd_size,
1,
1,
-
+
},
{ "stat",
"arrayName",
array_cmd_stat,
1,
1,
-
+
},
{ "unset",
"arrayName ?pattern?",
array_cmd_unset,
1,
2,
-
+
},
{ NULL
}
};
@@ -5987,11 +6002,12 @@
Jim_arrayInit(interp);
Jim_stdlibInit(interp);
Jim_tclcompatInit(interp);
return JIM_OK;
}
-#define JIM_OPTIMIZATION
+#define JIM_OPTIMIZATION
+#define _GNU_SOURCE
#include
#include
#include
@@ -6056,10 +6072,16 @@
#define JimPanic(X) JimPanicDump X
#else
#define JimPanic(X)
#endif
+#ifdef JIM_OPTIMIZATION
+#define JIM_IF_OPTIM(X) X
+#else
+#define JIM_IF_OPTIM(X)
+#endif
+
static char JimEmptyStringRep[] = "";
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -6112,34 +6134,34 @@
if (*pattern == '^') {
not++;
pattern++;
}
-
+
if (*pattern == ']') {
goto first;
}
}
while (*pattern && *pattern != ']') {
-
+
if (pattern[0] == '\\') {
first:
pattern += utf8_tounicode_case(pattern, &pchar, nocase);
}
else {
-
+
int start;
int end;
pattern += utf8_tounicode_case(pattern, &start, nocase);
if (pattern[0] == '-' && pattern[1]) {
-
+
pattern += utf8_tounicode(pattern, &pchar);
pattern += utf8_tounicode_case(pattern, &end, nocase);
-
+
if ((c >= start && c <= end) || (c >= end && c <= start)) {
match = 1;
}
continue;
}
@@ -6169,19 +6191,19 @@
while (pattern[1] == '*') {
pattern++;
}
pattern++;
if (!pattern[0]) {
- return 1;
+ return 1;
}
while (*string) {
-
+
if (JimGlobMatch(pattern, string, nocase))
- return 1;
+ return 1;
string += utf8_tounicode(string, &c);
}
- return 0;
+ return 0;
case '?':
string += utf8_tounicode(string, &c);
break;
@@ -6190,20 +6212,20 @@
pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
if (!pattern) {
return 0;
}
if (!*pattern) {
-
+
continue;
}
break;
}
case '\\':
if (pattern[1]) {
pattern++;
}
-
+
default:
string += utf8_tounicode_case(string, &c, nocase);
utf8_tounicode_case(pattern, &pchar, nocase);
if (pchar != c) {
return 0;
@@ -6249,11 +6271,11 @@
maxchars--;
}
if (!maxchars) {
return 0;
}
-
+
if (*s1) {
return 1;
}
if (*s2) {
return -1;
@@ -6290,11 +6312,11 @@
const char *p;
if (!l1 || !l2 || l1 > l2)
return -1;
-
+
for (p = s2 + l2 - 1; p != s2 - 1; p--) {
if (*p == *s1 && memcmp(s1, p, l1) == 0) {
return p - s2;
}
}
@@ -6349,28 +6371,28 @@
}
*sign = 1;
}
if (str[i] != '0') {
-
+
return 0;
}
-
+
switch (str[i + 1]) {
case 'x': case 'X': *base = 16; break;
case 'o': case 'O': *base = 8; break;
case 'b': case 'B': *base = 2; break;
default: return 0;
}
i += 2;
-
+
if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
-
+
return i;
}
-
+
*base = 10;
return 0;
}
static long jim_strtol(const char *str, char **endptr)
@@ -6384,11 +6406,11 @@
if (endptr == NULL || *endptr != str + i) {
return value * sign;
}
}
-
+
return strtol(str, endptr, 10);
}
static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6403,11 +6425,11 @@
if (endptr == NULL || *endptr != str + i) {
return value * sign;
}
}
-
+
return strtoull(str, endptr, 10);
#else
return (unsigned long)jim_strtol(str, endptr);
#endif
}
@@ -6428,26 +6450,40 @@
int Jim_StringToDouble(const char *str, double *doublePtr)
{
char *endptr;
-
+
errno = 0;
*doublePtr = strtod(str, &endptr);
return JimCheckConversion(str, endptr);
}
static jim_wide JimPowWide(jim_wide b, jim_wide e)
{
- jim_wide i, res = 1;
+ jim_wide res = 1;
- if ((b == 0 && e != 0) || (e < 0))
- return 0;
- for (i = 0; i < e; i++) {
- res *= b;
+
+ if (b == 1) {
+
+ return 1;
+ }
+ if (e < 0) {
+ if (b != -1) {
+ return 0;
+ }
+ e = -e;
+ }
+ while (e)
+ {
+ if (e & 1) {
+ res *= b;
+ }
+ e >>= 1;
+ b *= b;
}
return res;
}
#ifdef JIM_DEBUG_PANIC
@@ -6509,11 +6545,11 @@
char *Jim_StrDupLen(const char *s, int l)
{
char *copy = Jim_Alloc(l + 1);
memcpy(copy, s, l + 1);
- copy[l] = 0;
+ copy[l] = 0;
return copy;
}
@@ -6598,52 +6634,52 @@
}
void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
{
- Jim_HashTable n;
+ Jim_HashTable n;
unsigned int realsize = JimHashTableNextPower(size), i;
if (size <= ht->used)
return;
Jim_InitHashTable(&n, ht->type, ht->privdata);
n.size = realsize;
n.sizemask = realsize - 1;
n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
-
+
n.uniq = ht->uniq;
-
+
memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
n.used = ht->used;
for (i = 0; ht->used > 0; i++) {
Jim_HashEntry *he, *nextHe;
if (ht->table[i] == NULL)
continue;
-
+
he = ht->table[i];
while (he) {
unsigned int h;
nextHe = he->next;
-
+
h = Jim_HashKey(ht, he->key) & n.sizemask;
he->next = n.table[h];
n.table[h] = he;
ht->used--;
-
+
he = nextHe;
}
}
assert(ht->used == 0);
Jim_Free(ht->table);
-
+
*ht = n;
}
int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6652,11 +6688,11 @@
entry = JimInsertHashEntry(ht, key, 0);
if (entry == NULL)
return JIM_ERR;
-
+
Jim_SetHashKey(ht, entry, key);
Jim_SetHashVal(ht, entry, val);
return JIM_OK;
}
@@ -6678,11 +6714,11 @@
Jim_SetHashVal(ht, entry, val);
}
existed = 1;
}
else {
-
+
Jim_SetHashKey(ht, entry, key);
Jim_SetHashVal(ht, entry, val);
existed = 0;
}
@@ -6701,11 +6737,11 @@
he = ht->table[h];
prevHe = NULL;
while (he) {
if (Jim_CompareHashKeys(ht, key, he->key)) {
-
+
if (prevHe)
prevHe->next = he->next;
else
ht->table[h] = he->next;
Jim_FreeEntryKey(ht, he);
@@ -6715,19 +6751,19 @@
return JIM_OK;
}
prevHe = he;
he = he->next;
}
- return JIM_ERR;
+ return JIM_ERR;
}
int Jim_FreeHashTable(Jim_HashTable *ht)
{
unsigned int i;
-
+
for (i = 0; ht->used > 0; i++) {
Jim_HashEntry *he, *nextHe;
if ((he = ht->table[i]) == NULL)
continue;
@@ -6738,15 +6774,15 @@
Jim_Free(he);
ht->used--;
he = nextHe;
}
}
-
+
Jim_Free(ht->table);
-
+
JimResetHashTable(ht);
- return JIM_OK;
+ return JIM_OK;
}
Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
{
Jim_HashEntry *he;
@@ -6819,24 +6855,24 @@
static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
{
unsigned int h;
Jim_HashEntry *he;
-
+
JimExpandHashTableIfNeeded(ht);
-
+
h = Jim_HashKey(ht, key) & ht->sizemask;
-
+
he = ht->table[h];
while (he) {
if (Jim_CompareHashKeys(ht, key, he->key))
return replace ? he : NULL;
he = he->next;
}
-
+
he = Jim_Alloc(sizeof(*he));
he->next = ht->table[h];
ht->table[h] = he;
ht->used++;
he->key = NULL;
@@ -6865,16 +6901,16 @@
{
Jim_Free(key);
}
static const Jim_HashTableType JimPackageHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- NULL
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ NULL
};
typedef struct AssocDataValue
{
Jim_InterpDeleteProc *delProc;
@@ -6889,16 +6925,16 @@
assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
Jim_Free(data);
}
static const Jim_HashTableType JimAssocDataHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- JimAssocDataHashTableValueDestructor
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ JimAssocDataHashTableValueDestructor
};
void Jim_InitStack(Jim_Stack *stack)
{
stack->len = 0;
@@ -6951,56 +6987,61 @@
freeFunc(stack->vector[i]);
}
-#define JIM_TT_NONE 0
-#define JIM_TT_STR 1
-#define JIM_TT_ESC 2
-#define JIM_TT_VAR 3
-#define JIM_TT_DICTSUGAR 4
-#define JIM_TT_CMD 5
-
-#define JIM_TT_SEP 6
-#define JIM_TT_EOL 7
-#define JIM_TT_EOF 8
-
-#define JIM_TT_LINE 9
-#define JIM_TT_WORD 10
+#define JIM_TT_NONE 0
+#define JIM_TT_STR 1
+#define JIM_TT_ESC 2
+#define JIM_TT_VAR 3
+#define JIM_TT_DICTSUGAR 4
+#define JIM_TT_CMD 5
+
+#define JIM_TT_SEP 6
+#define JIM_TT_EOL 7
+#define JIM_TT_EOF 8
+
+#define JIM_TT_LINE 9
+#define JIM_TT_WORD 10
#define JIM_TT_SUBEXPR_START 11
#define JIM_TT_SUBEXPR_END 12
#define JIM_TT_SUBEXPR_COMMA 13
#define JIM_TT_EXPR_INT 14
#define JIM_TT_EXPR_DOUBLE 15
+#define JIM_TT_EXPR_BOOLEAN 16
-#define JIM_TT_EXPRSUGAR 16
+#define JIM_TT_EXPRSUGAR 17
#define JIM_TT_EXPR_OP 20
#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
+#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA)
+
+#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP)
+
struct JimParseMissing {
- int ch;
- int line;
+ int ch;
+ int line;
};
struct JimParserCtx
{
- const char *p;
- int len;
- int linenr;
+ const char *p;
+ int len;
+ int linenr;
const char *tstart;
- const char *tend;
- int tline;
- int tt;
- int eof;
- int inquote;
- int comment;
- struct JimParseMissing missing;
+ const char *tend;
+ int tline;
+ int tt;
+ int eof;
+ int inquote;
+ int comment;
+ struct JimParseMissing missing;
};
static int JimParseScript(struct JimParserCtx *pc);
static int JimParseSep(struct JimParserCtx *pc);
static int JimParseEol(struct JimParserCtx *pc);
@@ -7030,11 +7071,11 @@
pc->missing.line = linenr;
}
static int JimParseScript(struct JimParserCtx *pc)
{
- while (1) {
+ while (1) {
if (!pc->len) {
pc->tstart = pc->p;
pc->tend = pc->p - 1;
pc->tline = pc->linenr;
pc->tt = JIM_TT_EOL;
@@ -7066,11 +7107,11 @@
pc->comment = 0;
return JimParseCmd(pc);
case '$':
pc->comment = 0;
if (JimParseVar(pc) == JIM_ERR) {
-
+
pc->tstart = pc->tend = pc->p++;
pc->len--;
pc->tt = JIM_TT_ESC;
}
return JIM_OK;
@@ -7127,11 +7168,11 @@
static void JimParseSubBrace(struct JimParserCtx *pc)
{
int level = 1;
-
+
pc->p++;
pc->len--;
while (pc->len) {
switch (*pc->p) {
case '\\':
@@ -7171,11 +7212,11 @@
static int JimParseSubQuote(struct JimParserCtx *pc)
{
int tt = JIM_TT_STR;
int line = pc->tline;
-
+
pc->p++;
pc->len--;
while (pc->len) {
switch (*pc->p) {
case '\\':
@@ -7220,11 +7261,11 @@
{
int level = 1;
int startofword = 1;
int line = pc->tline;
-
+
pc->p++;
pc->len--;
while (pc->len) {
switch (*pc->p) {
case '\\':
@@ -7300,17 +7341,17 @@
return JIM_OK;
}
static int JimParseVar(struct JimParserCtx *pc)
{
-
+
pc->p++;
pc->len--;
#ifdef EXPRSUGAR_BRACKET
if (*pc->p == '[') {
-
+
JimParseCmd(pc);
pc->tt = JIM_TT_EXPRSUGAR;
return JIM_OK;
}
#endif
@@ -7336,11 +7377,11 @@
pc->len--;
}
}
else {
while (1) {
-
+
if (pc->p[0] == ':' && pc->p[1] == ':') {
while (*pc->p == ':') {
pc->p++;
pc->len--;
}
@@ -7351,11 +7392,11 @@
pc->len--;
continue;
}
break;
}
-
+
if (*pc->p == '(') {
int count = 1;
const char *paren = NULL;
pc->tt = JIM_TT_DICTSUGAR;
@@ -7378,11 +7419,11 @@
if (count == 0) {
pc->p++;
pc->len--;
}
else if (paren) {
-
+
paren++;
pc->len += (pc->p - paren);
pc->p = paren;
}
#ifndef EXPRSUGAR_BRACKET
@@ -7403,19 +7444,19 @@
static int JimParseStr(struct JimParserCtx *pc)
{
if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
-
+
if (*pc->p == '{') {
return JimParseBrace(pc);
}
if (*pc->p == '"') {
pc->inquote = 1;
pc->p++;
pc->len--;
-
+
pc->missing.line = pc->tline;
}
}
pc->tstart = pc->p;
pc->tline = pc->linenr;
@@ -7441,25 +7482,25 @@
}
pc->p++;
pc->len--;
}
else if (pc->len == 1) {
-
+
pc->missing.ch = '\\';
}
break;
case '(':
-
+
if (pc->len > 1 && pc->p[1] != '$') {
break;
}
-
+
case ')':
-
+
if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
if (pc->p == pc->tstart) {
-
+
pc->p++;
pc->len--;
}
pc->tend = pc->p - 1;
pc->tt = JIM_TT_ESC;
@@ -7499,11 +7540,11 @@
break;
}
pc->p++;
pc->len--;
}
- return JIM_OK;
+ return JIM_OK;
}
static int JimParseComment(struct JimParserCtx *pc)
{
while (*pc->p) {
@@ -7610,34 +7651,34 @@
if (c == -1) {
break;
}
val = (val << 4) | c;
}
-
+
if (s[i] == '{') {
if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
-
+
i--;
k = 0;
}
else {
-
+
k++;
}
}
if (k) {
-
+
if (s[i] == 'x') {
*p++ = val;
}
else {
p += utf8_fromunicode(p, val);
}
i += k;
break;
}
-
+
*p++ = s[i];
}
break;
case 'v':
*p++ = 0xb;
@@ -7646,11 +7687,11 @@
case '\0':
*p++ = '\\';
i++;
break;
case '\n':
-
+
*p++ = ' ';
do {
i++;
} while (s[i + 1] == ' ' || s[i + 1] == '\t');
break;
@@ -7660,11 +7701,11 @@
case '3':
case '4':
case '5':
case '6':
case '7':
-
+
{
int val = 0;
int c = odigitval(s[i + 1]);
val = c;
@@ -7717,16 +7758,16 @@
}
else {
len = (end - start) + 1;
token = Jim_Alloc(len + 1);
if (pc->tt != JIM_TT_ESC) {
-
+
memcpy(token, start, len);
token[len] = '\0';
}
else {
-
+
len = JimEscape(token, start, len);
}
}
return Jim_NewStringObjNoAlloc(interp, token, len);
@@ -7790,11 +7831,11 @@
while (pc->len) {
switch (*pc->p) {
case '\\':
pc->tt = JIM_TT_ESC;
if (--pc->len == 0) {
-
+
pc->tend = pc->p;
return JIM_OK;
}
pc->p++;
break;
@@ -7826,11 +7867,11 @@
pc->tend = pc->p - 1;
return JIM_OK;
}
if (*pc->p == '\\') {
if (--pc->len == 0) {
-
+
pc->tend = pc->p;
return JIM_OK;
}
pc->tt = JIM_TT_ESC;
pc->p++;
@@ -7846,24 +7887,24 @@
Jim_Obj *Jim_NewObj(Jim_Interp *interp)
{
Jim_Obj *objPtr;
-
+
if (interp->freeList != NULL) {
-
+
objPtr = interp->freeList;
interp->freeList = objPtr->nextObjPtr;
}
else {
-
+
objPtr = Jim_Alloc(sizeof(*objPtr));
}
objPtr->refCount = 0;
-
+
objPtr->prevObjPtr = NULL;
objPtr->nextObjPtr = interp->liveList;
if (interp->liveList)
interp->liveList->prevObjPtr = objPtr;
interp->liveList = objPtr;
@@ -7871,32 +7912,32 @@
return objPtr;
}
void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
{
-
+
JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : ""));
-
+
Jim_FreeIntRep(interp, objPtr);
-
+
if (objPtr->bytes != NULL) {
if (objPtr->bytes != JimEmptyStringRep)
Jim_Free(objPtr->bytes);
}
-
+
if (objPtr->prevObjPtr)
objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
if (objPtr->nextObjPtr)
objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
if (interp->liveList == objPtr)
interp->liveList = objPtr->nextObjPtr;
#ifdef JIM_DISABLE_OBJECT_POOL
Jim_Free(objPtr);
#else
-
+
objPtr->prevObjPtr = NULL;
objPtr->nextObjPtr = interp->freeList;
if (interp->freeList)
interp->freeList->prevObjPtr = objPtr;
interp->freeList = objPtr;
@@ -7919,45 +7960,45 @@
{
Jim_Obj *dupPtr;
dupPtr = Jim_NewObj(interp);
if (objPtr->bytes == NULL) {
-
+
dupPtr->bytes = NULL;
}
else if (objPtr->length == 0) {
-
+
dupPtr->bytes = JimEmptyStringRep;
dupPtr->length = 0;
dupPtr->typePtr = NULL;
return dupPtr;
}
else {
dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
dupPtr->length = objPtr->length;
-
+
memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
}
-
+
dupPtr->typePtr = objPtr->typePtr;
if (objPtr->typePtr != NULL) {
if (objPtr->typePtr->dupIntRepProc == NULL) {
dupPtr->internalRep = objPtr->internalRep;
}
else {
-
+
objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
}
}
return dupPtr;
}
const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
{
if (objPtr->bytes == NULL) {
-
+
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
objPtr->typePtr->updateStringProc(objPtr);
}
if (lenPtr)
*lenPtr = objPtr->length;
@@ -7966,11 +8007,11 @@
int Jim_Length(Jim_Obj *objPtr)
{
if (objPtr->bytes == NULL) {
-
+
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
objPtr->typePtr->updateStringProc(objPtr);
}
return objPtr->length;
}
@@ -7977,11 +8018,11 @@
const char *Jim_String(Jim_Obj *objPtr)
{
if (objPtr->bytes == NULL) {
-
+
JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
objPtr->typePtr->updateStringProc(objPtr);
}
return objPtr->bytes;
@@ -8037,22 +8078,22 @@
}
static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
if (objPtr->typePtr != &stringObjType) {
-
+
if (objPtr->bytes == NULL) {
-
+
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
objPtr->typePtr->updateStringProc(objPtr);
}
-
+
Jim_FreeIntRep(interp, objPtr);
-
+
objPtr->typePtr = &stringObjType;
objPtr->internalRep.strValue.maxLength = objPtr->length;
-
+
objPtr->internalRep.strValue.charLength = -1;
}
return JIM_OK;
}
@@ -8073,14 +8114,14 @@
Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
{
Jim_Obj *objPtr = Jim_NewObj(interp);
-
+
if (len == -1)
len = strlen(s);
-
+
if (len == 0) {
objPtr->bytes = JimEmptyStringRep;
}
else {
objPtr->bytes = Jim_Alloc(len + 1);
@@ -8087,25 +8128,25 @@
memcpy(objPtr->bytes, s, len);
objPtr->bytes[len] = '\0';
}
objPtr->length = len;
-
+
objPtr->typePtr = NULL;
return objPtr;
}
Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
{
#ifdef JIM_UTF8
-
+
int bytelen = utf8_index(s, charlen);
Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
-
+
objPtr->typePtr = &stringObjType;
objPtr->internalRep.strValue.maxLength = bytelen;
objPtr->internalRep.strValue.charLength = charlen;
return objPtr;
@@ -8132,11 +8173,11 @@
len = strlen(str);
needlen = objPtr->length + len;
if (objPtr->internalRep.strValue.maxLength < needlen ||
objPtr->internalRep.strValue.maxLength == 0) {
needlen *= 2;
-
+
if (needlen < 7) {
needlen = 7;
}
if (objPtr->bytes == JimEmptyStringRep) {
objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8148,11 +8189,11 @@
}
memcpy(objPtr->bytes + objPtr->length, str, len);
objPtr->bytes[objPtr->length + len] = '\0';
if (objPtr->internalRep.strValue.charLength >= 0) {
-
+
objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
}
objPtr->length += len;
}
@@ -8210,11 +8251,11 @@
int l1, l2;
const char *s1 = Jim_GetString(firstObjPtr, &l1);
const char *s2 = Jim_GetString(secondObjPtr, &l2);
if (nocase) {
-
+
return JimStringCompareLen(s1, s2, -1, nocase);
}
return JimStringCompare(s1, l1, s2, l2);
}
@@ -8312,11 +8353,11 @@
if (first == 0 && rangeLen == len) {
return strObjPtr;
}
if (len == bytelen) {
-
+
return Jim_NewStringObj(interp, str + first, rangeLen);
}
return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
#else
return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8341,19 +8382,19 @@
return strObjPtr;
}
str = Jim_String(strObjPtr);
-
+
objPtr = Jim_NewStringObjUtf8(interp, str, first);
-
+
if (newStrObj) {
Jim_AppendObj(interp, objPtr, newStrObj);
}
-
+
Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
return objPtr;
}
@@ -8452,11 +8493,11 @@
while (len) {
int c;
int n = utf8_tounicode(str, &c);
if (utf8_memchr(trimchars, trimlen, c) == NULL) {
-
+
break;
}
str += n;
len -= n;
}
@@ -8523,41 +8564,41 @@
len = Jim_Length(strObjPtr);
nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
if (nontrim == NULL) {
-
+
return Jim_NewEmptyStringObj(interp);
}
if (nontrim == strObjPtr->bytes + len) {
-
+
return strObjPtr;
}
if (Jim_IsShared(strObjPtr)) {
strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
}
else {
-
+
strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
strObjPtr->length = (nontrim - strObjPtr->bytes);
}
return strObjPtr;
}
static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
{
-
+
Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
-
+
strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
-
+
if (objPtr != strObjPtr && objPtr->refCount == 0) {
-
+
Jim_FreeNewObj(interp, objPtr);
}
return strObjPtr;
}
@@ -8575,17 +8616,17 @@
static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
{
static const char * const strclassnames[] = {
"integer", "alpha", "alnum", "ascii", "digit",
"double", "lower", "upper", "space", "xdigit",
- "control", "print", "graph", "punct",
+ "control", "print", "graph", "punct", "boolean",
NULL
};
enum {
STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
- STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
+ STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN,
};
int strclass;
int len;
int i;
const char *str;
@@ -8613,10 +8654,17 @@
{
double d;
Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
return JIM_OK;
}
+
+ case STR_IS_BOOLEAN:
+ {
+ int b;
+ Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK);
+ return JIM_OK;
+ }
case STR_IS_ALPHA: isclassfunc = isalpha; break;
case STR_IS_ALNUM: isclassfunc = isalnum; break;
case STR_IS_ASCII: isclassfunc = jim_isascii; break;
case STR_IS_DIGIT: isclassfunc = isdigit; break;
@@ -8665,11 +8713,11 @@
if (objPtr->typePtr != &comparedStringObjType) {
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &comparedStringObjType;
}
- objPtr->internalRep.ptr = (char *)str;
+ objPtr->internalRep.ptr = (char *)str;
return 1;
}
}
static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8758,20 +8806,20 @@
int type;
} ScriptToken;
typedef struct ScriptObj
{
- ScriptToken *token;
- Jim_Obj *fileNameObj;
- int len;
- int substFlags;
+ ScriptToken *token;
+ Jim_Obj *fileNameObj;
+ int len;
+ int substFlags;
int inUse; /* Used to share a ScriptObj. Currently
only used by Jim_EvalObj() as protection against
shimmering of the currently evaluated object. */
- int firstline;
- int linenr;
- int missing;
+ int firstline;
+ int linenr;
+ int missing;
} ScriptObj;
static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
static int JimParseCheckMissing(Jim_Interp *interp, int ch);
static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -8799,23 +8847,23 @@
dupPtr->typePtr = NULL;
}
typedef struct
{
- const char *token;
- int len;
- int type;
- int line;
+ const char *token;
+ int len;
+ int type;
+ int line;
} ParseToken;
typedef struct
{
-
- ParseToken *list;
- int size;
- int count;
- ParseToken static_list[20];
+
+ ParseToken *list;
+ int size;
+ int count;
+ ParseToken static_list[20];
} ParseTokenList;
static void ScriptTokenListInit(ParseTokenList *tokenlist)
{
tokenlist->list = tokenlist->static_list;
@@ -8834,18 +8882,18 @@
int line)
{
ParseToken *t;
if (tokenlist->count == tokenlist->size) {
-
+
tokenlist->size *= 2;
if (tokenlist->list != tokenlist->static_list) {
tokenlist->list =
Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
}
else {
-
+
tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
memcpy(tokenlist->list, tokenlist->static_list,
tokenlist->count * sizeof(*tokenlist->list));
}
}
@@ -8859,20 +8907,20 @@
static int JimCountWordTokens(ParseToken *t)
{
int expand = 1;
int count = 0;
-
+
if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
-
+
expand = -1;
t++;
}
}
-
+
while (!TOKEN_IS_SEP(t->type)) {
t++;
count++;
}
@@ -8882,11 +8930,11 @@
static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
{
Jim_Obj *objPtr;
if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
-
+
int len = t->len;
char *str = Jim_Alloc(len + 1);
len = JimEscape(str, t->token, len);
objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
}
@@ -8899,13 +8947,13 @@
static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
ParseTokenList *tokenlist)
{
int i;
struct ScriptToken *token;
-
+
int lineargs = 0;
-
+
ScriptToken *linefirst;
int count;
int linenr;
#ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8914,11 +8962,11 @@
printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
tokenlist->list[i].len, tokenlist->list[i].token);
}
#endif
-
+
count = tokenlist->count;
for (i = 0; i < tokenlist->count; i++) {
if (tokenlist->list[i].type == JIM_TT_EOL) {
count++;
}
@@ -8925,59 +8973,59 @@
}
linenr = script->firstline = tokenlist->list[0].line;
token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
-
+
linefirst = token++;
for (i = 0; i < tokenlist->count; ) {
-
+
int wordtokens;
-
+
while (tokenlist->list[i].type == JIM_TT_SEP) {
i++;
}
wordtokens = JimCountWordTokens(tokenlist->list + i);
if (wordtokens == 0) {
-
+
if (lineargs) {
linefirst->type = JIM_TT_LINE;
linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
Jim_IncrRefCount(linefirst->objPtr);
-
+
lineargs = 0;
linefirst = token++;
}
i++;
continue;
}
else if (wordtokens != 1) {
-
+
token->type = JIM_TT_WORD;
token->objPtr = Jim_NewIntObj(interp, wordtokens);
Jim_IncrRefCount(token->objPtr);
token++;
if (wordtokens < 0) {
-
+
i++;
wordtokens = -wordtokens - 1;
lineargs--;
}
}
if (lineargs == 0) {
-
+
linenr = tokenlist->list[i].line;
}
lineargs++;
-
+
while (wordtokens--) {
const ParseToken *t = &tokenlist->list[i++];
token->type = t->type;
token->objPtr = JimMakeScriptObj(interp, t);
@@ -9049,11 +9097,11 @@
token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
for (i = 0; i < tokenlist->count; i++) {
const ParseToken *t = &tokenlist->list[i];
-
+
token->type = t->type;
token->objPtr = JimMakeScriptObj(interp, t);
Jim_IncrRefCount(token->objPtr);
token++;
}
@@ -9068,29 +9116,29 @@
struct JimParserCtx parser;
struct ScriptObj *script;
ParseTokenList tokenlist;
int line = 1;
-
+
if (objPtr->typePtr == &sourceObjType) {
line = objPtr->internalRep.sourceValue.lineNumber;
}
-
+
ScriptTokenListInit(&tokenlist);
JimParserInit(&parser, scriptText, scriptTextLen, line);
while (!parser.eof) {
JimParseScript(&parser);
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
parser.tline);
}
-
+
ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
-
+
script = Jim_Alloc(sizeof(*script));
memset(script, 0, sizeof(*script));
script->inUse = 1;
if (objPtr->typePtr == &sourceObjType) {
script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -9102,14 +9150,14 @@
script->missing = parser.missing.ch;
script->linenr = parser.missing.line;
ScriptObjAddTokens(interp, script, &tokenlist);
-
+
ScriptTokenListFree(&tokenlist);
-
+
Jim_FreeIntRep(interp, objPtr);
Jim_SetIntRepPtr(objPtr, script);
objPtr->typePtr = &scriptObjType;
}
@@ -9116,11 +9164,11 @@
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
{
if (objPtr == interp->emptyObj) {
-
+
objPtr = interp->nullScriptObj;
}
if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
JimSetScriptFromAny(interp, objPtr);
@@ -9155,17 +9203,17 @@
Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
Jim_Free(cmdPtr->u.proc.staticVars);
}
}
else {
-
+
if (cmdPtr->u.native.delProc) {
cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
}
}
if (cmdPtr->prevCmd) {
-
+
JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
}
Jim_Free(cmdPtr);
}
}
@@ -9176,46 +9224,46 @@
Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
Jim_Free(val);
}
static const Jim_HashTableType JimVariablesHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- JimVariablesHTValDestructor
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ JimVariablesHTValDestructor
};
static void JimCommandsHT_ValDestructor(void *interp, void *val)
{
JimDecrCmdRefCount(interp, val);
}
static const Jim_HashTableType JimCommandsHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- JimCommandsHT_ValDestructor
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ JimCommandsHT_ValDestructor
};
#ifdef jim_ext_namespace
static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
{
const char *name = Jim_String(nsObj);
if (name[0] == ':' && name[1] == ':') {
-
+
while (*++name == ':') {
}
nsObj = Jim_NewStringObj(interp, name, -1);
}
else if (Jim_Length(interp->framePtr->nsObj)) {
-
+
nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
Jim_AppendStrings(interp, nsObj, "::", name, NULL);
}
return nsObj;
}
@@ -9239,16 +9287,16 @@
static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
{
Jim_Obj *objPtr = interp->emptyObj;
if (name[0] == ':' && name[1] == ':') {
-
+
while (*++name == ':') {
}
}
else if (Jim_Length(interp->framePtr->nsObj)) {
-
+
objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
Jim_AppendStrings(interp, objPtr, "::", name, NULL);
name = Jim_String(objPtr);
}
Jim_IncrRefCount(objPtr);
@@ -9257,11 +9305,11 @@
}
#define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
#else
-
+
#define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
#define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
{
@@ -9276,17 +9324,17 @@
Jim_InterpIncrProcEpoch(interp);
}
if (he && interp->local) {
-
+
cmd->prevCmd = Jim_GetHashEntryVal(he);
Jim_SetHashVal(&interp->commands, he, cmd);
}
else {
if (he) {
-
+
Jim_DeleteHashEntry(&interp->commands, name);
}
Jim_AddHashEntry(&interp->commands, name, cmd);
}
@@ -9297,11 +9345,11 @@
int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
{
Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
-
+
memset(cmdPtr, 0, sizeof(*cmdPtr));
cmdPtr->inUse = 1;
cmdPtr->u.native.delProc = delProc;
cmdPtr->u.native.cmdProc = cmdProc;
cmdPtr->u.native.privData = privData;
@@ -9326,11 +9374,11 @@
Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
Jim_Var *varPtr;
int subLen;
objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
-
+
subLen = Jim_ListLength(interp, objPtr);
if (subLen == 1 || subLen == 2) {
nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
if (subLen == 1) {
initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9372,19 +9420,19 @@
static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
{
#ifdef jim_ext_namespace
if (cmdPtr->isproc) {
-
+
const char *pt = strrchr(cmdname, ':');
if (pt && pt != cmdname && pt[-1] == ':') {
Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
-
+
Jim_InterpIncrProcEpoch(interp);
}
}
}
#endif
@@ -9397,11 +9445,11 @@
int argListLen;
int i;
argListLen = Jim_ListLength(interp, argListObjPtr);
-
+
cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
memset(cmdPtr, 0, sizeof(*cmdPtr));
cmdPtr->inUse = 1;
cmdPtr->isproc = 1;
cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9412,24 +9460,24 @@
cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
Jim_IncrRefCount(argListObjPtr);
Jim_IncrRefCount(bodyObjPtr);
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
-
+
if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
goto err;
}
-
-
+
+
for (i = 0; i < argListLen; i++) {
Jim_Obj *argPtr;
Jim_Obj *nameObjPtr;
Jim_Obj *defaultObjPtr;
int len;
-
+
argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
len = Jim_ListLength(interp, argPtr);
if (len == 0) {
Jim_SetResultString(interp, "argument with no name", -1);
err:
@@ -9440,16 +9488,16 @@
Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
goto err;
}
if (len == 2) {
-
+
nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
}
else {
-
+
nameObjPtr = argPtr;
defaultObjPtr = NULL;
}
@@ -9510,29 +9558,29 @@
}
fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
-
+
he = Jim_FindHashEntry(&interp->commands, fqold);
if (he == NULL) {
Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
}
else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
}
else {
-
+
cmdPtr = Jim_GetHashEntryVal(he);
JimIncrCmdRefCount(cmdPtr);
JimUpdateProcNamespace(interp, cmdPtr, fqnew);
Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
-
+
Jim_DeleteHashEntry(&interp->commands, fqold);
-
+
Jim_InterpIncrProcEpoch(interp);
ret = JIM_OK;
}
@@ -9571,23 +9619,23 @@
objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
#ifdef jim_ext_namespace
|| !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
#endif
) {
-
-
+
+
const char *name = Jim_String(objPtr);
Jim_HashEntry *he;
if (name[0] == ':' && name[1] == ':') {
while (*++name == ':') {
}
}
#ifdef jim_ext_namespace
else if (Jim_Length(interp->framePtr->nsObj)) {
-
+
Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
Jim_AppendStrings(interp, nameObj, "::", name, NULL);
he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
Jim_FreeNewObj(interp, nameObj);
if (he) {
@@ -9594,11 +9642,11 @@
goto found;
}
}
#endif
-
+
he = Jim_FindHashEntry(&interp->commands, name);
if (he == NULL) {
if (flags & JIM_ERRMSG) {
Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
}
@@ -9607,11 +9655,11 @@
#ifdef jim_ext_namespace
found:
#endif
cmd = Jim_GetHashEntryVal(he);
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &commandObjType;
objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
objPtr->internalRep.cmdValue.cmdPtr = cmd;
objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9626,11 +9674,11 @@
return cmd;
}
-#define JIM_DICT_SUGAR 100
+#define JIM_DICT_SUGAR 100
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
static const Jim_ObjType variableObjType = {
"variable",
@@ -9640,11 +9688,11 @@
JIM_TYPE_REFERENCES,
};
static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
{
-
+
if (nameObjPtr->typePtr != &variableObjType) {
int len;
const char *str = Jim_GetString(nameObjPtr, &len);
if (memchr(str, '\0', len)) {
Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9660,18 +9708,18 @@
Jim_CallFrame *framePtr;
Jim_HashEntry *he;
int global;
int len;
-
+
if (objPtr->typePtr == &variableObjType) {
framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
-
+
return JIM_OK;
}
-
+
}
else if (objPtr->typePtr == &dictSubstObjType) {
return JIM_DICT_SUGAR;
}
else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9679,11 +9727,11 @@
}
varName = Jim_GetString(objPtr, &len);
-
+
if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
return JIM_DICT_SUGAR;
}
if (varName[0] == ':' && varName[1] == ':') {
@@ -9695,23 +9743,23 @@
else {
global = 0;
framePtr = interp->framePtr;
}
-
+
he = Jim_FindHashEntry(&framePtr->vars, varName);
if (he == NULL) {
if (!global && framePtr->staticVars) {
-
+
he = Jim_FindHashEntry(framePtr->staticVars, varName);
}
if (he == NULL) {
return JIM_ERR;
}
}
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &variableObjType;
objPtr->internalRep.varValue.callFrameId = framePtr->id;
objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
objPtr->internalRep.varValue.global = global;
@@ -9726,11 +9774,11 @@
{
const char *name;
Jim_CallFrame *framePtr;
int global;
-
+
Jim_Var *var = Jim_Alloc(sizeof(*var));
var->objPtr = valObjPtr;
Jim_IncrRefCount(valObjPtr);
var->linkFramePtr = NULL;
@@ -9745,14 +9793,14 @@
else {
framePtr = interp->framePtr;
global = 0;
}
-
+
Jim_AddHashEntry(&framePtr->vars, name, var);
-
+
Jim_FreeIntRep(interp, nameObjPtr);
nameObjPtr->typePtr = &variableObjType;
nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
nameObjPtr->internalRep.varValue.varPtr = var;
nameObjPtr->internalRep.varValue.global = global;
@@ -9782,11 +9830,11 @@
if (var->linkFramePtr == NULL) {
Jim_IncrRefCount(valObjPtr);
Jim_DecrRefCount(interp, var->objPtr);
var->objPtr = valObjPtr;
}
- else {
+ else {
Jim_CallFrame *savedCallFrame;
savedCallFrame = interp->framePtr;
interp->framePtr = var->linkFramePtr;
err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9843,14 +9891,14 @@
const char *varName;
const char *targetName;
Jim_CallFrame *framePtr;
Jim_Var *varPtr;
-
+
switch (SetVariableFromAny(interp, nameObjPtr)) {
case JIM_DICT_SUGAR:
-
+
Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
return JIM_ERR;
case JIM_OK:
varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9858,23 +9906,23 @@
if (varPtr->linkFramePtr == NULL) {
Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
return JIM_ERR;
}
-
+
varPtr->linkFramePtr = NULL;
break;
}
-
-
+
+
varName = Jim_String(nameObjPtr);
if (varName[0] == ':' && varName[1] == ':') {
while (*++varName == ':') {
}
-
+
framePtr = interp->topFramePtr;
}
else {
framePtr = interp->framePtr;
}
@@ -9894,15 +9942,15 @@
nameObjPtr);
Jim_DecrRefCount(interp, targetNameObjPtr);
return JIM_ERR;
}
-
+
if (framePtr == targetCallFrame) {
Jim_Obj *objPtr = targetNameObjPtr;
-
+
while (1) {
if (strcmp(Jim_String(objPtr), varName) == 0) {
Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
Jim_DecrRefCount(interp, targetNameObjPtr);
return JIM_ERR;
@@ -9914,13 +9962,13 @@
break;
objPtr = varPtr->objPtr;
}
}
-
+
Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
-
+
nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
Jim_DecrRefCount(interp, targetNameObjPtr);
return JIM_OK;
}
@@ -9934,26 +9982,26 @@
return varPtr->objPtr;
}
else {
Jim_Obj *objPtr;
-
+
Jim_CallFrame *savedCallFrame = interp->framePtr;
interp->framePtr = varPtr->linkFramePtr;
objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
interp->framePtr = savedCallFrame;
if (objPtr) {
return objPtr;
}
-
+
}
}
break;
case JIM_DICT_SUGAR:
-
+
return JimDictSugarGet(interp, nameObjPtr, flags);
}
if (flags & JIM_ERRMSG) {
Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
}
@@ -10003,17 +10051,17 @@
int retval;
Jim_CallFrame *framePtr;
retval = SetVariableFromAny(interp, nameObjPtr);
if (retval == JIM_DICT_SUGAR) {
-
+
return JimDictSugarSet(interp, nameObjPtr, NULL);
}
else if (retval == JIM_OK) {
varPtr = nameObjPtr->internalRep.varValue.varPtr;
-
+
if (varPtr->linkFramePtr) {
framePtr = interp->framePtr;
interp->framePtr = varPtr->linkFramePtr;
retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
interp->framePtr = framePtr;
@@ -10028,11 +10076,11 @@
framePtr = interp->framePtr;
}
retval = Jim_DeleteHashEntry(&framePtr->vars, name);
if (retval == JIM_OK) {
-
+
framePtr->id = interp->callFrameEpoch++;
}
}
}
if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -10061,11 +10109,11 @@
keyLen = (str + len) - p;
if (str[len - 1] == ')') {
keyLen--;
}
-
+
keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
Jim_IncrRefCount(varObjPtr);
Jim_IncrRefCount(keyObjPtr);
*varPtrPtr = varObjPtr;
@@ -10080,23 +10128,23 @@
err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
&objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
if (err == JIM_OK) {
-
+
Jim_SetEmptyResult(interp);
}
else {
if (!valObjPtr) {
-
+
if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
objPtr);
return err;
}
}
-
+
Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
(valObjPtr ? "set" : "unset"), objPtr);
}
return err;
}
@@ -10118,11 +10166,11 @@
Jim_SetResultFormatted(interp,
"can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
ret < 0 ? "variable isn't" : "no such element in");
}
else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
-
+
Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
}
return resObjPtr;
}
@@ -10160,11 +10208,11 @@
{
if (objPtr->typePtr != &dictSubstObjType) {
Jim_Obj *varObjPtr, *keyObjPtr;
if (objPtr->typePtr == &interpolatedObjType) {
-
+
varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
Jim_IncrRefCount(varObjPtr);
@@ -10205,11 +10253,11 @@
static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
{
Jim_Obj *resultObjPtr;
if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
-
+
resultObjPtr->refCount--;
return resultObjPtr;
}
return NULL;
}
@@ -10249,11 +10297,11 @@
return cf;
}
static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
{
-
+
if (localCommands) {
Jim_Obj *cmdNameObj;
while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
Jim_HashEntry *he;
@@ -10268,20 +10316,20 @@
Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
if (cmd->prevCmd) {
Jim_Cmd *prevCmd = cmd->prevCmd;
cmd->prevCmd = NULL;
-
+
JimDecrCmdRefCount(interp, cmd);
-
+
Jim_SetHashVal(ht, he, prevCmd);
}
else {
Jim_DeleteHashEntry(ht, fqname);
- Jim_InterpIncrProcEpoch(interp);
}
+ Jim_InterpIncrProcEpoch(interp);
}
Jim_DecrRefCount(interp, cmdNameObj);
JimFreeQualifiedName(interp, fqObjName);
}
Jim_FreeStack(localCommands);
@@ -10289,12 +10337,12 @@
}
return JIM_OK;
}
-#define JIM_FCF_FULL 0
-#define JIM_FCF_REUSE 1
+#define JIM_FCF_FULL 0
+#define JIM_FCF_REUSE 1
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
{
JimDeleteLocalProcs(interp, cf->localCommands);
if (cf->procArgsObjPtr)
@@ -10327,263 +10375,10 @@
cf->next = interp->freeFramesList;
interp->freeFramesList = cf;
}
-#ifdef JIM_REFERENCES
-
-static void JimReferencesHTValDestructor(void *interp, void *val)
-{
- Jim_Reference *refPtr = (void *)val;
-
- Jim_DecrRefCount(interp, refPtr->objPtr);
- if (refPtr->finalizerCmdNamePtr != NULL) {
- Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
- }
- Jim_Free(val);
-}
-
-static unsigned int JimReferencesHTHashFunction(const void *key)
-{
-
- const unsigned long *widePtr = key;
- unsigned int intValue = (unsigned int)*widePtr;
-
- return Jim_IntHashFunction(intValue);
-}
-
-static void *JimReferencesHTKeyDup(void *privdata, const void *key)
-{
- void *copy = Jim_Alloc(sizeof(unsigned long));
-
- JIM_NOTUSED(privdata);
-
- memcpy(copy, key, sizeof(unsigned long));
- return copy;
-}
-
-static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2)
-{
- JIM_NOTUSED(privdata);
-
- return memcmp(key1, key2, sizeof(unsigned long)) == 0;
-}
-
-static void JimReferencesHTKeyDestructor(void *privdata, void *key)
-{
- JIM_NOTUSED(privdata);
-
- Jim_Free(key);
-}
-
-static const Jim_HashTableType JimReferencesHashTableType = {
- JimReferencesHTHashFunction,
- JimReferencesHTKeyDup,
- NULL,
- JimReferencesHTKeyCompare,
- JimReferencesHTKeyDestructor,
- JimReferencesHTValDestructor
-};
-
-
-
-#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
-
-static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
-{
- const char *fmt = ".%020lu>";
-
- sprintf(buf, fmt, refPtr->tag, id);
- return JIM_REFERENCE_SPACE;
-}
-
-static void UpdateStringOfReference(struct Jim_Obj *objPtr);
-
-static const Jim_ObjType referenceObjType = {
- "reference",
- NULL,
- NULL,
- UpdateStringOfReference,
- JIM_TYPE_REFERENCES,
-};
-
-static void UpdateStringOfReference(struct Jim_Obj *objPtr)
-{
- char buf[JIM_REFERENCE_SPACE + 1];
-
- JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id);
- JimSetStringBytes(objPtr, buf);
-}
-
-static int isrefchar(int c)
-{
- return (c == '_' || isalnum(c));
-}
-
-static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
-{
- unsigned long value;
- int i, len;
- const char *str, *start, *end;
- char refId[21];
- Jim_Reference *refPtr;
- Jim_HashEntry *he;
- char *endptr;
-
-
- str = Jim_GetString(objPtr, &len);
-
- if (len < JIM_REFERENCE_SPACE)
- goto badformat;
-
- start = str;
- end = str + len - 1;
- while (*start == ' ')
- start++;
- while (*end == ' ' && end > start)
- end--;
- if (end - start + 1 != JIM_REFERENCE_SPACE)
- goto badformat;
-
- if (memcmp(start, "' || end[0] != '>')
- goto badformat;
-
- for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
- if (!isrefchar(start[12 + i]))
- goto badformat;
- }
-
- memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
- refId[20] = '\0';
-
- value = strtoul(refId, &endptr, 10);
- if (JimCheckConversion(refId, endptr) != JIM_OK)
- goto badformat;
-
- he = Jim_FindHashEntry(&interp->references, &value);
- if (he == NULL) {
- Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
- return JIM_ERR;
- }
- refPtr = Jim_GetHashEntryVal(he);
-
- Jim_FreeIntRep(interp, objPtr);
- objPtr->typePtr = &referenceObjType;
- objPtr->internalRep.refValue.id = value;
- objPtr->internalRep.refValue.refPtr = refPtr;
- return JIM_OK;
-
- badformat:
- Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
- return JIM_ERR;
-}
-
-Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
-{
- struct Jim_Reference *refPtr;
- unsigned long id;
- Jim_Obj *refObjPtr;
- const char *tag;
- int tagLen, i;
-
-
- Jim_CollectIfNeeded(interp);
-
- refPtr = Jim_Alloc(sizeof(*refPtr));
- refPtr->objPtr = objPtr;
- Jim_IncrRefCount(objPtr);
- refPtr->finalizerCmdNamePtr = cmdNamePtr;
- if (cmdNamePtr)
- Jim_IncrRefCount(cmdNamePtr);
- id = interp->referenceNextId++;
- Jim_AddHashEntry(&interp->references, &id, refPtr);
- refObjPtr = Jim_NewObj(interp);
- refObjPtr->typePtr = &referenceObjType;
- refObjPtr->bytes = NULL;
- refObjPtr->internalRep.refValue.id = id;
- refObjPtr->internalRep.refValue.refPtr = refPtr;
- interp->referenceNextId++;
- tag = Jim_GetString(tagPtr, &tagLen);
- if (tagLen > JIM_REFERENCE_TAGLEN)
- tagLen = JIM_REFERENCE_TAGLEN;
- for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
- if (i < tagLen && isrefchar(tag[i]))
- refPtr->tag[i] = tag[i];
- else
- refPtr->tag[i] = '_';
- }
- refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0';
- return refObjPtr;
-}
-
-Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr)
-{
- if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR)
- return NULL;
- return objPtr->internalRep.refValue.refPtr;
-}
-
-int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr)
-{
- Jim_Reference *refPtr;
-
- if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
- return JIM_ERR;
- Jim_IncrRefCount(cmdNamePtr);
- if (refPtr->finalizerCmdNamePtr)
- Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
- refPtr->finalizerCmdNamePtr = cmdNamePtr;
- return JIM_OK;
-}
-
-int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr)
-{
- Jim_Reference *refPtr;
-
- if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
- return JIM_ERR;
- *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr;
- return JIM_OK;
-}
-
-
-
-static const Jim_HashTableType JimRefMarkHashTableType = {
- JimReferencesHTHashFunction,
- JimReferencesHTKeyDup,
- NULL,
- JimReferencesHTKeyCompare,
- JimReferencesHTKeyDestructor,
- NULL
-};
-
-
-int Jim_Collect(Jim_Interp *interp)
-{
- int collected = 0;
- return collected;
-}
-
-#define JIM_COLLECT_ID_PERIOD 5000
-#define JIM_COLLECT_TIME_PERIOD 300
-
-void Jim_CollectIfNeeded(Jim_Interp *interp)
-{
- unsigned long elapsedId;
- int elapsedTime;
-
- elapsedId = interp->referenceNextId - interp->lastCollectId;
- elapsedTime = time(NULL) - interp->lastCollectTime;
-
-
- if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) {
- Jim_Collect(interp);
- }
-}
-#endif
int Jim_IsBigEndian(void)
{
union {
unsigned short s;
@@ -10630,11 +10425,11 @@
Jim_IncrRefCount(i->nullScriptObj);
Jim_IncrRefCount(i->errorProc);
Jim_IncrRefCount(i->trueObj);
Jim_IncrRefCount(i->falseObj);
-
+
Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim");
Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
@@ -10652,11 +10447,11 @@
{
Jim_CallFrame *cf, *cfx;
Jim_Obj *objPtr, *nextObjPtr;
-
+
for (cf = i->framePtr; cf; cf = cfx) {
cfx = cf->parent;
JimFreeCallFrame(i, cf, JIM_FCF_FULL);
}
@@ -10705,27 +10500,27 @@
printf("-------------------------------------\n\n");
JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
}
#endif
-
+
objPtr = i->freeList;
while (objPtr) {
nextObjPtr = objPtr->nextObjPtr;
Jim_Free(objPtr);
objPtr = nextObjPtr;
}
-
+
for (cf = i->freeFramesList; cf; cf = cfx) {
cfx = cf->next;
if (cf->vars.table)
Jim_FreeHashTable(&cf->vars);
Jim_Free(cf);
}
-
+
Jim_Free(i);
}
Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
{
@@ -10746,25 +10541,25 @@
else {
if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
level = -1;
}
else {
-
+
level = interp->framePtr->level - level;
}
}
}
else {
- str = "1";
+ str = "1";
level = interp->framePtr->level - 1;
}
if (level == 0) {
return interp->topFramePtr;
}
if (level > 0) {
-
+
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
if (framePtr->level == level) {
return framePtr;
}
}
@@ -10779,19 +10574,19 @@
long level;
Jim_CallFrame *framePtr;
if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
if (level <= 0) {
-
+
level = interp->framePtr->level + level;
}
if (level == 0) {
return interp->topFramePtr;
}
-
+
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
if (framePtr->level == level) {
return framePtr;
}
}
@@ -10810,11 +10605,11 @@
static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
{
int len;
-
+
Jim_IncrRefCount(stackTraceObj);
Jim_DecrRefCount(interp, interp->stackTrace);
interp->stackTrace = stackTraceObj;
interp->errorFlag = 1;
@@ -10831,32 +10626,32 @@
{
if (strcmp(procname, "unknown") == 0) {
procname = "";
}
if (!*procname && !Jim_Length(fileNameObj)) {
-
+
return;
}
if (Jim_IsShared(interp->stackTrace)) {
Jim_DecrRefCount(interp, interp->stackTrace);
interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
Jim_IncrRefCount(interp->stackTrace);
}
-
+
if (!*procname && Jim_Length(fileNameObj)) {
-
+
int len = Jim_ListLength(interp, interp->stackTrace);
if (len >= 3) {
Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
if (Jim_Length(objPtr)) {
-
+
objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
if (Jim_Length(objPtr) == 0) {
-
+
ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
return;
}
}
@@ -10958,18 +10753,18 @@
{
jim_wide wideValue;
const char *str;
if (objPtr->typePtr == &coercedDoubleObjType) {
-
+
objPtr->typePtr = &intObjType;
return JIM_OK;
}
-
+
str = Jim_String(objPtr);
-
+
if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
if (flags & JIM_ERRMSG) {
Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
}
return JIM_ERR;
@@ -10976,11 +10771,11 @@
}
if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
Jim_SetResultString(interp, "Integer value too big to be represented", -1);
return JIM_ERR;
}
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &intObjType;
objPtr->internalRep.wideValue = wideValue;
return JIM_OK;
}
@@ -11075,17 +10870,17 @@
{
char buf[JIM_DOUBLE_SPACE + 1];
int i;
int len = sprintf(buf, "%.12g", value);
-
+
for (i = 0; i < len; i++) {
if (buf[i] == '.' || buf[i] == 'e') {
#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
char *e = strchr(buf, 'e');
if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
-
+
e += 2;
memmove(e, e + 1, len - (e - buf));
}
#endif
break;
@@ -11107,38 +10902,38 @@
const char *str;
str = Jim_String(objPtr);
#ifdef HAVE_LONG_LONG
-
+
#define MIN_INT_IN_DOUBLE -(1LL << 53)
#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
if (objPtr->typePtr == &intObjType
&& JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
&& JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
-
+
objPtr->typePtr = &coercedDoubleObjType;
return JIM_OK;
}
else
#endif
if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &coercedDoubleObjType;
objPtr->internalRep.wideValue = wideValue;
return JIM_OK;
}
else {
-
+
if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
return JIM_ERR;
}
-
+
Jim_FreeIntRep(interp, objPtr);
}
objPtr->typePtr = &doubleObjType;
objPtr->internalRep.doubleValue = doubleValue;
return JIM_OK;
@@ -11170,10 +10965,50 @@
objPtr->typePtr = &doubleObjType;
objPtr->bytes = NULL;
objPtr->internalRep.doubleValue = doubleValue;
return objPtr;
}
+
+static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags);
+
+int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr)
+{
+ if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR)
+ return JIM_ERR;
+ *booleanPtr = (int) JimWideValue(objPtr);
+ return JIM_OK;
+}
+
+static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
+{
+ static const char * const falses[] = {
+ "0", "false", "no", "off", NULL
+ };
+ static const char * const trues[] = {
+ "1", "true", "yes", "on", NULL
+ };
+
+ int boolean;
+
+ int index;
+ if (Jim_GetEnum(interp, objPtr, falses, &index, NULL, 0) == JIM_OK) {
+ boolean = 0;
+ } else if (Jim_GetEnum(interp, objPtr, trues, &index, NULL, 0) == JIM_OK) {
+ boolean = 1;
+ } else {
+ if (flags & JIM_ERRMSG) {
+ Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr);
+ }
+ return JIM_ERR;
+ }
+
+
+ Jim_FreeIntRep(interp, objPtr);
+ objPtr->typePtr = &intObjType;
+ objPtr->internalRep.wideValue = boolean;
+ return JIM_OK;
+}
static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -11221,11 +11056,11 @@
#define JIM_ELESTR_QUOTE 2
static unsigned char ListElementQuotingType(const char *s, int len)
{
int i, level, blevel, trySimple = 1;
-
+
if (len == 0)
return JIM_ELESTR_BRACE;
if (s[0] == '"' || s[0] == '{') {
trySimple = 0;
goto testbrace;
@@ -11243,20 +11078,20 @@
case '\n':
case '\t':
case '\f':
case '\v':
trySimple = 0;
-
+
case '{':
case '}':
goto testbrace;
}
}
return JIM_ELESTR_SIMPLE;
testbrace:
-
+
if (s[len - 1] == '\\')
return JIM_ELESTR_QUOTE;
level = 0;
blevel = 0;
for (i = 0; i < len; i++) {
@@ -11372,11 +11207,11 @@
int i, bufLen, realLength;
const char *strRep;
char *p;
unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
-
+
if (objc > STATIC_QUOTING_LEN) {
quotingType = Jim_Alloc(objc);
}
else {
quotingType = staticQuoting;
@@ -11391,25 +11226,25 @@
case JIM_ELESTR_SIMPLE:
if (i != 0 || strRep[0] != '#') {
bufLen += len;
break;
}
-
+
quotingType[i] = JIM_ELESTR_BRACE;
-
+
case JIM_ELESTR_BRACE:
bufLen += len + 2;
break;
case JIM_ELESTR_QUOTE:
bufLen += len * 2;
break;
}
- bufLen++;
+ bufLen++;
}
bufLen++;
-
+
p = objPtr->bytes = Jim_Alloc(bufLen + 1);
realLength = 0;
for (i = 0; i < objc; i++) {
int len, qlen;
@@ -11436,17 +11271,17 @@
qlen = BackslashQuoteString(strRep, len, p);
p += qlen;
realLength += qlen;
break;
}
-
+
if (i + 1 != objc) {
*p++ = ' ';
realLength++;
}
}
- *p = '\0';
+ *p = '\0';
objPtr->length = realLength;
if (quotingType != staticQuoting) {
Jim_Free(quotingType);
}
@@ -11477,21 +11312,21 @@
listObjPtrPtr = JimDictPairs(objPtr, &len);
for (i = 0; i < len; i++) {
Jim_IncrRefCount(listObjPtrPtr[i]);
}
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &listObjType;
objPtr->internalRep.listValue.len = len;
objPtr->internalRep.listValue.maxLen = len;
objPtr->internalRep.listValue.ele = listObjPtrPtr;
return JIM_OK;
}
-
+
if (objPtr->typePtr == &sourceObjType) {
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
linenr = objPtr->internalRep.sourceValue.lineNumber;
}
else {
@@ -11498,20 +11333,20 @@
fileNameObj = interp->emptyObj;
linenr = 1;
}
Jim_IncrRefCount(fileNameObj);
-
+
str = Jim_GetString(objPtr, &strLen);
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &listObjType;
objPtr->internalRep.listValue.len = 0;
objPtr->internalRep.listValue.maxLen = 0;
objPtr->internalRep.listValue.ele = NULL;
-
+
if (strLen) {
JimParserInit(&parser, str, strLen, linenr);
while (!parser.eof) {
Jim_Obj *elementPtr;
@@ -11641,11 +11476,11 @@
Jim_Obj *compare_script;
int rc;
jim_wide ret = 0;
-
+
compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11663,23 +11498,23 @@
int dst = 0;
Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
if (comp(&ele[dst], &ele[src]) == 0) {
-
+
Jim_DecrRefCount(sort_info->interp, ele[dst]);
}
else {
-
+
dst++;
}
ele[dst] = ele[src];
}
-
+
ele[++dst] = ele[src];
-
+
listObjPtr->internalRep.listValue.len = dst;
}
static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11693,11 +11528,11 @@
int rc;
JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
SetListFromAny(interp, listObjPtr);
-
+
prev_info = sort_info;
sort_info = info;
vector = listObjPtr->internalRep.listValue.ele;
len = listObjPtr->internalRep.listValue.len;
@@ -11716,17 +11551,17 @@
break;
case JIM_LSORT_COMMAND:
fn = ListSortCommand;
break;
default:
- fn = NULL;
+ fn = NULL;
JimPanic((1, "ListSort called with invalid sort type"));
- return -1;
+ return -1;
}
if (info->indexed) {
-
+
info->subfn = fn;
fn = ListSortIndexHelper;
}
if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11750,11 +11585,11 @@
int i;
Jim_Obj **point;
if (requiredLen > listPtr->internalRep.listValue.maxLen) {
if (requiredLen < 2) {
-
+
requiredLen = 4;
}
else {
requiredLen *= 2;
}
@@ -11936,34 +11771,34 @@
for (i = 0; i < objc; i++)
ListAppendList(objPtr, objv[i]);
return objPtr;
}
else {
-
+
int len = 0, objLen;
char *bytes, *p;
-
+
for (i = 0; i < objc; i++) {
len += Jim_Length(objv[i]);
}
if (objc)
len += objc - 1;
-
+
p = bytes = Jim_Alloc(len + 1);
for (i = 0; i < objc; i++) {
const char *s = Jim_GetString(objv[i], &objLen);
-
+
while (objLen && isspace(UCHAR(*s))) {
s++;
objLen--;
len--;
}
-
+
while (objLen && isspace(UCHAR(s[objLen - 1]))) {
-
+
if (objLen > 1 && s[objLen - 2] == '\\') {
break;
}
objLen--;
len--;
@@ -11990,11 +11825,11 @@
int len, rangeLen;
if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
return NULL;
- len = Jim_ListLength(interp, listObjPtr);
+ len = Jim_ListLength(interp, listObjPtr);
first = JimRelToAbsIndex(len, first);
last = JimRelToAbsIndex(len, last);
JimRelToAbsRange(len, &first, &last, &rangeLen);
if (first == 0 && last == len) {
return listObjPtr;
@@ -12030,16 +11865,16 @@
{
Jim_DecrRefCount(interp, (Jim_Obj *)val);
}
static const Jim_HashTableType JimDictHashTableType = {
- JimObjectHTHashFunction,
- JimObjectHTKeyValDup,
- JimObjectHTKeyValDup,
- JimObjectHTKeyCompare,
- JimObjectHTKeyValDestructor,
- JimObjectHTKeyValDestructor
+ JimObjectHTHashFunction,
+ JimObjectHTKeyValDup,
+ JimObjectHTKeyValDup,
+ JimObjectHTKeyCompare,
+ JimObjectHTKeyValDestructor,
+ JimObjectHTKeyValDestructor
};
static const Jim_ObjType dictObjType = {
"dict",
FreeDictInternalRep,
@@ -12060,17 +11895,17 @@
{
Jim_HashTable *ht, *dupHt;
Jim_HashTableIterator htiter;
Jim_HashEntry *he;
-
+
ht = srcPtr->internalRep.ptr;
dupHt = Jim_Alloc(sizeof(*dupHt));
Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
if (ht->size != 0)
Jim_ExpandHashTable(dupHt, ht->size);
-
+
JimInitHashTableIterator(ht, &htiter);
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
Jim_AddHashEntry(dupHt, he->key, he->u.val);
}
@@ -12086,11 +11921,11 @@
Jim_Obj **objv;
int i;
ht = dictPtr->internalRep.ptr;
-
+
objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
JimInitHashTableIterator(ht, &htiter);
i = 0;
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
objv[i++] = Jim_GetHashEntryKey(he);
@@ -12100,15 +11935,15 @@
return objv;
}
static void UpdateStringOfDict(struct Jim_Obj *objPtr)
{
-
+
int len;
Jim_Obj **objv = JimDictPairs(objPtr, &len);
-
+
JimMakeListStringRep(objPtr, objv, len);
Jim_Free(objv);
}
@@ -12122,18 +11957,18 @@
if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
Jim_String(objPtr);
}
-
+
listlen = Jim_ListLength(interp, objPtr);
if (listlen % 2) {
Jim_SetResultString(interp, "missing value to go with key", -1);
return JIM_ERR;
}
else {
-
+
Jim_HashTable *ht;
int i;
ht = Jim_Alloc(sizeof(*ht));
Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -12158,11 +11993,11 @@
static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
{
Jim_HashTable *ht = objPtr->internalRep.ptr;
- if (valueObjPtr == NULL) {
+ if (valueObjPtr == NULL) {
return Jim_DeleteHashEntry(ht, keyObjPtr);
}
Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
return JIM_OK;
}
@@ -12258,11 +12093,11 @@
int shared, i;
varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
if (objPtr == NULL) {
if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
-
+
return JIM_ERR;
}
varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
Jim_FreeNewObj(interp, varObjPtr);
@@ -12272,26 +12107,26 @@
if ((shared = Jim_IsShared(objPtr)))
varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
for (i = 0; i < keyc; i++) {
dictObjPtr = objPtr;
-
+
if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
goto err;
}
if (i == keyc - 1) {
-
+
if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
if (newObjPtr || (flags & JIM_MUSTEXIST)) {
goto err;
}
}
break;
}
-
+
Jim_InvalidateStringRep(dictObjPtr);
if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
if (Jim_IsShared(objPtr)) {
objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12304,11 +12139,11 @@
}
objPtr = Jim_NewDictObj(interp, NULL, 0);
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
}
}
-
+
Jim_InvalidateStringRep(objPtr);
Jim_InvalidateStringRep(varObjPtr);
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
goto err;
}
@@ -12341,11 +12176,11 @@
char buf[JIM_INTEGER_SPACE + 1];
if (objPtr->internalRep.intValue >= 0) {
sprintf(buf, "%d", objPtr->internalRep.intValue);
}
else {
-
+
sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
}
JimSetStringBytes(objPtr, buf);
}
}
@@ -12354,14 +12189,14 @@
{
int idx, end = 0;
const char *str;
char *endptr;
-
+
str = Jim_String(objPtr);
-
+
if (strncmp(str, "end", 3) == 0) {
end = 1;
str += 3;
idx = 0;
}
@@ -12372,21 +12207,21 @@
goto badindex;
}
str = endptr;
}
-
+
if (*str == '+' || *str == '-') {
int sign = (*str == '+' ? 1 : -1);
idx += sign * jim_strtol(++str, &endptr);
if (str == endptr || *endptr) {
goto badindex;
}
str = endptr;
}
-
+
while (isspace(UCHAR(*str))) {
str++;
}
if (*str) {
goto badindex;
@@ -12394,19 +12229,19 @@
if (end) {
if (idx > 0) {
idx = INT_MAX;
}
else {
-
+
idx--;
}
}
else if (idx < 0) {
idx = -INT_MAX;
}
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &indexObjType;
objPtr->internalRep.intValue = idx;
return JIM_OK;
@@ -12416,11 +12251,11 @@
return JIM_ERR;
}
int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
{
-
+
if (objPtr->typePtr == &intObjType) {
jim_wide val = JimWideValue(objPtr);
if (val < 0)
*indexPtr = -INT_MAX;
@@ -12473,18 +12308,18 @@
static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
int returnCode;
jim_wide wideValue;
-
+
if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
returnCode = (int)wideValue;
else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
return JIM_ERR;
}
-
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &returnCodeObjType;
objPtr->internalRep.intValue = returnCode;
return JIM_OK;
}
@@ -12498,19 +12333,20 @@
}
static int JimParseExprOperator(struct JimParserCtx *pc);
static int JimParseExprNumber(struct JimParserCtx *pc);
static int JimParseExprIrrational(struct JimParserCtx *pc);
+static int JimParseExprBoolean(struct JimParserCtx *pc);
enum
{
-
-
- JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
+
+
+ JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
JIM_EXPROP_DIV,
JIM_EXPROP_MOD,
JIM_EXPROP_SUB,
JIM_EXPROP_ADD,
JIM_EXPROP_LSHIFT,
@@ -12521,66 +12357,67 @@
JIM_EXPROP_GT,
JIM_EXPROP_LTE,
JIM_EXPROP_GTE,
JIM_EXPROP_NUMEQ,
JIM_EXPROP_NUMNE,
- JIM_EXPROP_BITAND,
+ JIM_EXPROP_BITAND,
JIM_EXPROP_BITXOR,
JIM_EXPROP_BITOR,
-
- JIM_EXPROP_LOGICAND,
+
+ JIM_EXPROP_LOGICAND,
JIM_EXPROP_LOGICAND_LEFT,
JIM_EXPROP_LOGICAND_RIGHT,
-
- JIM_EXPROP_LOGICOR,
+
+ JIM_EXPROP_LOGICOR,
JIM_EXPROP_LOGICOR_LEFT,
JIM_EXPROP_LOGICOR_RIGHT,
-
-
- JIM_EXPROP_TERNARY,
+
+
+ JIM_EXPROP_TERNARY,
JIM_EXPROP_TERNARY_LEFT,
JIM_EXPROP_TERNARY_RIGHT,
-
- JIM_EXPROP_COLON,
+
+ JIM_EXPROP_COLON,
JIM_EXPROP_COLON_LEFT,
JIM_EXPROP_COLON_RIGHT,
- JIM_EXPROP_POW,
+ JIM_EXPROP_POW,
- JIM_EXPROP_STREQ,
+ JIM_EXPROP_STREQ,
JIM_EXPROP_STRNE,
JIM_EXPROP_STRIN,
JIM_EXPROP_STRNI,
- JIM_EXPROP_NOT,
+ JIM_EXPROP_NOT,
JIM_EXPROP_BITNOT,
JIM_EXPROP_UNARYMINUS,
JIM_EXPROP_UNARYPLUS,
-
- JIM_EXPROP_FUNC_FIRST,
+
+ JIM_EXPROP_FUNC_FIRST,
JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
JIM_EXPROP_FUNC_WIDE,
JIM_EXPROP_FUNC_ABS,
JIM_EXPROP_FUNC_DOUBLE,
JIM_EXPROP_FUNC_ROUND,
JIM_EXPROP_FUNC_RAND,
JIM_EXPROP_FUNC_SRAND,
-
- JIM_EXPROP_FUNC_SIN,
+
+ JIM_EXPROP_FUNC_SIN,
JIM_EXPROP_FUNC_COS,
JIM_EXPROP_FUNC_TAN,
JIM_EXPROP_FUNC_ASIN,
JIM_EXPROP_FUNC_ACOS,
JIM_EXPROP_FUNC_ATAN,
+ JIM_EXPROP_FUNC_ATAN2,
JIM_EXPROP_FUNC_SINH,
JIM_EXPROP_FUNC_COSH,
JIM_EXPROP_FUNC_TANH,
JIM_EXPROP_FUNC_CEIL,
JIM_EXPROP_FUNC_FLOOR,
@@ -12587,10 +12424,12 @@
JIM_EXPROP_FUNC_EXP,
JIM_EXPROP_FUNC_LOG,
JIM_EXPROP_FUNC_LOG10,
JIM_EXPROP_FUNC_SQRT,
JIM_EXPROP_FUNC_POW,
+ JIM_EXPROP_FUNC_HYPOT,
+ JIM_EXPROP_FUNC_FMOD,
};
struct JimExprState
{
Jim_Obj **stack;
@@ -12667,11 +12506,15 @@
case JIM_EXPROP_UNARYPLUS:
dC = dA;
intresult = 0;
break;
case JIM_EXPROP_FUNC_ABS:
+#ifdef JIM_MATH_FUNCTIONS
+ dC = fabs(dA);
+#else
dC = dA >= 0 ? dA : -dA;
+#endif
intresult = 0;
break;
case JIM_EXPROP_UNARYMINUS:
dC = -dA;
intresult = 0;
@@ -12859,16 +12702,16 @@
}
}
break;
case JIM_EXPROP_ROTL:
case JIM_EXPROP_ROTR:{
-
+
unsigned long uA = (unsigned long)wA;
unsigned long uB = (unsigned long)wB;
const unsigned int S = sizeof(unsigned long) * 8;
-
+
uB %= S;
if (e->opcode == JIM_EXPROP_ROTR) {
uB = S - uB;
}
@@ -12890,11 +12733,10 @@
static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
{
- int intresult = 1;
int rc = JIM_OK;
double dA, dB, dC = 0;
jim_wide wA, wB, wC = 0;
Jim_Obj *B = ExprPop(e);
@@ -12902,30 +12744,36 @@
if ((A->typePtr != &doubleObjType || A->bytes) &&
(B->typePtr != &doubleObjType || B->bytes) &&
JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
-
+
switch (e->opcode) {
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
+ if (wA == 0 && wB < 0) {
+ Jim_SetResultString(interp, "exponentiation of zero by negative power", -1);
+ rc = JIM_ERR;
+ goto done;
+ }
wC = JimPowWide(wA, wB);
- break;
+ goto intresult;
case JIM_EXPROP_ADD:
wC = wA + wB;
- break;
+ goto intresult;
case JIM_EXPROP_SUB:
wC = wA - wB;
- break;
+ goto intresult;
case JIM_EXPROP_MUL:
wC = wA * wB;
- break;
+ goto intresult;
case JIM_EXPROP_DIV:
if (wB == 0) {
Jim_SetResultString(interp, "Division by zero", -1);
rc = JIM_ERR;
+ goto done;
}
else {
if (wB < 0) {
wB = -wB;
wA = -wA;
@@ -12932,55 +12780,67 @@
}
wC = wA / wB;
if (wA % wB < 0) {
wC--;
}
+ goto intresult;
}
- break;
case JIM_EXPROP_LT:
wC = wA < wB;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = wA > wB;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = wA <= wB;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = wA >= wB;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = wA == wB;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = wA != wB;
- break;
- default:
- abort();
+ goto intresult;
}
}
- else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
- intresult = 0;
+ if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
switch (e->opcode) {
+#ifndef JIM_MATH_FUNCTIONS
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
-#ifdef JIM_MATH_FUNCTIONS
- dC = pow(dA, dB);
-#else
+ case JIM_EXPROP_FUNC_ATAN2:
+ case JIM_EXPROP_FUNC_HYPOT:
+ case JIM_EXPROP_FUNC_FMOD:
Jim_SetResultString(interp, "unsupported", -1);
rc = JIM_ERR;
+ goto done;
+#else
+ case JIM_EXPROP_POW:
+ case JIM_EXPROP_FUNC_POW:
+ dC = pow(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_ATAN2:
+ dC = atan2(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_HYPOT:
+ dC = hypot(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_FMOD:
+ dC = fmod(dA, dB);
+ goto doubleresult;
#endif
- break;
case JIM_EXPROP_ADD:
dC = dA + dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_SUB:
dC = dA - dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_MUL:
dC = dA * dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_DIV:
if (dB == 0) {
#ifdef INFINITY
dC = dA < 0 ? -INFINITY : INFINITY;
#else
@@ -12988,83 +12848,70 @@
#endif
}
else {
dC = dA / dB;
}
- break;
+ goto doubleresult;
case JIM_EXPROP_LT:
wC = dA < dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = dA > dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = dA <= dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = dA >= dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = dA == dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = dA != dB;
- intresult = 1;
- break;
- default:
- abort();
+ goto intresult;
}
}
else {
-
-
+
+
int i = Jim_StringCompareObj(interp, A, B, 0);
switch (e->opcode) {
case JIM_EXPROP_LT:
wC = i < 0;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = i > 0;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = i <= 0;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = i >= 0;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = i == 0;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = i != 0;
- break;
- default:
- rc = JIM_ERR;
- break;
+ goto intresult;
}
}
- if (rc == JIM_OK) {
- if (intresult) {
- ExprPush(e, Jim_NewIntObj(interp, wC));
- }
- else {
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
- }
- }
-
+ rc = JIM_ERR;
+done:
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, B);
-
return rc;
+intresult:
+ ExprPush(e, Jim_NewIntObj(interp, wC));
+ goto done;
+doubleresult:
+ ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ goto done;
}
static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
{
int listlen;
@@ -13113,16 +12960,20 @@
static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
{
long l;
double d;
+ int b;
if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
return l != 0;
}
if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
return d != 0;
+ }
+ if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
+ return b != 0;
}
return -1;
}
static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
@@ -13131,21 +12982,21 @@
Jim_Obj *A = ExprPop(e);
int rc = JIM_OK;
switch (ExprBool(interp, A)) {
case 0:
-
+
e->skip = JimWideValue(skip);
ExprPush(e, Jim_NewIntObj(interp, 0));
break;
case 1:
-
+
break;
case -1:
-
+
rc = JIM_ERR;
}
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, skip);
@@ -13158,21 +13009,21 @@
Jim_Obj *A = ExprPop(e);
int rc = JIM_OK;
switch (ExprBool(interp, A)) {
case 0:
-
+
break;
case 1:
-
+
e->skip = JimWideValue(skip);
ExprPush(e, Jim_NewIntObj(interp, 1));
break;
case -1:
-
+
rc = JIM_ERR;
break;
}
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, skip);
@@ -13193,11 +13044,11 @@
case 1:
ExprPush(e, Jim_NewIntObj(interp, 1));
break;
case -1:
-
+
rc = JIM_ERR;
break;
}
Jim_DecrRefCount(interp, A);
@@ -13208,27 +13059,27 @@
{
Jim_Obj *skip = ExprPop(e);
Jim_Obj *A = ExprPop(e);
int rc = JIM_OK;
-
+
ExprPush(e, A);
switch (ExprBool(interp, A)) {
case 0:
-
+
e->skip = JimWideValue(skip);
-
+
ExprPush(e, Jim_NewIntObj(interp, 0));
break;
case 1:
-
+
break;
case -1:
-
+
rc = JIM_ERR;
break;
}
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, skip);
@@ -13240,15 +13091,15 @@
{
Jim_Obj *skip = ExprPop(e);
Jim_Obj *B = ExprPop(e);
Jim_Obj *A = ExprPop(e);
-
+
if (ExprBool(interp, A)) {
-
+
e->skip = JimWideValue(skip);
-
+
ExprPush(e, B);
}
Jim_DecrRefCount(interp, skip);
Jim_DecrRefCount(interp, A);
@@ -13264,15 +13115,16 @@
enum
{
LAZY_NONE,
LAZY_OP,
LAZY_LEFT,
- LAZY_RIGHT
+ LAZY_RIGHT,
+ RIGHT_ASSOC,
};
-#define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1}
-#define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1}
+#define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1}
+#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, LAZY_NONE)
static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("*", 110, 2, JimExprOpBin),
OPRINIT("/", 110, 2, JimExprOpBin),
OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13296,27 +13148,28 @@
OPRINIT("&", 50, 2, JimExprOpIntBin),
OPRINIT("^", 49, 2, JimExprOpIntBin),
OPRINIT("|", 48, 2, JimExprOpIntBin),
- OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP),
- OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
- OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
-
- OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP),
- OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
- OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
-
- OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP),
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
-
- OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP),
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
-
- OPRINIT("**", 250, 2, JimExprOpBin),
+ OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP),
+ OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
+ OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
+
+ OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP),
+ OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
+ OPRINIT_ATTR(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
+
+ OPRINIT_ATTR("?", 5, 2, JimExprOpNull, LAZY_OP),
+ OPRINIT_ATTR(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
+ OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
+
+ OPRINIT_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP),
+ OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
+ OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
+
+
+ OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC),
OPRINIT("eq", 60, 2, JimExprOpStrBin),
OPRINIT("ne", 60, 2, JimExprOpStrBin),
OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13342,10 +13195,11 @@
OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
+ OPRINIT("atan2", 200, 2, JimExprOpBin),
OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13352,10 +13206,12 @@
OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
OPRINIT("pow", 200, 2, JimExprOpBin),
+ OPRINIT("hypot", 200, 2, JimExprOpBin),
+ OPRINIT("fmod", 200, 2, JimExprOpBin),
#endif
};
#undef OPRINIT
#undef OPRINIT_LAZY
@@ -13362,20 +13218,20 @@
#define JIM_EXPR_OPERATORS_NUM \
(sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
static int JimParseExpression(struct JimParserCtx *pc)
{
-
+
while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
if (*pc->p == '\n') {
pc->linenr++;
}
pc->p++;
pc->len--;
}
-
+
pc->tline = pc->linenr;
pc->tstart = pc->p;
if (pc->len == 0) {
pc->tend = pc->p;
@@ -13401,11 +13257,11 @@
return JimParseCmd(pc);
case '$':
if (JimParseVar(pc) == JIM_ERR)
return JimParseExprOperator(pc);
else {
-
+
if (pc->tt == JIM_TT_EXPRSUGAR) {
return JIM_ERR;
}
return JIM_OK;
}
@@ -13430,10 +13286,18 @@
case 'N':
case 'I':
case 'n':
case 'i':
if (JimParseExprIrrational(pc) == JIM_ERR)
+ if (JimParseExprBoolean(pc) == JIM_ERR)
+ return JimParseExprOperator(pc);
+ break;
+ case 't':
+ case 'f':
+ case 'o':
+ case 'y':
+ if (JimParseExprBoolean(pc) == JIM_ERR)
return JimParseExprOperator(pc);
break;
default:
return JimParseExprOperator(pc);
break;
@@ -13443,21 +13307,21 @@
static int JimParseExprNumber(struct JimParserCtx *pc)
{
char *end;
-
+
pc->tt = JIM_TT_EXPR_INT;
jim_strtoull(pc->p, (char **)&pc->p);
-
+
if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
- if (strtod(pc->tstart, &end)) { }
+ if (strtod(pc->tstart, &end)) { }
if (end == pc->tstart)
return JIM_ERR;
if (end > pc->p) {
-
+
pc->tt = JIM_TT_EXPR_DOUBLE;
pc->p = end;
}
}
pc->tend = pc->p - 1;
@@ -13481,17 +13345,38 @@
return JIM_OK;
}
}
return JIM_ERR;
}
+
+static int JimParseExprBoolean(struct JimParserCtx *pc)
+{
+ const char *booleans[] = { "false", "no", "off", "true", "yes", "on", NULL };
+ const int lengths[] = { 5, 2, 3, 4, 3, 2, 0 };
+ int i;
+
+ for (i = 0; booleans[i]; i++) {
+ const char *boolean = booleans[i];
+ int length = lengths[i];
+
+ if (strncmp(boolean, pc->p, length) == 0) {
+ pc->p += length;
+ pc->len -= length;
+ pc->tend = pc->p - 1;
+ pc->tt = JIM_TT_EXPR_BOOLEAN;
+ return JIM_OK;
+ }
+ }
+ return JIM_ERR;
+}
static int JimParseExprOperator(struct JimParserCtx *pc)
{
int i;
int bestIdx = -1, bestLen = 0;
-
+
for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
const char * const opname = Jim_ExprOperators[i].name;
const int oplen = Jim_ExprOperators[i].namelen;
if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13505,11 +13390,11 @@
}
if (bestIdx == -1) {
return JIM_ERR;
}
-
+
if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
const char *p = pc->p + bestLen;
int len = pc->len - bestLen;
while (len && isspace(UCHAR(*p))) {
@@ -13539,13 +13424,19 @@
const char *jim_tt_name(int type)
{
static const char * const tt_names[JIM_TT_EXPR_OP] =
{ "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
- "DBL", "$()" };
+ "DBL", "BOO", "$()" };
if (type < JIM_TT_EXPR_OP) {
return tt_names[type];
+ }
+ else if (type == JIM_EXPROP_UNARYMINUS) {
+ return "-VE";
+ }
+ else if (type == JIM_EXPROP_UNARYPLUS) {
+ return "+VE";
}
else {
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
static char buf[20];
@@ -13570,13 +13461,13 @@
};
typedef struct ExprByteCode
{
- ScriptToken *token;
- int len;
- int inUse;
+ ScriptToken *token;
+ int len;
+ int inUse;
} ExprByteCode;
static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
{
int i;
@@ -13604,26 +13495,29 @@
static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
{
JIM_NOTUSED(interp);
JIM_NOTUSED(srcPtr);
-
+
dupPtr->typePtr = NULL;
}
-
-static int ExprCheckCorrectness(ExprByteCode * expr)
+static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr)
{
int i;
int stacklen = 0;
int ternary = 0;
+ int lasttt = JIM_TT_NONE;
+ const char *errmsg;
for (i = 0; i < expr->len; i++) {
ScriptToken *t = &expr->token[i];
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
+ lasttt = t->type;
stacklen -= op->arity;
+
if (stacklen < 0) {
break;
}
if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
ternary++;
@@ -13630,26 +13524,47 @@
}
else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
ternary--;
}
-
+
stacklen++;
}
- if (stacklen != 1 || ternary != 0) {
- return JIM_ERR;
+ if (stacklen == 1 && ternary == 0) {
+ return JIM_OK;
}
- return JIM_OK;
+
+ if (stacklen <= 0) {
+
+ if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
+ errmsg = "too few arguments for math function";
+ Jim_SetResultString(interp, "too few arguments for math function", -1);
+ } else {
+ errmsg = "premature end of expression";
+ }
+ }
+ else if (stacklen > 1) {
+ if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
+ errmsg = "too many arguments for math function";
+ } else {
+ errmsg = "extra tokens at end of expression";
+ }
+ }
+ else {
+ errmsg = "invalid ternary expression";
+ }
+ Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg);
+ return JIM_ERR;
}
static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
{
int i;
int leftindex, arity, offset;
-
+
leftindex = expr->len - 1;
arity = 1;
while (arity) {
ScriptToken *tt = &expr->token[leftindex];
@@ -13662,11 +13577,11 @@
return JIM_ERR;
}
}
leftindex++;
-
+
memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
sizeof(*expr->token) * (expr->len - leftindex));
expr->len += 2;
offset = (expr->len - leftindex) - 1;
@@ -13674,16 +13589,16 @@
expr->token[leftindex + 1].objPtr = interp->emptyObj;
expr->token[leftindex].type = JIM_TT_EXPR_INT;
expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
-
+
expr->token[expr->len].objPtr = interp->emptyObj;
expr->token[expr->len].type = t->type + 2;
expr->len++;
-
+
for (i = leftindex - 1; i > 0; i--) {
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
if (op->lazy == LAZY_LEFT) {
if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13729,11 +13644,11 @@
return right_index;
}
right_index--;
}
-
+
return -1;
}
static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
{
@@ -13771,11 +13686,11 @@
if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
continue;
}
-
+
if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
continue;
}
tmp = expr->token[prev_right_index];
@@ -13784,25 +13699,25 @@
}
expr->token[i] = tmp;
JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
-
+
i++;
}
}
-static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj)
+static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
{
Jim_Stack stack;
ExprByteCode *expr;
int ok = 1;
int i;
int prevtt = JIM_TT_NONE;
int have_ternary = 0;
-
+
int count = tokenlist->count - 1;
expr = Jim_Alloc(sizeof(*expr));
expr->inUse = 1;
expr->len = 0;
@@ -13813,11 +13728,11 @@
ParseToken *t = &tokenlist->list[i];
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
if (op->lazy == LAZY_OP) {
count += 2;
-
+
if (t->type == JIM_EXPROP_TERNARY) {
have_ternary = 1;
}
}
}
@@ -13825,128 +13740,128 @@
expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
for (i = 0; i < tokenlist->count && ok; i++) {
ParseToken *t = &tokenlist->list[i];
-
+
struct ScriptToken *token = &expr->token[expr->len];
if (t->type == JIM_TT_EOL) {
break;
}
- switch (t->type) {
- case JIM_TT_STR:
- case JIM_TT_ESC:
- case JIM_TT_VAR:
- case JIM_TT_DICTSUGAR:
- case JIM_TT_EXPRSUGAR:
- case JIM_TT_CMD:
- token->type = t->type;
-strexpr:
- token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
- if (t->type == JIM_TT_CMD) {
-
- JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
- }
- expr->len++;
- break;
-
- case JIM_TT_EXPR_INT:
- case JIM_TT_EXPR_DOUBLE:
- {
- char *endptr;
- if (t->type == JIM_TT_EXPR_INT) {
- token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
- }
- else {
- token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
- }
- if (endptr != t->token + t->len) {
-
- Jim_FreeNewObj(interp, token->objPtr);
- token->type = JIM_TT_STR;
- goto strexpr;
- }
- token->type = t->type;
- expr->len++;
- }
- break;
-
- case JIM_TT_SUBEXPR_START:
- Jim_StackPush(&stack, t);
- prevtt = JIM_TT_NONE;
- continue;
-
- case JIM_TT_SUBEXPR_COMMA:
-
- continue;
-
- case JIM_TT_SUBEXPR_END:
- ok = 0;
- while (Jim_StackLen(&stack)) {
- ParseToken *tt = Jim_StackPop(&stack);
-
- if (tt->type == JIM_TT_SUBEXPR_START) {
- ok = 1;
- break;
- }
-
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
- goto err;
- }
- }
- if (!ok) {
- Jim_SetResultString(interp, "Unexpected close parenthesis", -1);
- goto err;
- }
- break;
-
-
- default:{
-
- const struct Jim_ExprOperator *op;
- ParseToken *tt;
-
-
- if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) {
- if (t->type == JIM_EXPROP_SUB) {
- t->type = JIM_EXPROP_UNARYMINUS;
- }
- else if (t->type == JIM_EXPROP_ADD) {
- t->type = JIM_EXPROP_UNARYPLUS;
- }
- }
-
- op = JimExprOperatorInfoByOpcode(t->type);
-
-
- while ((tt = Jim_StackPeek(&stack)) != NULL) {
- const struct Jim_ExprOperator *tt_op =
- JimExprOperatorInfoByOpcode(tt->type);
-
-
-
- if (op->arity != 1 && tt_op->precedence >= op->precedence) {
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
- ok = 0;
- goto err;
- }
- Jim_StackPop(&stack);
- }
- else {
- break;
- }
- }
- Jim_StackPush(&stack, t);
- break;
- }
+ if (TOKEN_IS_EXPR_OP(t->type)) {
+ const struct Jim_ExprOperator *op;
+ ParseToken *tt;
+
+
+ if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) {
+ if (t->type == JIM_EXPROP_SUB) {
+ t->type = JIM_EXPROP_UNARYMINUS;
+ }
+ else if (t->type == JIM_EXPROP_ADD) {
+ t->type = JIM_EXPROP_UNARYPLUS;
+ }
+ }
+
+ op = JimExprOperatorInfoByOpcode(t->type);
+
+
+ while ((tt = Jim_StackPeek(&stack)) != NULL) {
+ const struct Jim_ExprOperator *tt_op =
+ JimExprOperatorInfoByOpcode(tt->type);
+
+
+ if (op->arity != 1 && tt_op->precedence >= op->precedence) {
+
+ if (tt_op->precedence == op->precedence && tt_op->lazy == RIGHT_ASSOC) {
+ break;
+ }
+ if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
+ ok = 0;
+ goto err;
+ }
+ Jim_StackPop(&stack);
+ }
+ else {
+ break;
+ }
+ }
+ Jim_StackPush(&stack, t);
+ }
+ else if (t->type == JIM_TT_SUBEXPR_START) {
+ Jim_StackPush(&stack, t);
+ }
+ else if (t->type == JIM_TT_SUBEXPR_END || t->type == JIM_TT_SUBEXPR_COMMA) {
+
+ ok = 0;
+ while (Jim_StackLen(&stack)) {
+ ParseToken *tt = Jim_StackPop(&stack);
+
+ if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) {
+ if (t->type == JIM_TT_SUBEXPR_COMMA) {
+
+ Jim_StackPush(&stack, tt);
+ }
+ ok = 1;
+ break;
+ }
+ if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
+ goto err;
+ }
+ }
+ if (!ok) {
+ Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr);
+ goto err;
+ }
+ }
+ else {
+ Jim_Obj *objPtr = NULL;
+
+
+ token->type = t->type;
+
+
+ if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) {
+ Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr);
+ ok = 0;
+ goto err;
+ }
+
+
+ if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) {
+ char *endptr;
+ if (t->type == JIM_TT_EXPR_INT) {
+ objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
+ }
+ else {
+ objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
+ }
+ if (endptr != t->token + t->len) {
+
+ Jim_FreeNewObj(interp, objPtr);
+ objPtr = NULL;
+ }
+ }
+
+ if (objPtr) {
+ token->objPtr = objPtr;
+ }
+ else {
+
+ token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
+ if (t->type == JIM_TT_CMD) {
+
+ JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
+ }
+ }
+ expr->len++;
}
prevtt = t->type;
}
-
+
while (Jim_StackLen(&stack)) {
ParseToken *tt = Jim_StackPop(&stack);
if (tt->type == JIM_TT_SUBEXPR_START) {
ok = 0;
@@ -13962,11 +13877,11 @@
if (have_ternary) {
ExprTernaryReorderExpression(interp, expr);
}
err:
-
+
Jim_FreeStack(&stack);
for (i = 0; i < expr->len; i++) {
Jim_IncrRefCount(expr->token[i].objPtr);
}
@@ -13989,11 +13904,11 @@
ParseTokenList tokenlist;
int line;
Jim_Obj *fileNameObj;
int rc = JIM_ERR;
-
+
if (objPtr->typePtr == &sourceObjType) {
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
line = objPtr->internalRep.sourceValue.lineNumber;
}
else {
@@ -14002,18 +13917,17 @@
}
Jim_IncrRefCount(fileNameObj);
exprText = Jim_GetString(objPtr, &exprTextLen);
-
+
ScriptTokenListInit(&tokenlist);
JimParserInit(&parser, exprText, exprTextLen, line);
while (!parser.eof) {
if (JimParseExpression(&parser) != JIM_OK) {
ScriptTokenListFree(&tokenlist);
- invalidexpr:
Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
expr = NULL;
goto err;
}
@@ -14036,14 +13950,14 @@
ScriptTokenListFree(&tokenlist);
Jim_DecrRefCount(interp, fileNameObj);
return JIM_ERR;
}
-
- expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj);
-
+ expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj);
+
+
ScriptTokenListFree(&tokenlist);
if (!expr) {
goto err;
}
@@ -14059,20 +13973,22 @@
printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
}
}
#endif
-
- if (ExprCheckCorrectness(expr) != JIM_OK) {
+
+ if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) {
+
ExprFreeByteCode(interp, expr);
- goto invalidexpr;
+ expr = NULL;
+ goto err;
}
rc = JIM_OK;
err:
-
+
Jim_DecrRefCount(interp, fileNameObj);
Jim_FreeIntRep(interp, objPtr);
Jim_SetIntRepPtr(objPtr, expr);
objPtr->typePtr = &exprObjType;
return rc;
@@ -14112,11 +14028,11 @@
int retcode = JIM_OK;
struct JimExprState e;
expr = JimGetExpression(interp, exprObjPtr);
if (!expr) {
- return JIM_ERR;
+ return JIM_ERR;
}
#ifdef JIM_OPTIMIZATION
{
Jim_Obj *objPtr;
@@ -14185,26 +14101,27 @@
noopt:
#endif
expr->inUse++;
-
+
if (expr->len > JIM_EE_STATICSTACK_LEN)
e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
else
e.stack = staticStack;
e.stacklen = 0;
-
+
for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
Jim_Obj *objPtr;
switch (expr->token[i].type) {
case JIM_TT_EXPR_INT:
case JIM_TT_EXPR_DOUBLE:
+ case JIM_TT_EXPR_BOOLEAN:
case JIM_TT_STR:
ExprPush(&e, expr->token[i].objPtr);
break;
case JIM_TT_VAR:
@@ -14240,16 +14157,16 @@
ExprPush(&e, Jim_GetResult(interp));
}
break;
default:{
-
+
e.skip = 0;
e.opcode = expr->token[i].type;
retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
-
+
i += e.skip;
continue;
}
}
}
@@ -14273,20 +14190,27 @@
int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
{
int retcode;
jim_wide wideValue;
double doubleValue;
+ int booleanValue;
Jim_Obj *exprResultPtr;
retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
if (retcode != JIM_OK)
return retcode;
if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
- Jim_DecrRefCount(interp, exprResultPtr);
- return JIM_ERR;
+ if (Jim_GetBoolean(interp, exprResultPtr, &booleanValue) != JIM_OK) {
+ Jim_DecrRefCount(interp, exprResultPtr);
+ return JIM_ERR;
+ } else {
+ Jim_DecrRefCount(interp, exprResultPtr);
+ *boolPtr = booleanValue;
+ return JIM_OK;
+ }
}
else {
Jim_DecrRefCount(interp, exprResultPtr);
*boolPtr = doubleValue != 0;
return JIM_OK;
@@ -14301,29 +14225,29 @@
typedef struct ScanFmtPartDescr
{
- char *arg;
- char *prefix;
- size_t width;
- int pos;
- char type;
- char modifier;
+ char *arg;
+ char *prefix;
+ size_t width;
+ int pos;
+ char type;
+ char modifier;
} ScanFmtPartDescr;
typedef struct ScanFmtStringObj
{
- jim_wide size;
- char *stringRep;
- size_t count;
- size_t convCount;
- size_t maxPos;
- const char *error;
- char *scratch;
- ScanFmtPartDescr descr[1];
+ jim_wide size;
+ char *stringRep;
+ size_t count;
+ size_t convCount;
+ size_t maxPos;
+ const char *error;
+ char *scratch;
+ ScanFmtPartDescr descr[1];
} ScanFmtStringObj;
static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14370,22 +14294,22 @@
int maxFmtLen = objPtr->length;
const char *fmtEnd = fmt + maxFmtLen;
int curr;
Jim_FreeIntRep(interp, objPtr);
-
+
for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
if (fmt[i] == '%')
++maxCount;
-
- approxSize = sizeof(ScanFmtStringObj)
- +(maxCount + 1) * sizeof(ScanFmtPartDescr)
- +maxFmtLen * sizeof(char) + 3 + 1
- + maxFmtLen * sizeof(char) + 1
- + maxFmtLen * sizeof(char)
- +(maxCount + 1) * sizeof(char)
- +1;
+
+ approxSize = sizeof(ScanFmtStringObj)
+ +(maxCount + 1) * sizeof(ScanFmtPartDescr)
+ +maxFmtLen * sizeof(char) + 3 + 1
+ + maxFmtLen * sizeof(char) + 1
+ + maxFmtLen * sizeof(char)
+ +(maxCount + 1) * sizeof(char)
+ +1;
fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
memset(fmtObj, 0, approxSize);
fmtObj->size = approxSize;
fmtObj->maxPos = 0;
fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14397,12 +14321,12 @@
for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
int width = 0, skip;
ScanFmtPartDescr *descr = &fmtObj->descr[curr];
fmtObj->count++;
- descr->width = 0;
-
+ descr->width = 0;
+
if (*fmt != '%' || fmt[1] == '%') {
descr->type = 0;
descr->prefix = &buffer[i];
for (; fmt < fmtEnd; ++fmt) {
if (*fmt == '%') {
@@ -14412,65 +14336,65 @@
}
buffer[i++] = *fmt;
}
buffer[i++] = 0;
}
-
+
++fmt;
-
+
if (fmt >= fmtEnd)
goto done;
- descr->pos = 0;
+ descr->pos = 0;
if (*fmt == '*') {
- descr->pos = -1;
+ descr->pos = -1;
++fmt;
}
else
- fmtObj->convCount++;
-
+ fmtObj->convCount++;
+
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
fmt += skip;
-
+
if (descr->pos != -1 && *fmt == '$') {
int prev;
++fmt;
descr->pos = width;
width = 0;
-
+
if ((lastPos == 0 && descr->pos > 0)
|| (lastPos > 0 && descr->pos == 0)) {
fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
return JIM_ERR;
}
-
+
for (prev = 0; prev < curr; ++prev) {
if (fmtObj->descr[prev].pos == -1)
continue;
if (fmtObj->descr[prev].pos == descr->pos) {
fmtObj->error =
"variable is assigned by multiple \"%n$\" conversion specifiers";
return JIM_ERR;
}
}
-
+
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
descr->width = width;
fmt += skip;
}
if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
fmtObj->maxPos = descr->pos;
}
else {
-
+
descr->width = width;
}
}
-
+
if (lastPos == -1)
lastPos = descr->pos;
-
+
if (*fmt == '[') {
int swapped = 1, beg = i, end, j;
descr->type = '[';
descr->arg = &buffer[i];
@@ -14485,11 +14409,11 @@
fmtObj->error = "unmatched [ in format string";
return JIM_ERR;
}
end = i;
buffer[i++] = 0;
-
+
while (swapped) {
swapped = 0;
for (j = beg + 1; j < end - 1; ++j) {
if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
char tmp = buffer[j - 1];
@@ -14500,11 +14424,11 @@
}
}
}
}
else {
-
+
if (strchr("hlL", *fmt) != 0)
descr->modifier = tolower((int)*fmt++);
descr->type = *fmt;
if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14543,11 +14467,11 @@
while (*str) {
int c;
int n;
if (!sdescr && isspace(UCHAR(*str)))
- break;
+ break;
n = utf8_tounicode(str, &c);
if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
break;
while (n--)
@@ -14566,89 +14490,89 @@
size_t scanned = 0;
size_t anchor = pos;
int i;
Jim_Obj *tmpObj = NULL;
-
+
*valObjPtr = 0;
if (descr->prefix) {
for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
-
+
if (isspace(UCHAR(descr->prefix[i])))
while (pos < strLen && isspace(UCHAR(str[pos])))
++pos;
else if (descr->prefix[i] != str[pos])
- break;
+ break;
else
- ++pos;
+ ++pos;
}
if (pos >= strLen) {
- return -1;
+ return -1;
}
else if (descr->prefix[i] != 0)
- return 0;
+ return 0;
}
-
+
if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
while (isspace(UCHAR(str[pos])))
++pos;
-
+
scanned = pos - anchor;
-
+
if (descr->type == 'n') {
-
+
*valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
}
else if (pos >= strLen) {
-
+
return -1;
}
else if (descr->type == 'c') {
int c;
scanned += utf8_tounicode(&str[pos], &c);
*valObjPtr = Jim_NewIntObj(interp, c);
return scanned;
}
else {
-
+
if (descr->width > 0) {
size_t sLen = utf8_strlen(&str[pos], strLen - pos);
size_t tLen = descr->width > sLen ? sLen : descr->width;
tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
tok = tmpObj->bytes;
}
else {
-
+
tok = &str[pos];
}
switch (descr->type) {
case 'd':
case 'o':
case 'x':
case 'u':
case 'i':{
- char *endp;
+ char *endp;
jim_wide w;
int base = descr->type == 'o' ? 8
: descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
-
+
if (base == 0) {
w = jim_strtoull(tok, &endp);
}
else {
w = strtoull(tok, &endp, base);
}
if (endp != tok) {
-
+
*valObjPtr = Jim_NewIntObj(interp, w);
-
+
scanned += endp - tok;
}
else {
scanned = *tok ? 0 : -1;
}
@@ -14665,13 +14589,13 @@
case 'g':{
char *endp;
double value = strtod(tok, &endp);
if (endp != tok) {
-
+
*valObjPtr = Jim_NewDoubleObj(interp, value);
-
+
scanned += endp - tok;
}
else {
scanned = *tok ? 0 : -1;
}
@@ -14696,65 +14620,65 @@
Jim_Obj **resultVec = 0;
int resultc;
Jim_Obj *emptyStr = 0;
ScanFmtStringObj *fmtObj;
-
+
JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
-
+
if (fmtObj->error != 0) {
if (flags & JIM_ERRMSG)
Jim_SetResultString(interp, fmtObj->error, -1);
return 0;
}
-
+
emptyStr = Jim_NewEmptyStringObj(interp);
Jim_IncrRefCount(emptyStr);
-
+
resultList = Jim_NewListObj(interp, NULL, 0);
if (fmtObj->maxPos > 0) {
for (i = 0; i < fmtObj->maxPos; ++i)
Jim_ListAppendElement(interp, resultList, emptyStr);
JimListGetElements(interp, resultList, &resultc, &resultVec);
}
-
+
for (i = 0, pos = 0; i < fmtObj->count; ++i) {
ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
Jim_Obj *value = 0;
-
+
if (descr->type == 0)
continue;
-
+
if (scanned > 0)
scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
-
+
if (scanned == -1 && i == 0)
goto eof;
-
+
pos += scanned;
-
+
if (value == 0)
value = Jim_NewEmptyStringObj(interp);
-
+
if (descr->pos == -1) {
Jim_FreeNewObj(interp, value);
}
else if (descr->pos == 0)
-
+
Jim_ListAppendElement(interp, resultList, value);
else if (resultVec[descr->pos - 1] == emptyStr) {
-
+
Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
Jim_IncrRefCount(value);
resultVec[descr->pos - 1] = value;
}
else {
-
+
Jim_FreeNewObj(interp, value);
goto err;
}
}
Jim_DecrRefCount(interp, emptyStr);
@@ -14792,15 +14716,15 @@
{
Jim_PrngState *prng;
unsigned char *destByte = (unsigned char *)dest;
unsigned int si, sj, x;
-
+
if (interp->prngState == NULL)
JimPrngInit(interp);
prng = interp->prngState;
-
+
for (x = 0; x < len; x++) {
prng->i = (prng->i + 1) & 0xff;
si = prng->sbox[prng->i];
prng->j = (prng->j + si) & 0xff;
sj = prng->sbox[prng->j];
@@ -14814,19 +14738,19 @@
static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
{
int i;
Jim_PrngState *prng;
-
+
if (interp->prngState == NULL)
JimPrngInit(interp);
prng = interp->prngState;
-
+
for (i = 0; i < 256; i++)
prng->sbox[i] = i;
-
+
for (i = 0; i < seedLen; i++) {
unsigned char t;
t = prng->sbox[i & 0xFF];
prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14853,11 +14777,11 @@
if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
return JIM_ERR;
}
intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
if (!intObjPtr) {
-
+
wideValue = 0;
}
else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
return JIM_ERR;
}
@@ -14867,26 +14791,26 @@
Jim_FreeNewObj(interp, intObjPtr);
return JIM_ERR;
}
}
else {
-
+
Jim_InvalidateStringRep(intObjPtr);
JimWideValue(intObjPtr) = wideValue + increment;
if (argv[1]->typePtr != &variableObjType) {
-
+
Jim_SetVariable(interp, argv[1], intObjPtr);
}
}
Jim_SetResult(interp, intObjPtr);
return JIM_OK;
}
-#define JIM_EVAL_SARGV_LEN 8
-#define JIM_EVAL_SINTV_LEN 8
+#define JIM_EVAL_SARGV_LEN 8
+#define JIM_EVAL_SINTV_LEN 8
static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int retcode;
@@ -14894,16 +14818,16 @@
if (interp->unknown_called > 50) {
return JIM_ERR;
}
-
+
if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
return JIM_ERR;
interp->unknown_called++;
-
+
retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
interp->unknown_called--;
return retcode;
}
@@ -14921,11 +14845,11 @@
}
printf("\n");
#endif
if (interp->framePtr->tailcallCmd) {
-
+
cmdPtr = interp->framePtr->tailcallCmd;
interp->framePtr->tailcallCmd = NULL;
}
else {
cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14940,11 +14864,11 @@
retcode = JIM_ERR;
goto out;
}
interp->evalDepth++;
-
+
Jim_SetEmptyResult(interp);
if (cmdPtr->isproc) {
retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
}
else {
@@ -14961,17 +14885,17 @@
int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
{
int i, retcode;
-
+
for (i = 0; i < objc; i++)
Jim_IncrRefCount(objv[i]);
retcode = JimInvokeCommand(interp, objc, objv);
-
+
for (i = 0; i < objc; i++)
Jim_DecrRefCount(interp, objv[i]);
return retcode;
}
@@ -14989,25 +14913,25 @@
}
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
{
if (!interp->errorFlag) {
-
+
interp->errorFlag = 1;
Jim_IncrRefCount(script->fileNameObj);
Jim_DecrRefCount(interp, interp->errorFileNameObj);
interp->errorFileNameObj = script->fileNameObj;
interp->errorLine = script->linenr;
JimResetStackTrace(interp);
-
+
interp->addStackTrace++;
}
-
+
if (interp->addStackTrace > 0) {
-
+
JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
if (Jim_Length(script->fileNameObj)) {
interp->addStackTrace = 0;
@@ -15042,14 +14966,14 @@
case JIM_OK:
case JIM_RETURN:
objPtr = interp->result;
break;
case JIM_BREAK:
-
+
return JIM_BREAK;
case JIM_CONTINUE:
-
+
return JIM_CONTINUE;
default:
return JIM_ERR;
}
break;
@@ -15084,23 +15008,23 @@
case JIM_OK:
case JIM_RETURN:
break;
case JIM_BREAK:
if (flags & JIM_SUBST_FLAG) {
-
+
tokens = i;
continue;
}
-
-
+
+
case JIM_CONTINUE:
if (flags & JIM_SUBST_FLAG) {
intv[i] = NULL;
continue;
}
-
-
+
+
default:
while (i--) {
Jim_DecrRefCount(interp, intv[i]);
}
if (intv != sintv) {
@@ -15111,28 +15035,28 @@
Jim_IncrRefCount(intv[i]);
Jim_String(intv[i]);
totlen += intv[i]->length;
}
-
+
if (tokens == 1 && intv[0] && intv == sintv) {
Jim_DecrRefCount(interp, intv[0]);
return intv[0];
}
objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
&& token[2].type == JIM_TT_VAR) {
-
+
objPtr->typePtr = &interpolatedObjType;
objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
Jim_IncrRefCount(intv[2]);
}
else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
-
+
JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
}
s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -15143,11 +15067,11 @@
s += intv[i]->length;
Jim_DecrRefCount(interp, intv[i]);
}
}
objPtr->bytes[totlen] = '\0';
-
+
if (intv != sintv) {
Jim_Free(intv);
}
return objPtr;
@@ -15187,11 +15111,11 @@
if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
return JimEvalObjList(interp, scriptObjPtr);
}
- Jim_IncrRefCount(scriptObjPtr);
+ Jim_IncrRefCount(scriptObjPtr);
script = JimGetScript(interp, scriptObjPtr);
if (!JimScriptValid(interp, script)) {
Jim_DecrRefCount(interp, scriptObjPtr);
return JIM_ERR;
}
@@ -15223,11 +15147,11 @@
}
#endif
script->inUse++;
-
+
prevScriptObj = interp->currentScriptObj;
interp->currentScriptObj = scriptObjPtr;
interp->errorFlag = 0;
argv = sargv;
@@ -15234,19 +15158,19 @@
for (i = 0; i < script->len && retcode == JIM_OK; ) {
int argc;
int j;
-
+
argc = token[i].objPtr->internalRep.scriptLineValue.argc;
script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
-
+
if (argc > JIM_EVAL_SARGV_LEN)
argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
-
+
i++;
for (j = 0; j < argc; j++) {
long wordtokens = 1;
int expand = 0;
@@ -15302,11 +15226,11 @@
if (!expand) {
argv[j] = wordObjPtr;
}
else {
-
+
int len = Jim_ListLength(interp, wordObjPtr);
int newargc = argc + len - 1;
int k;
if (len > 1) {
@@ -15315,39 +15239,39 @@
argv = Jim_Alloc(sizeof(*argv) * newargc);
memcpy(argv, sargv, sizeof(*argv) * j);
}
}
else {
-
+
argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
}
}
-
+
for (k = 0; k < len; k++) {
argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
}
Jim_DecrRefCount(interp, wordObjPtr);
-
+
j--;
argc += len - 1;
}
}
if (retcode == JIM_OK && argc) {
-
+
retcode = JimInvokeCommand(interp, argc, argv);
-
+
if (Jim_CheckSignal(interp)) {
retcode = JIM_SIGNAL;
}
}
-
+
while (j-- > 0) {
Jim_DecrRefCount(interp, argv[j]);
}
if (argv != sargv) {
@@ -15354,21 +15278,21 @@
Jim_Free(argv);
argv = sargv;
}
}
-
+
if (retcode == JIM_ERR) {
JimAddErrorToStack(interp, script);
}
-
+
else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
-
+
interp->addStackTrace = 0;
}
-
+
interp->currentScriptObj = prevScriptObj;
Jim_FreeIntRep(interp, scriptObjPtr);
scriptObjPtr->typePtr = &scriptObjType;
Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15378,14 +15302,14 @@
}
static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
{
int retcode;
-
+
const char *varname = Jim_String(argNameObj);
if (*varname == '&') {
-
+
Jim_Obj *objPtr;
Jim_CallFrame *savedCallFrame = interp->framePtr;
interp->framePtr = interp->framePtr->parent;
objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15392,11 +15316,11 @@
interp->framePtr = savedCallFrame;
if (!objPtr) {
return JIM_ERR;
}
-
+
objPtr = Jim_NewStringObj(interp, varname + 1, -1);
Jim_IncrRefCount(objPtr);
retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
Jim_DecrRefCount(interp, objPtr);
}
@@ -15406,26 +15330,26 @@
return retcode;
}
static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
{
-
+
Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
int i;
for (i = 0; i < cmd->u.proc.argListLen; i++) {
Jim_AppendString(interp, argmsg, " ", 1);
if (i == cmd->u.proc.argsPos) {
if (cmd->u.proc.arglist[i].defaultObjPtr) {
-
+
Jim_AppendString(interp, argmsg, "?", 1);
Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
Jim_AppendString(interp, argmsg, " ...?", -1);
}
else {
-
+
Jim_AppendString(interp, argmsg, "?arg...?", -1);
}
}
else {
if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15450,11 +15374,11 @@
int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
{
Jim_CallFrame *callFramePtr;
int retcode;
-
+
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
callFramePtr->argv = &interp->emptyObj;
callFramePtr->argc = 0;
callFramePtr->procArgsObjPtr = NULL;
callFramePtr->procBodyObjPtr = scriptObj;
@@ -15462,21 +15386,21 @@
callFramePtr->fileNameObj = interp->emptyObj;
callFramePtr->line = 0;
Jim_IncrRefCount(scriptObj);
interp->framePtr = callFramePtr;
-
+
if (interp->framePtr->level == interp->maxCallFrameDepth) {
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
retcode = JIM_ERR;
}
else {
-
+
retcode = Jim_EvalObj(interp, scriptObj);
}
-
+
interp->framePtr = interp->framePtr->parent;
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
return retcode;
}
@@ -15486,62 +15410,62 @@
{
Jim_CallFrame *callFramePtr;
int i, d, retcode, optargs;
ScriptObj *script;
-
+
if (argc - 1 < cmd->u.proc.reqArity ||
(cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
JimSetProcWrongArgs(interp, argv[0], cmd);
return JIM_ERR;
}
if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
-
+
return JIM_OK;
}
-
+
if (interp->framePtr->level == interp->maxCallFrameDepth) {
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
return JIM_ERR;
}
-
+
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
callFramePtr->argv = argv;
callFramePtr->argc = argc;
callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
callFramePtr->staticVars = cmd->u.proc.staticVars;
-
+
script = JimGetScript(interp, interp->currentScriptObj);
callFramePtr->fileNameObj = script->fileNameObj;
callFramePtr->line = script->linenr;
Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
interp->framePtr = callFramePtr;
-
+
optargs = (argc - 1 - cmd->u.proc.reqArity);
-
+
i = 1;
for (d = 0; d < cmd->u.proc.argListLen; d++) {
Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
if (d == cmd->u.proc.argsPos) {
-
+
Jim_Obj *listObjPtr;
int argsLen = 0;
if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
}
listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
-
+
if (cmd->u.proc.arglist[d].defaultObjPtr) {
nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
}
retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
if (retcode != JIM_OK) {
@@ -15550,33 +15474,33 @@
i += argsLen;
continue;
}
-
+
if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
}
else {
-
+
retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
}
if (retcode != JIM_OK) {
goto badargset;
}
}
-
+
retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
badargset:
-
+
interp->framePtr = interp->framePtr->parent;
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
-
+
if (interp->framePtr->tailcallObj) {
do {
Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
interp->framePtr->tailcallObj = NULL;
@@ -15588,18 +15512,18 @@
}
}
Jim_DecrRefCount(interp, tailcallObj);
} while (interp->framePtr->tailcallObj);
-
+
if (interp->framePtr->tailcallCmd) {
JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
interp->framePtr->tailcallCmd = NULL;
}
}
-
+
if (retcode == JIM_RETURN) {
if (--interp->returnLevel <= 0) {
retcode = interp->returnCode;
interp->returnCode = JIM_OK;
interp->returnLevel = 0;
@@ -15711,20 +15635,20 @@
prevScriptObj = interp->currentScriptObj;
interp->currentScriptObj = scriptObjPtr;
retcode = Jim_EvalObj(interp, scriptObjPtr);
-
+
if (retcode == JIM_RETURN) {
if (--interp->returnLevel <= 0) {
retcode = interp->returnCode;
interp->returnCode = JIM_OK;
interp->returnLevel = 0;
}
}
if (retcode == JIM_ERR) {
-
+
interp->addStackTrace++;
}
interp->currentScriptObj = prevScriptObj;
@@ -15750,11 +15674,11 @@
}
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
if (JimParseVar(pc) == JIM_OK) {
return;
}
-
+
pc->tstart = pc->p;
flags |= JIM_SUBST_NOVAR;
}
while (pc->len) {
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15781,32 +15705,32 @@
const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
struct JimParserCtx parser;
struct ScriptObj *script = Jim_Alloc(sizeof(*script));
ParseTokenList tokenlist;
-
+
ScriptTokenListInit(&tokenlist);
JimParserInit(&parser, scriptText, scriptTextLen, 1);
while (1) {
JimParseSubst(&parser, flags);
if (parser.eof) {
-
+
break;
}
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
parser.tline);
}
-
+
script->inUse = 1;
script->substFlags = flags;
script->fileNameObj = interp->emptyObj;
Jim_IncrRefCount(script->fileNameObj);
SubstObjAddTokens(interp, script, &tokenlist);
-
+
ScriptTokenListFree(&tokenlist);
#ifdef DEBUG_SHOW_SUBST
{
int i;
@@ -15817,11 +15741,11 @@
Jim_String(script->token[i].objPtr));
}
}
#endif
-
+
Jim_FreeIntRep(interp, objPtr);
Jim_SetIntRepPtr(objPtr, script);
objPtr->typePtr = &scriptObjType;
return JIM_OK;
}
@@ -15835,11 +15759,11 @@
int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
{
ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
- Jim_IncrRefCount(substObjPtr);
+ Jim_IncrRefCount(substObjPtr);
script->inUse++;
*resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
script->inUse--;
@@ -15851,11 +15775,15 @@
}
void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
{
Jim_Obj *objPtr;
- Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
+ Jim_Obj *listObjPtr;
+
+ JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0"));
+
+ listObjPtr = Jim_NewListObj(interp, argv, argc);
if (*msg) {
Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
}
Jim_IncrRefCount(listObjPtr);
@@ -15876,11 +15804,11 @@
JimHashtableIteratorCallbackType *callback, int type)
{
Jim_HashEntry *he;
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
-
+
if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
if (he) {
callback(interp, listObjPtr, he, type);
}
@@ -15907,11 +15835,11 @@
{
Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
Jim_Obj *objPtr;
if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
-
+
return;
}
objPtr = Jim_NewStringObj(interp, he->key, -1);
Jim_IncrRefCount(objPtr);
@@ -15967,11 +15895,11 @@
targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
if (targetCallFrame == NULL) {
return JIM_ERR;
}
-
+
if (targetCallFrame == interp->topFramePtr) {
Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
return JIM_ERR;
}
if (info_level_cmd) {
@@ -16154,11 +16082,11 @@
if (!objPtr)
return JIM_ERR;
Jim_SetResult(interp, objPtr);
return JIM_OK;
}
-
+
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
return JIM_ERR;
Jim_SetResult(interp, argv[2]);
return JIM_OK;
}
@@ -16197,11 +16125,11 @@
if (argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "condition body");
return JIM_ERR;
}
-
+
while (1) {
int boolean, retval;
if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
return retval;
@@ -16237,11 +16165,11 @@
if (argc != 5) {
Jim_WrongNumArgs(interp, 1, argv, "start test next body");
return JIM_ERR;
}
-
+
if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
return retval;
}
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16253,19 +16181,19 @@
ExprByteCode *expr;
jim_wide stop, currentVal;
Jim_Obj *objPtr;
int cmpOffset;
-
+
expr = JimGetExpression(interp, argv[2]);
incrScript = JimGetScript(interp, argv[3]);
-
+
if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
goto evalstart;
}
-
+
if (incrScript->token[1].type != JIM_TT_ESC ||
expr->token[0].type != JIM_TT_VAR ||
(expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
goto evalstart;
}
@@ -16278,48 +16206,48 @@
}
else {
goto evalstart;
}
-
+
if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
goto evalstart;
}
-
+
if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
goto evalstart;
}
-
+
if (expr->token[1].type == JIM_TT_EXPR_INT) {
if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
goto evalstart;
}
}
else {
stopVarNamePtr = expr->token[1].objPtr;
Jim_IncrRefCount(stopVarNamePtr);
-
+
stop = 0;
}
-
+
varNamePtr = expr->token[0].objPtr;
Jim_IncrRefCount(varNamePtr);
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
if (objPtr == NULL || Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK) {
goto testcond;
}
-
+
while (retval == JIM_OK) {
-
-
-
+
+
+
if (stopVarNamePtr) {
objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
goto testcond;
}
@@ -16327,18 +16255,18 @@
if (currentVal >= stop + cmpOffset) {
break;
}
-
+
retval = Jim_EvalObj(interp, argv[4]);
if (retval == JIM_OK || retval == JIM_CONTINUE) {
retval = JIM_OK;
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
-
+
if (objPtr == NULL) {
retval = JIM_ERR;
goto out;
}
if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16358,25 +16286,25 @@
}
evalstart:
#endif
while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
-
+
retval = Jim_EvalObj(interp, argv[4]);
if (retval == JIM_OK || retval == JIM_CONTINUE) {
-
- evalnext:
+
+JIM_IF_OPTIM(evalnext:)
retval = Jim_EvalObj(interp, argv[3]);
if (retval == JIM_OK || retval == JIM_CONTINUE) {
-
- testcond:
+
+JIM_IF_OPTIM(testcond:)
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
}
}
}
- out:
+JIM_IF_OPTIM(out:)
if (stopVarNamePtr) {
Jim_DecrRefCount(interp, stopVarNamePtr);
}
if (varNamePtr) {
Jim_DecrRefCount(interp, varNamePtr);
@@ -16418,11 +16346,11 @@
if (retval == JIM_OK || retval == JIM_CONTINUE) {
Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
retval = JIM_OK;
-
+
i += incr;
if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
if (argv[1]->typePtr != &variableObjType) {
if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16483,21 +16411,21 @@
static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
{
int result = JIM_OK;
int i, numargs;
- Jim_ListIter twoiters[2];
+ Jim_ListIter twoiters[2];
Jim_ListIter *iters;
Jim_Obj *script;
Jim_Obj *resultObj;
if (argc < 4 || argc % 2 != 0) {
Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
return JIM_ERR;
}
- script = argv[argc - 1];
- numargs = (argc - 1 - 1);
+ script = argv[argc - 1];
+ numargs = (argc - 1 - 1);
if (numargs == 2) {
iters = twoiters;
}
else {
@@ -16521,34 +16449,34 @@
resultObj = interp->emptyObj;
}
Jim_IncrRefCount(resultObj);
while (1) {
-
+
for (i = 0; i < numargs; i += 2) {
if (!JimListIterDone(interp, &iters[i + 1])) {
break;
}
}
if (i == numargs) {
-
+
break;
}
-
+
for (i = 0; i < numargs; i += 2) {
Jim_Obj *varName;
-
+
JimListIterInit(&iters[i], argv[i + 1]);
while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
if (!valObj) {
-
+
valObj = interp->emptyObj;
}
-
+
Jim_IncrRefCount(valObj);
result = Jim_SetVariable(interp, varName, valObj);
Jim_DecrRefCount(interp, valObj);
if (result != JIM_OK) {
goto err;
@@ -16630,41 +16558,41 @@
{
int boolean, retval, current = 1, falsebody = 0;
if (argc >= 3) {
while (1) {
-
+
if (current >= argc)
goto err;
if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
!= JIM_OK)
return retval;
-
+
if (current >= argc)
goto err;
if (Jim_CompareStringImmediate(interp, argv[current], "then"))
current++;
-
+
if (current >= argc)
goto err;
if (boolean)
return Jim_EvalObj(interp, argv[current]);
-
+
if (++current >= argc) {
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
return JIM_OK;
}
falsebody = current++;
if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
-
+
if (current != argc - 1)
goto err;
return Jim_EvalObj(interp, argv[current]);
}
else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
continue;
-
+
else if (falsebody != argc - 1)
goto err;
return Jim_EvalObj(interp, argv[falsebody]);
}
return JIM_OK;
@@ -16772,21 +16700,21 @@
if (Jim_StringMatchObj(interp, patObj, strObj, 0))
script = caseList[i + 1];
break;
case SWITCH_RE:
command = Jim_NewStringObj(interp, "regexp", -1);
-
+
case SWITCH_CMD:{
int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
if (argc - opt == 1) {
Jim_Obj **vector;
JimListGetElements(interp, argv[opt], &patCount, &vector);
caseList = vector;
}
-
+
if (rc < 0) {
return -rc;
}
if (rc)
script = caseList[i + 1];
@@ -16920,11 +16848,11 @@
case OPT_COMMAND:
if (i >= argc - 2) {
goto wrongargs;
}
commandObj = argv[++i];
-
+
case OPT_EXACT:
case OPT_GLOB:
case OPT_REGEXP:
opt_match = option;
break;
@@ -16968,17 +16896,17 @@
goto done;
}
break;
}
-
+
if (!eq && opt_bool && opt_not && !opt_all) {
continue;
}
if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
-
+
Jim_Obj *resultObj;
if (opt_bool) {
resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
}
@@ -17001,11 +16929,11 @@
if (opt_all) {
Jim_SetResult(interp, listObjPtr);
}
else {
-
+
if (opt_bool) {
Jim_SetResultBool(interp, opt_not);
}
else if (!opt_inline) {
Jim_SetResultInt(interp, -1);
@@ -17030,11 +16958,11 @@
Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
return JIM_ERR;
}
listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
if (!listObjPtr) {
-
+
listObjPtr = Jim_NewListObj(interp, NULL, 0);
new_obj = 1;
}
else if (Jim_IsShared(listObjPtr)) {
listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
@@ -17103,31 +17031,31 @@
first = JimRelToAbsIndex(len, first);
last = JimRelToAbsIndex(len, last);
JimRelToAbsRange(len, &first, &last, &rangeLen);
-
+
if (first < len) {
-
+
}
else if (len == 0) {
-
+
first = 0;
}
else {
Jim_SetResultString(interp, "list doesn't contain element ", -1);
Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
return JIM_ERR;
}
-
+
newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
-
+
ListInsertElements(newListObj, -1, argc - 4, argv + 4);
-
+
ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
Jim_SetResult(interp, newListObj);
return JIM_OK;
}
@@ -17138,11 +17066,11 @@
if (argc < 3) {
Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
return JIM_ERR;
}
else if (argc == 3) {
-
+
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
return JIM_ERR;
Jim_SetResult(interp, argv[2]);
return JIM_OK;
}
@@ -17253,11 +17181,11 @@
}
else {
int new_obj = 0;
stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
if (!stringObjPtr) {
-
+
stringObjPtr = Jim_NewEmptyStringObj(interp);
new_obj = 1;
}
else if (Jim_IsShared(stringObjPtr)) {
new_obj = 1;
@@ -17302,11 +17230,11 @@
else {
rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
}
if (rc == JIM_ERR) {
-
+
interp->addStackTrace++;
}
return rc;
}
@@ -17316,14 +17244,14 @@
if (argc >= 2) {
int retcode;
Jim_CallFrame *savedCallFrame, *targetCallFrame;
const char *str;
-
+
savedCallFrame = interp->framePtr;
-
+
str = Jim_String(argv[1]);
if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
argc--;
argv++;
@@ -17336,11 +17264,11 @@
}
if (argc < 2) {
Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
return JIM_ERR;
}
-
+
interp->framePtr = targetCallFrame;
if (argc == 2) {
retcode = Jim_EvalObj(interp, argv[1]);
}
else {
@@ -17438,15 +17366,15 @@
if (i != argc - 1 && i != argc) {
Jim_WrongNumArgs(interp, 1, argv,
"?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
}
-
+
if (stackTraceObj && returnCode == JIM_ERR) {
JimSetStackTrace(interp, stackTraceObj);
}
-
+
if (errorCodeObj && returnCode == JIM_ERR) {
Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
}
interp->returnCode = returnCode;
interp->returnLevel = level;
@@ -17463,31 +17391,31 @@
if (interp->framePtr->level == 0) {
Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
return JIM_ERR;
}
else if (argc >= 2) {
-
+
Jim_CallFrame *cf = interp->framePtr->parent;
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
if (cmdPtr == NULL) {
return JIM_ERR;
}
JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
-
+
JimIncrCmdRefCount(cmdPtr);
cf->tailcallCmd = cmdPtr;
-
+
JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
Jim_IncrRefCount(cf->tailcallObj);
-
+
return JIM_EVAL;
}
return JIM_OK;
}
@@ -17494,11 +17422,11 @@
static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *cmdList;
Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
-
+
cmdList = Jim_DuplicateObj(interp, prefixListObj);
Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
return JimEvalObjList(interp, cmdList);
}
@@ -17552,22 +17480,22 @@
else {
cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
}
if (cmd) {
-
+
Jim_Obj *qualifiedCmdNameObj;
const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
JimCreateCommand(interp, cmdname, cmd);
-
+
JimUpdateProcNamespace(interp, cmd, cmdname);
JimFreeQualifiedName(interp, qualifiedCmdNameObj);
-
+
Jim_SetResult(interp, argv[1]);
return JIM_OK;
}
return JIM_ERR;
}
@@ -17580,17 +17508,17 @@
if (argc < 2) {
Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
return JIM_ERR;
}
-
+
interp->local++;
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
interp->local--;
-
+
if (retcode == 0) {
Jim_Obj *cmdNameObj = Jim_GetResult(interp);
if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
return JIM_ERR;
@@ -17619,18 +17547,18 @@
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
return JIM_ERR;
}
-
+
cmdPtr->u.proc.upcall++;
JimIncrCmdRefCount(cmdPtr);
-
+
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
-
+
cmdPtr->u.proc.upcall--;
JimDecrCmdRefCount(interp, cmdPtr);
return retcode;
}
@@ -17657,11 +17585,11 @@
return JIM_ERR;
}
if (len == 3) {
#ifdef jim_ext_namespace
-
+
nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
#else
Jim_SetResultString(interp, "namespaces not enabled", -1);
return JIM_ERR;
#endif
@@ -17670,11 +17598,11 @@
bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
if (cmd) {
-
+
nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
Jim_IncrRefCount(nargv[0]);
memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17700,11 +17628,11 @@
static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int i;
Jim_CallFrame *targetCallFrame;
-
+
if (argc > 3 && (argc % 2 == 0)) {
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
argc--;
argv++;
}
@@ -17713,17 +17641,17 @@
}
if (targetCallFrame == NULL) {
return JIM_ERR;
}
-
+
if (argc < 3) {
Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
return JIM_ERR;
}
-
+
for (i = 1; i < argc; i += 2) {
if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
return JIM_ERR;
}
return JIM_OK;
@@ -17736,15 +17664,15 @@
if (argc < 2) {
Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
return JIM_ERR;
}
-
+
if (interp->framePtr->level == 0)
- return JIM_OK;
+ return JIM_OK;
for (i = 1; i < argc; i++) {
-
+
const char *name = Jim_String(argv[i]);
if (name[0] != ':' || name[1] != ':') {
if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
return JIM_ERR;
}
@@ -17767,21 +17695,21 @@
}
str = Jim_String(objPtr);
strLen = Jim_Utf8Length(interp, objPtr);
-
+
resultObjPtr = Jim_NewStringObj(interp, "", 0);
while (strLen) {
for (i = 0; i < numMaps; i += 2) {
- Jim_Obj *objPtr;
+ Jim_Obj *eachObjPtr;
const char *k;
int kl;
- objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
- k = Jim_String(objPtr);
- kl = Jim_Utf8Length(interp, objPtr);
+ eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
+ k = Jim_String(eachObjPtr);
+ kl = Jim_Utf8Length(interp, eachObjPtr);
if (strLen >= kl && kl) {
int rc;
rc = JimStringCompareLen(str, k, kl, nocase);
if (rc == 0) {
@@ -17794,11 +17722,11 @@
strLen -= kl;
break;
}
}
}
- if (i == numMaps) {
+ if (i == numMaps) {
int c;
if (noMatchStart == NULL)
noMatchStart = str;
str += utf8_tounicode(str, &c);
strLen--;
@@ -17859,11 +17787,11 @@
return JIM_OK;
case OPT_CAT:{
Jim_Obj *objPtr;
if (argc == 3) {
-
+
objPtr = argv[2];
}
else {
int i;
@@ -17878,11 +17806,11 @@
}
case OPT_COMPARE:
case OPT_EQUAL:
{
-
+
long opt_length = -1;
int n = argc - 4;
int i = 2;
while (n > 0) {
int subopt;
@@ -17891,16 +17819,16 @@
badcompareargs:
Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
return JIM_ERR;
}
if (subopt == 0) {
-
+
opt_case = 0;
n--;
}
else {
-
+
if (n < 2) {
goto badcompareargs;
}
if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
return JIM_ERR;
@@ -17911,11 +17839,11 @@
if (n) {
goto badcompareargs;
}
argv += argc - 2;
if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
-
+
Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
}
else {
if (opt_length >= 0) {
n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -18025,11 +17953,10 @@
}
case OPT_REVERSE:{
char *buf, *p;
const char *str;
- int len;
int i;
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "string");
return JIM_ERR;
@@ -18069,11 +17996,11 @@
}
if (idx < 0 || idx >= len || str == NULL) {
Jim_SetResultString(interp, "", 0);
}
else if (len == Jim_Length(argv[2])) {
-
+
Jim_SetResultString(interp, str + idx, 1);
}
else {
int c;
int i = utf8_index(str, idx);
@@ -18223,11 +18150,11 @@
{
int exitCode = 0;
int i;
int sig = 0;
-
+
jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
static const int max_ignore_code = sizeof(ignore_mask) * 8;
Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
@@ -18234,11 +18161,11 @@
for (i = 1; i < argc - 1; i++) {
const char *arg = Jim_String(argv[i]);
jim_wide option;
int ignore;
-
+
if (strcmp(arg, "--") == 0) {
i++;
break;
}
if (*arg != '-') {
@@ -18285,28 +18212,28 @@
sig++;
}
interp->signal_level += sig;
if (Jim_CheckSignal(interp)) {
-
+
exitCode = JIM_SIGNAL;
}
else {
exitCode = Jim_EvalObj(interp, argv[0]);
-
+
interp->errorFlag = 0;
}
interp->signal_level -= sig;
-
+
if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
-
+
return exitCode;
}
if (sig && exitCode == JIM_SIGNAL) {
-
+
if (interp->signal_set_result) {
interp->signal_set_result(interp, interp->sigmask);
}
else {
Jim_SetResultInt(interp, interp->sigmask);
@@ -18345,125 +18272,10 @@
}
Jim_SetResultInt(interp, exitCode);
return JIM_OK;
}
-#ifdef JIM_REFERENCES
-
-
-static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 3 && argc != 4) {
- Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?");
- return JIM_ERR;
- }
- if (argc == 3) {
- Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL));
- }
- else {
- Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3]));
- }
- return JIM_OK;
-}
-
-
-static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_Reference *refPtr;
-
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "reference");
- return JIM_ERR;
- }
- if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
- return JIM_ERR;
- Jim_SetResult(interp, refPtr->objPtr);
- return JIM_OK;
-}
-
-
-static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_Reference *refPtr;
-
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 1, argv, "reference newValue");
- return JIM_ERR;
- }
- if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
- return JIM_ERR;
- Jim_IncrRefCount(argv[2]);
- Jim_DecrRefCount(interp, refPtr->objPtr);
- refPtr->objPtr = argv[2];
- Jim_SetResult(interp, argv[2]);
- return JIM_OK;
-}
-
-
-static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "");
- return JIM_ERR;
- }
- Jim_SetResultInt(interp, Jim_Collect(interp));
-
-
- while (interp->freeList) {
- Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr;
- Jim_Free(interp->freeList);
- interp->freeList = nextObjPtr;
- }
-
- return JIM_OK;
-}
-
-
-static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 2 && argc != 3) {
- Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?");
- return JIM_ERR;
- }
- if (argc == 2) {
- Jim_Obj *cmdNamePtr;
-
- if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK)
- return JIM_ERR;
- if (cmdNamePtr != NULL)
- Jim_SetResult(interp, cmdNamePtr);
- }
- else {
- if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK)
- return JIM_ERR;
- Jim_SetResult(interp, argv[2]);
- }
- return JIM_OK;
-}
-
-
-static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_Obj *listObjPtr;
- Jim_HashTableIterator htiter;
- Jim_HashEntry *he;
-
- listObjPtr = Jim_NewListObj(interp, NULL, 0);
-
- JimInitHashTableIterator(&interp->references, &htiter);
- while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
- char buf[JIM_REFERENCE_SPACE + 1];
- Jim_Reference *refPtr = Jim_GetHashEntryVal(he);
- const unsigned long *refId = he->key;
-
- JimFormatReference(buf, refPtr, *refId);
- Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
- }
- Jim_SetResult(interp, listObjPtr);
- return JIM_OK;
-}
-#endif
static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
if (argc != 3) {
@@ -18494,11 +18306,11 @@
JimDictMatchCallbackType *callback, int type)
{
Jim_HashEntry *he;
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
-
+
Jim_HashTableIterator htiter;
JimInitHashTableIterator(ht, &htiter);
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
callback(interp, listObjPtr, he, type);
@@ -18544,11 +18356,11 @@
return JIM_ERR;
}
ht = (Jim_HashTable *)objPtr->internalRep.ptr;
-
+
printf("%d entries in table, %d buckets\n", ht->used, ht->size);
for (i = 0; i < ht->size; i++) {
Jim_HashEntry *he = ht->table[i];
@@ -18668,16 +18480,16 @@
return JIM_OK;
}
if (Jim_DictSize(interp, argv[2]) < 0) {
return JIM_ERR;
}
-
+
break;
case OPT_UPDATE:
if (argc < 6 || argc % 2) {
-
+
argc = 2;
}
break;
case OPT_CREATE:
@@ -18694,11 +18506,11 @@
Jim_WrongNumArgs(interp, 2, argv, "dictionary");
return JIM_ERR;
}
return Jim_DictInfo(interp, argv[2]);
}
-
+
return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
}
static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18764,11 +18576,11 @@
#ifdef jim_ext_namespace
int nons = 0;
if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
-
+
argc--;
argv++;
nons = 1;
}
#endif
@@ -18780,11 +18592,11 @@
if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
!= JIM_OK) {
return JIM_ERR;
}
-
+
switch (cmd) {
case INFO_EXISTS:
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "varName");
return JIM_ERR;
@@ -18809,21 +18621,21 @@
Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
return JIM_OK;
}
case INFO_CHANNELS:
- mode++;
+ mode++;
#ifndef jim_ext_aio
Jim_SetResultString(interp, "aio not enabled", -1);
return JIM_ERR;
#endif
-
+
case INFO_PROCS:
- mode++;
-
+ mode++;
+
case INFO_COMMANDS:
-
+
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
return JIM_ERR;
}
#ifdef jim_ext_namespace
@@ -18835,17 +18647,17 @@
#endif
Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
break;
case INFO_VARS:
- mode++;
-
+ mode++;
+
case INFO_LOCALS:
- mode++;
-
+ mode++;
+
case INFO_GLOBALS:
-
+
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
return JIM_ERR;
}
#ifdef jim_ext_namespace
@@ -18951,13 +18763,12 @@
case INFO_ARGS:
Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
break;
case INFO_STATICS:
if (cmdPtr->u.proc.staticVars) {
- int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
- NULL, JimVariablesMatch, mode));
+ NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES));
}
break;
}
break;
}
@@ -18985,15 +18796,15 @@
}
}
break;
case INFO_HOSTNAME:
-
+
return Jim_Eval(interp, "os.gethostname");
case INFO_NAMEOFEXECUTABLE:
-
+
return Jim_Eval(interp, "{info nameofexecutable}");
case INFO_RETURNCODES:
if (argc == 2) {
int i;
@@ -19070,11 +18881,11 @@
if (option == OPT_VAR) {
result = Jim_GetVariable(interp, objPtr, 0) != NULL;
}
else {
-
+
Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
if (cmd) {
switch (option) {
case OPT_COMMAND:
@@ -19113,11 +18924,11 @@
if (len == 0) {
return JIM_OK;
}
strLen = Jim_Utf8Length(interp, argv[1]);
-
+
if (argc == 2) {
splitChars = " \n\t\r";
splitLen = 4;
}
else {
@@ -19126,11 +18937,11 @@
}
noMatchStart = str;
resObjPtr = Jim_NewListObj(interp, NULL, 0);
-
+
if (splitLen) {
Jim_Obj *objPtr;
while (strLen--) {
const char *sc = splitChars;
int scLen = splitLen;
@@ -19155,11 +18966,11 @@
#define NUM_COMMON (128 - 9)
while (strLen--) {
int n = utf8_tounicode(str, &c);
#ifdef JIM_OPTIMIZATION
if (c >= 9 && c < 128) {
-
+
c -= 9;
if (!commonObj) {
commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
}
@@ -19189,11 +19000,11 @@
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
return JIM_ERR;
}
-
+
if (argc == 2) {
joinStr = " ";
joinStrLen = 1;
}
else {
@@ -19468,13 +19279,13 @@
return -1;
else if (step < 0 && end > start)
return -1;
len = end - start;
if (len < 0)
- len = -len;
+ len = -len;
if (step < 0)
- step = -step;
+ step = -step;
len = 1 + ((len - 1) / step);
if (len > INT_MAX)
len = INT_MAX;
return (int)((len < 0) ? -1 : len);
}
@@ -19688,11 +19499,11 @@
*indexPtr = -1;
for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
-
+
*indexPtr = i;
return JIM_OK;
}
if (flags & JIM_ENUM_ABBREV) {
if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19706,11 +19517,11 @@
match = i;
}
}
}
-
+
if (match >= 0) {
*indexPtr = match;
return JIM_OK;
}
@@ -19743,11 +19554,11 @@
return objPtr->typePtr == &listObjType;
}
void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
{
-
+
int len = strlen(format);
int extra = 0;
int n = 0;
const char *params[5];
char *buf;
@@ -19808,11 +19619,11 @@
#include
static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
-
+
return JIM_OK;
}
static const jim_subcmd_type dummy_subcmd = {
"dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19887,43 +19698,43 @@
return 0;
}
cmd = argv[1];
-
+
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
if (argc == 2) {
-
+
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}
help = 1;
-
+
cmd = argv[2];
}
-
+
if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
-
+
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
add_commands(interp, command_table, " ");
return &dummy_subcmd;
}
cmdstr = Jim_GetString(cmd, &cmdlen);
for (ct = command_table; ct->cmd; ct++) {
if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
-
+
break;
}
if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
if (partial) {
-
+
if (help) {
-
+
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}
bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
return 0;
@@ -19931,44 +19742,44 @@
partial = ct;
}
continue;
}
-
+
if (partial && !ct->cmd) {
ct = partial;
}
if (!ct->cmd) {
-
+
if (help) {
-
+
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}
bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
return 0;
}
if (help) {
Jim_SetResultString(interp, "Usage: ", -1);
-
+
add_cmd_usage(interp, ct, argv[0]);
return &dummy_subcmd;
}
-
+
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
-
+
add_cmd_usage(interp, ct, argv[0]);
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
return 0;
}
-
+
return ct;
}
int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
{
@@ -20019,11 +19830,11 @@
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
*p = 0x80 | (uc & 0x3f);
return 3;
}
-
+
else {
*p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
*p++ = 0x80 | ((uc & 0x3f000) >> 12);
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
*p = 0x80 | (uc & 0x3f);
@@ -20210,11 +20021,11 @@
if (ch == 'h') {
useShort = 1;
format += step;
step = utf8_tounicode(format, &ch);
} else if (ch == 'l') {
-
+
format += step;
step = utf8_tounicode(format, &ch);
if (ch == 'l') {
format += step;
step = utf8_tounicode(format, &ch);
@@ -20237,11 +20048,11 @@
goto errorMsg;
case 's': {
formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
if (gotPrecision && (precision < formatted_chars)) {
-
+
formatted_chars = precision;
formatted_bytes = utf8_index(formatted_buf, precision);
}
break;
}
@@ -20249,11 +20060,11 @@
jim_wide code;
if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
goto error;
}
-
+
formatted_bytes = utf8_getchars(spec, code);
formatted_buf = spec;
formatted_chars = 1;
break;
}
@@ -20267,11 +20078,11 @@
goto error;
}
length = sizeof(w) * 8;
-
+
if (num_buffer_size < length + 1) {
num_buffer_size = length + 1;
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
}
@@ -20295,29 +20106,29 @@
case 'E':
case 'f':
case 'g':
case 'G':
doubleType = 1;
-
+
case 'd':
case 'u':
case 'o':
case 'x':
case 'X': {
jim_wide w;
double d;
int length;
-
+
if (width) {
p += sprintf(p, "%ld", width);
}
if (gotPrecision) {
p += sprintf(p, ".%ld", precision);
}
-
+
if (doubleType) {
if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
goto error;
}
length = MAX_FLOAT_WIDTH;
@@ -20344,19 +20155,19 @@
}
*p++ = (char) ch;
*p = '\0';
-
+
if (width > length) {
length = width;
}
if (gotPrecision) {
length += precision;
}
-
+
if (num_buffer_size < length + 1) {
num_buffer_size = length + 1;
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
}
@@ -20370,11 +20181,11 @@
formatted_buf = num_buffer;
break;
}
default: {
-
+
spec[0] = ch;
spec[1] = '\0';
Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
goto error;
}
@@ -20422,37 +20233,37 @@
#define REG_MAX_PAREN 100
-#define END 0
-#define BOL 1
-#define EOL 2
-#define ANY 3
-#define ANYOF 4
-#define ANYBUT 5
-#define BRANCH 6
-#define BACK 7
-#define EXACTLY 8
-#define NOTHING 9
-#define REP 10
-#define REPMIN 11
-#define REPX 12
-#define REPXMIN 13
-#define BOLX 14
-#define EOLX 15
-#define WORDA 16
-#define WORDZ 17
-
-#define OPENNC 1000
-#define OPEN 1001
-
-
-
-
-#define CLOSENC 2000
-#define CLOSE 2001
+#define END 0
+#define BOL 1
+#define EOL 2
+#define ANY 3
+#define ANYOF 4
+#define ANYBUT 5
+#define BRANCH 6
+#define BACK 7
+#define EXACTLY 8
+#define NOTHING 9
+#define REP 10
+#define REPMIN 11
+#define REPX 12
+#define REPXMIN 13
+#define BOLX 14
+#define EOLX 15
+#define WORDA 16
+#define WORDZ 17
+
+#define OPENNC 1000
+#define OPEN 1001
+
+
+
+
+#define CLOSENC 2000
+#define CLOSE 2001
#define CLOSE_END (CLOSE+REG_MAX_PAREN)
#define REG_MAGIC 0xFADED00D
@@ -20465,18 +20276,18 @@
#define FAIL(R,M) { (R)->err = (M); return (M); }
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
#define META "^$.[()|?{+*"
-#define HASWIDTH 1
-#define SIMPLE 2
-#define SPSTART 4
-#define WORST 0
+#define HASWIDTH 1
+#define SIMPLE 2
+#define SPSTART 4
+#define WORST 0
#define MAX_REP_COUNT 1000000
-static int reg(regex_t *preg, int paren , int *flagp );
+static int reg(regex_t *preg, int paren, int *flagp );
static int regpiece(regex_t *preg, int *flagp );
static int regbranch(regex_t *preg, int *flagp );
static int regatom(regex_t *preg, int *flagp );
static int regnode(regex_t *preg, int op );
static int regnext(regex_t *preg, int p );
@@ -20520,15 +20331,15 @@
memset(preg, 0, sizeof(*preg));
if (exp == NULL)
FAIL(preg, REG_ERR_NULL_ARGUMENT);
-
+
preg->cflags = cflags;
preg->regparse = exp;
-
+
preg->proglen = (strlen(exp) + 1) * 5;
preg->program = malloc(preg->proglen * sizeof(int));
if (preg->program == NULL)
FAIL(preg, REG_ERR_NOMEM);
@@ -20535,24 +20346,24 @@
regc(preg, REG_MAGIC);
if (reg(preg, 0, &flags) == 0) {
return preg->err;
}
-
- if (preg->re_nsub >= REG_MAX_PAREN)
+
+ if (preg->re_nsub >= REG_MAX_PAREN)
FAIL(preg,REG_ERR_TOO_BIG);
-
- preg->regstart = 0;
+
+ preg->regstart = 0;
preg->reganch = 0;
preg->regmust = 0;
preg->regmlen = 0;
- scan = 1;
- if (OP(preg, regnext(preg, scan)) == END) {
+ scan = 1;
+ if (OP(preg, regnext(preg, scan)) == END) {
scan = OPERAND(scan);
-
+
if (OP(preg, scan) == EXACTLY) {
preg->regstart = preg->program[OPERAND(scan)];
}
else if (OP(preg, scan) == BOL)
preg->reganch++;
@@ -20579,24 +20390,24 @@
#endif
return 0;
}
-static int reg(regex_t *preg, int paren , int *flagp )
+static int reg(regex_t *preg, int paren, int *flagp )
{
int ret;
int br;
int ender;
int parno = 0;
int flags;
- *flagp = HASWIDTH;
+ *flagp = HASWIDTH;
-
+
if (paren) {
if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
-
+
preg->regparse += 2;
parno = -1;
}
else {
parno = ++preg->re_nsub;
@@ -20603,16 +20414,16 @@
}
ret = regnode(preg, OPEN+parno);
} else
ret = 0;
-
+
br = regbranch(preg, &flags);
if (br == 0)
return 0;
if (ret != 0)
- regtail(preg, ret, br);
+ regtail(preg, ret, br);
else
ret = br;
if (!(flags&HASWIDTH))
*flagp &= ~HASWIDTH;
*flagp |= flags&SPSTART;
@@ -20619,25 +20430,25 @@
while (*preg->regparse == '|') {
preg->regparse++;
br = regbranch(preg, &flags);
if (br == 0)
return 0;
- regtail(preg, ret, br);
+ regtail(preg, ret, br);
if (!(flags&HASWIDTH))
*flagp &= ~HASWIDTH;
*flagp |= flags&SPSTART;
}
-
+
ender = regnode(preg, (paren) ? CLOSE+parno : END);
regtail(preg, ret, ender);
-
+
for (br = ret; br != 0; br = regnext(preg, br))
regoptail(preg, br, ender);
-
+
if (paren && *preg->regparse++ != ')') {
preg->err = REG_ERR_UNMATCHED_PAREN;
return 0;
} else if (!paren && *preg->regparse != '\0') {
if (*preg->regparse == ')') {
@@ -20657,11 +20468,11 @@
int ret;
int chain;
int latest;
int flags;
- *flagp = WORST;
+ *flagp = WORST;
ret = regnode(preg, BRANCH);
chain = 0;
while (*preg->regparse != '\0' && *preg->regparse != ')' &&
*preg->regparse != '|') {
@@ -20675,11 +20486,11 @@
else {
regtail(preg, chain, latest);
}
chain = latest;
}
- if (chain == 0)
+ if (chain == 0)
(void) regnode(preg, NOTHING);
return(ret);
}
@@ -20705,11 +20516,11 @@
if (!(flags&HASWIDTH) && op != '?') {
preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
return 0;
}
-
+
if (op == '{') {
char *end;
min = strtoul(preg->regparse + 1, &end, 10);
if (end == preg->regparse + 1) {
@@ -20777,11 +20588,11 @@
static void reg_addrange(regex_t *preg, int lower, int upper)
{
if (lower > upper) {
reg_addrange(preg, upper, lower);
}
-
+
regc(preg, upper - lower + 1);
regc(preg, lower);
}
static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20845,17 +20656,17 @@
case 'r': *ch = '\r'; break;
case 't': *ch = '\t'; break;
case 'v': *ch = '\v'; break;
case 'u':
if (*s == '{') {
-
+
n = parse_hex(s + 1, 6, ch);
if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
s += n + 2;
}
else {
-
+
*ch = 'u';
}
}
else if ((n = parse_hex(s, 4, ch)) > 0) {
s += n;
@@ -20886,15 +20697,15 @@
int nocase = (preg->cflags & REG_ICASE);
int ch;
int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
- *flagp = WORST;
+ *flagp = WORST;
preg->regparse += n;
switch (ch) {
-
+
case '^':
ret = regnode(preg, BOL);
break;
case '$':
ret = regnode(preg, EOL);
@@ -20904,24 +20715,24 @@
*flagp |= HASWIDTH|SIMPLE;
break;
case '[': {
const char *pattern = preg->regparse;
- if (*pattern == '^') {
+ if (*pattern == '^') {
ret = regnode(preg, ANYBUT);
pattern++;
} else
ret = regnode(preg, ANYOF);
-
+
if (*pattern == ']' || *pattern == '-') {
reg_addrange(preg, *pattern, *pattern);
pattern++;
}
while (*pattern && *pattern != ']') {
-
+
int start;
int end;
pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
if (start == '\\') {
@@ -20930,11 +20741,11 @@
preg->err = REG_ERR_NULL_CHAR;
return 0;
}
}
if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
-
+
pattern += utf8_tounicode(pattern, &end);
pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
if (end == '\\') {
pattern += reg_decode_escape(pattern, &end);
if (end == 0) {
@@ -20957,22 +20768,22 @@
CC_NUM
};
int i;
for (i = 0; i < CC_NUM; i++) {
- int n = strlen(character_class[i]);
+ n = strlen(character_class[i]);
if (strncmp(pattern, character_class[i], n) == 0) {
-
+
pattern += n + 1;
break;
}
}
if (i != CC_NUM) {
switch (i) {
case CC_ALNUM:
reg_addrange(preg, '0', '9');
-
+
case CC_ALPHA:
if ((preg->cflags & REG_ICASE) == 0) {
reg_addrange(preg, 'a', 'z');
}
reg_addrange(preg, 'A', 'Z');
@@ -20990,11 +20801,11 @@
reg_addrange(preg, 'a', 'z');
break;
case CC_XDIGIT:
reg_addrange(preg, 'a', 'f');
reg_addrange(preg, 'A', 'F');
-
+
case CC_DIGIT:
reg_addrange(preg, '0', '9');
break;
case CC_CNTRL:
reg_addrange(preg, 0, 31);
@@ -21014,11 +20825,11 @@
break;
}
continue;
}
}
-
+
reg_addrange(preg, start, start);
}
regc(preg, '\0');
if (*pattern) {
@@ -21037,11 +20848,11 @@
break;
case '\0':
case '|':
case ')':
preg->err = REG_ERR_INTERNAL;
- return 0;
+ return 0;
case '?':
case '+':
case '*':
case '{':
preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
@@ -21090,34 +20901,34 @@
ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT);
reg_addrange_str(preg," \t\r\n\f\v");
regc(preg, '\0');
*flagp |= HASWIDTH|SIMPLE;
break;
-
+
default:
-
-
+
+
preg->regparse--;
goto de_fault;
}
break;
de_fault:
default: {
int added = 0;
-
+
preg->regparse -= n;
ret = regnode(preg, EXACTLY);
-
+
while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
if (ch == '\\' && preg->regparse[n]) {
if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) {
-
+
break;
}
n += reg_decode_escape(preg->regparse + n, &ch);
if (ch == 0) {
preg->err = REG_ERR_NULL_CHAR;
@@ -21125,23 +20936,23 @@
}
}
if (ISMULT(preg->regparse[n])) {
-
+
if (added) {
-
+
break;
}
-
+
regc(preg, ch);
added++;
preg->regparse += n;
break;
}
-
+
regc(preg, ch);
added++;
preg->regparse += n;
}
regc(preg, '\0');
@@ -21168,15 +20979,15 @@
static int regnode(regex_t *preg, int op)
{
reg_grow(preg, 2);
-
+
preg->program[preg->p++] = op;
preg->program[preg->p++] = 0;
-
+
return preg->p - 2;
}
static void regc(regex_t *preg, int b )
{
@@ -21186,13 +20997,13 @@
static int reginsert(regex_t *preg, int op, int size, int opnd )
{
reg_grow(preg, size);
-
+
memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
-
+
memset(preg->program + opnd, 0, sizeof(int) * size);
preg->program[opnd] = op;
preg->p += size;
@@ -21204,11 +21015,11 @@
{
int scan;
int temp;
int offset;
-
+
scan = p;
for (;;) {
temp = regnext(preg, scan);
if (temp == 0)
break;
@@ -21224,11 +21035,11 @@
}
static void regoptail(regex_t *preg, int p, int val )
{
-
+
if (p != 0 && OP(preg, p) == BRANCH) {
regtail(preg, OPERAND(p), val);
}
}
@@ -21240,16 +21051,16 @@
int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
{
const char *s;
int scan;
-
+
if (preg == NULL || preg->program == NULL || string == NULL) {
return REG_ERR_NULL_ARGUMENT;
}
-
+
if (*preg->program != REG_MAGIC) {
return REG_ERR_CORRUPTED;
}
#ifdef DEBUG
@@ -21258,51 +21069,51 @@
#endif
preg->eflags = eflags;
preg->pmatch = pmatch;
preg->nmatch = nmatch;
- preg->start = string;
+ preg->start = string;
-
+
for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
int op = OP(preg, scan);
if (op == END)
break;
if (op == REPX || op == REPXMIN)
preg->program[scan + 4] = 0;
}
-
+
if (preg->regmust != 0) {
s = string;
while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
break;
}
s++;
}
- if (s == NULL)
+ if (s == NULL)
return REG_NOMATCH;
}
-
+
preg->regbol = string;
-
+
if (preg->reganch) {
if (eflags & REG_NOTBOL) {
-
+
goto nextline;
}
while (1) {
if (regtry(preg, string)) {
return REG_NOERROR;
}
if (*string) {
nextline:
if (preg->cflags & REG_NEWLINE) {
-
+
string = strchr(string, '\n');
if (string) {
preg->regbol = ++string;
continue;
}
@@ -21310,22 +21121,22 @@
}
return REG_NOMATCH;
}
}
-
+
s = string;
if (preg->regstart != '\0') {
-
+
while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
if (regtry(preg, s))
return REG_NOERROR;
s++;
}
}
else
-
+
while (1) {
if (regtry(preg, s))
return REG_NOERROR;
if (*s == '\0') {
break;
@@ -21334,15 +21145,15 @@
int c;
s += utf8_tounicode(s, &c);
}
}
-
+
return REG_NOMATCH;
}
-
+
static int regtry( regex_t *preg, const char *string )
{
int i;
preg->reginput = string;
@@ -21379,11 +21190,11 @@
}
static int reg_range_find(const int *range, int c)
{
while (*range) {
-
+
if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
return 1;
}
range += 2;
}
@@ -21391,11 +21202,11 @@
}
static const char *str_find(const char *string, int c, int nocase)
{
if (nocase) {
-
+
c = utf8_upper(c);
}
while (*string) {
int ch;
int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21435,15 +21246,15 @@
no = regrepeat(preg, scan + 5, max);
if (no < min) {
return 0;
}
if (matchmin) {
-
+
max = no;
no = min;
}
-
+
while (1) {
if (matchmin) {
if (no > max) {
break;
}
@@ -21453,22 +21264,22 @@
break;
}
}
preg->reginput = save + utf8_index(save, no);
reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
-
+
if (reg_iseol(preg, nextch) || c == nextch) {
if (regmatch(preg, next)) {
return(1);
}
}
if (matchmin) {
-
+
no++;
}
else {
-
+
no--;
}
}
return(0);
}
@@ -21478,13 +21289,13 @@
int *scanpt = preg->program + scan;
int max = scanpt[2];
int min = scanpt[3];
-
+
if (scanpt[4] < min) {
-
+
scanpt[4]++;
if (regmatch(preg, scan + 5)) {
return 1;
}
scanpt[4]--;
@@ -21493,39 +21304,39 @@
if (scanpt[4] > max) {
return 0;
}
if (matchmin) {
-
+
if (regmatch(preg, regnext(preg, scan))) {
return 1;
}
-
+
scanpt[4]++;
if (regmatch(preg, scan + 5)) {
return 1;
}
scanpt[4]--;
return 0;
}
-
+
if (scanpt[4] < max) {
scanpt[4]++;
if (regmatch(preg, scan + 5)) {
return 1;
}
scanpt[4]--;
}
-
+
return regmatch(preg, regnext(preg, scan));
}
static int regmatch(regex_t *preg, int prog)
{
- int scan;
- int next;
+ int scan;
+ int next;
const char *save;
scan = prog;
#ifdef DEBUG
@@ -21535,11 +21346,11 @@
while (scan != 0) {
int n;
int c;
#ifdef DEBUG
if (regnarrate) {
- fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
+ fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
}
#endif
next = regnext(preg, scan);
n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
@@ -21546,49 +21357,49 @@
switch (OP(preg, scan)) {
case BOLX:
if ((preg->eflags & REG_NOTBOL)) {
return(0);
}
-
+
case BOL:
if (preg->reginput != preg->regbol) {
return(0);
}
break;
case EOLX:
if (c != 0) {
-
+
return 0;
}
break;
case EOL:
if (!reg_iseol(preg, c)) {
return(0);
}
break;
case WORDA:
-
+
if ((!isalnum(UCHAR(c))) && c != '_')
return(0);
-
+
if (preg->reginput > preg->regbol &&
(isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
return(0);
break;
case WORDZ:
-
+
if (preg->reginput > preg->regbol) {
-
+
if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
c = preg->reginput[-1];
-
+
if (isalnum(UCHAR(c)) || c == '_') {
break;
}
}
}
-
+
return(0);
case ANY:
if (reg_iseol(preg, c))
return 0;
@@ -21624,12 +21435,12 @@
case NOTHING:
break;
case BACK:
break;
case BRANCH:
- if (OP(preg, next) != BRANCH)
- next = OPERAND(scan);
+ if (OP(preg, next) != BRANCH)
+ next = OPERAND(scan);
else {
do {
save = preg->reginput;
if (regmatch(preg, OPERAND(scan))) {
return(1);
@@ -21636,11 +21447,11 @@
}
preg->reginput = save;
scan = regnext(preg, scan);
} while (scan != 0 && OP(preg, scan) == BRANCH);
return(0);
-
+
}
break;
case REP:
case REPMIN:
return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21648,11 +21459,11 @@
case REPX:
case REPXMIN:
return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
case END:
- return 1;
+ return 1;
case OPENNC:
case CLOSENC:
return regmatch(preg, next);
@@ -21695,11 +21506,11 @@
scan = preg->reginput;
opnd = OPERAND(p);
switch (OP(preg, p)) {
case ANY:
-
+
while (!reg_iseol(preg, *scan) && count < max) {
count++;
scan++;
}
break;
@@ -21731,13 +21542,13 @@
}
count++;
scan += n;
}
break;
- default:
+ default:
preg->err = REG_ERR_INTERNAL;
- count = 0;
+ count = 0;
break;
}
preg->reginput = scan;
return(count);
@@ -21758,11 +21569,11 @@
return(p+offset);
}
static int regopsize(regex_t *preg, int p )
{
-
+
switch (OP(preg, p)) {
case REP:
case REPMIN:
case REPX:
case REPXMIN:
@@ -21879,26 +21690,26 @@
{
DIR *dir = 0;
if (name && name[0]) {
size_t base_length = strlen(name);
- const char *all =
+ const char *all =
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
(dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
strcat(strcpy(dir->name, name), all);
if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
dir->result.d_name = 0;
- else {
+ else {
Jim_Free(dir->name);
Jim_Free(dir);
dir = 0;
}
}
- else {
+ else {
Jim_Free(dir);
dir = 0;
errno = ENOMEM;
}
}
@@ -21916,11 +21727,11 @@
if (dir->handle != -1)
result = _findclose(dir->handle);
Jim_Free(dir->name);
Jim_Free(dir);
}
- if (result == -1)
+ if (result == -1)
errno = EBADF;
return result;
}
struct dirent *readdir(DIR * dir)
@@ -21999,11 +21810,11 @@
}
void Jim_HistoryShow(void)
{
#ifdef USE_LINENOISE
-
+
int i;
int len;
char **history = linenoiseHistory(&len);
for (i = 0; i < len; i++) {
printf("%4d %s\n", i + 1, history[i]);
@@ -22065,11 +21876,11 @@
Jim_DecrRefCount(interp, scriptObjPtr);
retcode = JIM_OK;
goto out;
}
if (Jim_Length(scriptObjPtr) != 0) {
-
+
Jim_AppendString(interp, scriptObjPtr, "\n", 1);
}
Jim_AppendString(interp, scriptObjPtr, line, -1);
free(line);
if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
@@ -22077,11 +21888,11 @@
snprintf(prompt, sizeof(prompt), "%c> ", state);
}
#ifdef USE_LINENOISE
if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
-
+
Jim_HistoryShow();
Jim_DecrRefCount(interp, scriptObjPtr);
continue;
}
@@ -22120,11 +21931,11 @@
static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
{
int n;
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
-
+
for (n = 0; n < argc; n++) {
Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
Jim_ListAppendElement(interp, listObj, obj);
}
@@ -22160,47 +21971,47 @@
{
int retcode;
Jim_Interp *interp;
char *const orig_argv0 = argv[0];
-
+
if (argc > 1 && strcmp(argv[1], "--version") == 0) {
printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
return 0;
}
else if (argc > 1 && strcmp(argv[1], "--help") == 0) {
usage(argv[0]);
return 0;
}
-
+
interp = Jim_CreateInterp();
Jim_RegisterCoreCommands(interp);
-
+
if (Jim_InitStaticExtensions(interp) != JIM_OK) {
JimPrintErrorMessage(interp);
}
Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0);
Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
retcode = Jim_initjimshInit(interp);
if (argc == 1) {
-
+
if (retcode == JIM_ERR) {
JimPrintErrorMessage(interp);
}
if (retcode != JIM_EXIT) {
JimSetArgv(interp, 0, NULL);
retcode = Jim_InteractivePrompt(interp);
}
}
else {
-
+
if (argc > 2 && strcmp(argv[1], "-e") == 0) {
-
+
JimSetArgv(interp, argc - 3, argv + 3);
retcode = Jim_Eval(interp, argv[2]);
if (retcode != JIM_ERR) {
printf("%s\n", Jim_String(Jim_GetResult(interp)));
}
Index: autosetup/local.tcl
==================================================================
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,8 +1,7 @@
-# For this project, disable the pager for --help and --ref
-# The user can still enable by using --nopager=0 or --disable-nopager
-dict set autosetup(optdefault) nopager 1
+# For this project, disable the pager for --help
+set useropts(nopager) 1
# Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
# Returns a dictionary of the contents of the tclConfig.sh file, or
# empty if not found
proc parse-tclconfig-sh {args} {
Index: autosetup/pkg-config.tcl
==================================================================
--- autosetup/pkg-config.tcl
+++ autosetup/pkg-config.tcl
@@ -35,16 +35,12 @@
set found 0
define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
msg-checking "Checking for pkg-config..."
- if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
- msg-result "[get-define PKG_CONFIG] (not found)"
- if {$required} {
- user-error "No usable pkg-config"
- }
- } else {
+ try {
+ set version [exec [get-define PKG_CONFIG] --version]
msg-result $version
define PKG_CONFIG_VERSION $version
set found 1
@@ -74,10 +70,16 @@
set env(PKG_CONFIG_DIR) ""
# Do we need to try /usr/local as well or instead?
set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig
set env(PKG_CONFIG_SYSROOT_DIR) $sysroot
}
+
+ } on error msg {
+ msg-result "[get-define PKG_CONFIG] (not found)"
+ if {$required} {
+ user-error "No usable pkg-config"
+ }
}
define HAVE_PKG_CONFIG $found
return $found
}
@@ -105,23 +107,25 @@
if {!$ok} {
msg-result "no pkg-config"
return 0
}
- if {[catch {exec [get-define PKG_CONFIG] --modversion "$module $args"} version]} {
+ try {
+ set version [exec [get-define PKG_CONFIG] --modversion "$module $args"]
+ msg-result $version
+ set prefix [feature-define-name $module PKG_]
+ define HAVE_${prefix}
+ define ${prefix}_VERSION $version
+ define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
+ define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
+ define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
+ return 1
+ } on error msg {
msg-result "not found"
- configlog "pkg-config --modversion $module $args: $version"
+ configlog "pkg-config --modversion $module $args: $msg"
return 0
}
- msg-result $version
- set prefix [feature-define-name $module PKG_]
- define HAVE_${prefix}
- define ${prefix}_VERSION $version
- define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
- define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
- define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
- return 1
}
# @pkg-config-get module setting
#
# Convenience access to the results of pkg-config
Index: autosetup/system.tcl
==================================================================
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -7,30 +7,17 @@
# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT
#
# It also support the 'feature' naming convention, where searching
# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H
#
-# It defines the following variables, based on --prefix unless overridden by the user:
-#
-## datadir
-## sysconfdir
-## sharedstatedir
-## localstatedir
-## infodir
-## mandir
-## includedir
-
-# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
-set defaultprefix [get-define defaultprefix /usr/local]
-
-module-options [subst -noc -nob {
+module-options {
host:host-alias => {a complete or partial cpu-vendor-opsys for the system where
the application will run (defaults to the same value as --build)}
build:build-alias => {a complete or partial cpu-vendor-opsys for the system
where the application will be built (defaults to the
result of running config.guess)}
- prefix:dir => {the target directory for the build (defaults to '$defaultprefix')}
+ prefix:dir => {the target directory for the build (defaults to /usr/local)}
# These (hidden) options are supported for autoconf/automake compatibility
exec-prefix:
bindir:
sbindir:
@@ -43,11 +30,11 @@
sysconfdir:
sharedstatedir:
localstatedir:
maintainer-mode=0
dependency-tracking=0
-}]
+}
# Returns 1 if exists, or 0 if not
#
proc check-feature {name code} {
msg-checking "Checking for $name..."
@@ -119,11 +106,11 @@
# If $outfile is blank/omitted, $template should end with ".in" which
# is removed to create the output file name.
#
# Each pattern of the form @define@ is replaced with the corresponding
# define, if it exists, or left unchanged if not.
-#
+#
# The special value @srcdir@ is substituted with the relative
# path to the source directory from the directory where the output
# file is created, while the special value @top_srcdir@ is substituted
# with the relative path to the top level source directory.
#
@@ -230,11 +217,12 @@
define host [config_sub $host]
set cross $host-
}
define cross [get-env CROSS $cross]
-set prefix [opt-val prefix $defaultprefix]
+# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
+set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
# These are for compatibility with autoconf
define target [get-define host]
define prefix $prefix
define builddir $autosetup(builddir)
Index: src/add.c
==================================================================
--- src/add.c
+++ src/add.c
@@ -272,12 +272,12 @@
** Options:
**
** --case-sensitive Override the case-sensitive setting.
** --dotfiles include files beginning with a dot (".")
** -f|--force Add files without prompting
-** --ignore Ignore unmanaged files matching patterns from
-** the comma separated list of glob patterns.
+** --ignore Ignore files matching patterns from the
+** comma separated list of glob patterns.
** --clean Also ignore files matching patterns from
** the comma separated list of glob patterns.
** --no-dir-symlinks Disables support for directory symlinks.
**
** See also: addremove, rm
@@ -619,12 +619,12 @@
** This command can be used to track third party software.
**
** Options:
** --case-sensitive Override the case-sensitive setting.
** --dotfiles Include files beginning with a dot (".")
-** --ignore Ignore unmanaged files matching patterns from
-** the comma separated list of glob patterns.
+** --ignore Ignore files matching patterns from the
+** comma separated list of glob patterns.
** --clean Also ignore files matching patterns from
** the comma separated list of glob patterns.
** -n|--dry-run If given, display instead of run actions.
** --no-dir-symlinks Disables support for directory symlinks.
**
Index: src/checkin.c
==================================================================
--- src/checkin.c
+++ src/checkin.c
@@ -1202,18 +1202,14 @@
"# Type \".\" on a line by itself when you are done:\n", -1);
zFile = mprintf("-");
}else{
Blob fname;
blob_zero(&fname);
- if( g.zLocalRoot!=0 ){
- file_relative_name(g.zLocalRoot, &fname, 1);
- zFile = db_text(0, "SELECT '%qci-comment-'||hex(randomblob(6))||'.txt'",
- blob_str(&fname));
- }else{
- file_tempname(&fname, "ci-comment");
- zFile = mprintf("%s", blob_str(&fname));
- }
+ assert( g.zLocalRoot!=0 );
+ file_relative_name(g.zLocalRoot, &fname, 1);
+ zFile = db_text(0, "SELECT '%qci-comment-'||hex(randomblob(6))||'.txt'",
+ blob_str(&fname));
blob_reset(&fname);
}
#if defined(_WIN32)
blob_add_cr(pPrompt);
#endif
Index: src/config.h
==================================================================
--- src/config.h
+++ src/config.h
@@ -173,25 +173,11 @@
# endif
#endif
#if !defined(_RC_COMPILE_) && !defined(SQLITE_AMALGAMATION)
-/*
-** MSVC does not include the "stdint.h" header file until 2010.
-*/
-#if defined(_MSC_VER) && _MSC_VER<1600
- typedef __int32 int32_t;
- typedef unsigned __int32 uint32_t;
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
-#else
-# include
-#endif
-
-#if USE_SEE && !defined(SQLITE_HAS_CODEC)
-# define SQLITE_HAS_CODEC
-#endif
+#include
#include "sqlite3.h"
/*
** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257.
*/
Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -34,13 +34,10 @@
# include
# endif
#else
# include
#endif
-#if USE_SEE && !defined(SQLITE_HAS_CODEC)
-# define SQLITE_HAS_CODEC
-#endif
#include
#include
#include
#include
#include
@@ -1043,39 +1040,18 @@
}
#endif
}
-/*
-** Sets the encryption key for the database, if necessary.
-*/
-void db_maybe_set_encryption_key(sqlite3 *db, const char *zDbName){
- Blob key;
- blob_init(&key, 0, 0);
- db_maybe_obtain_encryption_key(zDbName, &key);
- if( blob_size(&key)>0 ){
- if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
- char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
- sqlite3_exec(db, zCmd, 0, 0, 0);
- fossil_secure_zero(zCmd, strlen(zCmd));
- sqlite3_free(zCmd);
-#if USE_SEE
- }else{
- sqlite3_key(db, blob_str(&key), -1);
-#endif
- }
- }
- blob_reset(&key);
-}
-
/*
** Open a database file. Return a pointer to the new database
** connection. An error results in process abort.
*/
LOCAL sqlite3 *db_open(const char *zDbName){
int rc;
sqlite3 *db;
+ Blob key;
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
rc = sqlite3_open_v2(
zDbName, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
@@ -1082,11 +1058,19 @@
g.zVfsName
);
if( rc!=SQLITE_OK ){
db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
}
- db_maybe_set_encryption_key(db, zDbName);
+ blob_init(&key, 0, 0);
+ db_maybe_obtain_encryption_key(zDbName, &key);
+ if( blob_size(&key)>0 ){
+ char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
+ sqlite3_exec(db, zCmd, 0, 0, 0);
+ fossil_secure_zero(zCmd, strlen(zCmd));
+ sqlite3_free(zCmd);
+ }
+ blob_reset(&key);
sqlite3_busy_timeout(db, 5000);
sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0);
sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
@@ -1116,30 +1100,19 @@
/*
** zDbName is the name of a database file. Attach zDbName using
** the name zLabel.
*/
void db_attach(const char *zDbName, const char *zLabel){
+ char *zCmd;
Blob key;
blob_init(&key, 0, 0);
db_maybe_obtain_encryption_key(zDbName, &key);
- if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
- char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
- zDbName, zLabel, blob_str(&key));
- db_multi_exec(zCmd /*works-like:""*/);
- fossil_secure_zero(zCmd, strlen(zCmd));
- sqlite3_free(zCmd);
- }else{
- char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY ''",
- zDbName, zLabel);
- db_multi_exec(zCmd /*works-like:""*/);
- sqlite3_free(zCmd);
-#if USE_SEE
- if( blob_size(&key)>0 ){
- sqlite3_key_v2(g.db, zLabel, blob_str(&key), -1);
- }
-#endif
- }
+ zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
+ zDbName, zLabel, blob_str(&key));
+ db_multi_exec(zCmd /*works-like:""*/);
+ fossil_secure_zero(zCmd, strlen(zCmd));
+ sqlite3_free(zCmd);
blob_reset(&key);
}
/*
** Change the schema name of the "main" database to zLabel.
@@ -1643,11 +1616,11 @@
/*
** Open the local database. If unable, exit with an error.
*/
void db_must_be_within_tree(void){
if( find_repository_option() ){
- fossil_fatal("the \"%s\" command only works from within an open check-out",
+ fossil_fatal("the \"%s\" command only work from within an open check-out",
g.argv[1]);
}
if( db_open_local(0)==0 ){
fossil_fatal("current directory is not within an open checkout");
}
Index: src/dispatch.c
==================================================================
--- src/dispatch.c
+++ src/dispatch.c
@@ -243,22 +243,22 @@
style_submenu_element("Command-List", "%s/help", g.zTop);
if( *zCmd=='/' ){
/* Some of the webpages require query parameters in order to work.
** @ */
- @ The "%h(zCmd)" page:
+ @ The "%s(zCmd)" page:
}else{
- @ The "%h(zCmd)" command:
+ @ The "%s(zCmd)" command:
}
rc = dispatch_name_search(zCmd, CMDFLAG_ANY, &pCmd);
if( rc==1 ){
- @ unknown command: %h(zCmd)
+ @ unknown command: %s(zCmd)
}else if( rc==2 ){
- @ ambiguous command prefix: %h(zCmd)
+ @ ambiguous command prefix: %s(zCmd)
}else{
if( pCmd->zHelp[0]==0 ){
- @ no help available for the %h(pCmd->zName) command
+ @ no help available for the %s(pCmd->zName) command
}else{
@
help_to_html(pCmd->zHelp, cgi_output_blob());
@
}
Index: src/doc.c
==================================================================
--- src/doc.c
+++ src/doc.c
@@ -84,11 +84,10 @@
{ "au", 2, "audio/ulaw" },
{ "avi", 3, "video/x-msvideo" },
{ "bat", 3, "application/x-msdos-program" },
{ "bcpio", 5, "application/x-bcpio" },
{ "bin", 3, "application/octet-stream" },
- { "bmp", 3, "image/bmp" },
{ "bz2", 3, "application/x-bzip2" },
{ "bzip", 4, "application/x-bzip" },
{ "c", 1, "text/plain" },
{ "cc", 2, "text/plain" },
{ "ccad", 4, "application/clariscad" },
@@ -102,11 +101,10 @@
{ "csh", 3, "application/x-csh" },
{ "css", 3, "text/css" },
{ "csv", 3, "text/csv" },
{ "dcr", 3, "application/x-director" },
{ "deb", 3, "application/x-debian-package" },
- { "dib", 3, "image/bmp" },
{ "dir", 3, "application/x-director" },
{ "dl", 2, "video/dl" },
{ "dms", 3, "application/octet-stream" },
{ "doc", 3, "application/msword" },
{ "docx", 4, "application/vnd.openxmlformats-"
@@ -136,11 +134,10 @@
{ "hh", 2, "text/plain" },
{ "hqx", 3, "application/mac-binhex40" },
{ "htm", 3, "text/html" },
{ "html", 4, "text/html" },
{ "ice", 3, "x-conference/x-cooltalk" },
- { "ico", 3, "image/vnd.microsoft.icon" },
{ "ief", 3, "image/ief" },
{ "iges", 4, "model/iges" },
{ "igs", 3, "model/iges" },
{ "ips", 3, "application/x-ipscript" },
{ "ipx", 3, "application/x-ipix" },
@@ -721,12 +718,10 @@
blob_reset(&tail);
}else{
style_header("%h", zName);
Th_Render(blob_str(&filebody));
}
- }else{
- Th_Render(blob_str(&filebody));
}
if( !raw ){
style_footer();
}
#endif
Index: src/file.c
==================================================================
--- src/file.c
+++ src/file.c
@@ -799,11 +799,10 @@
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
*/
int file_simplify_name(char *z, int n, int slash){
int i = 1, j;
- assert( z!=0 );
if( n<0 ) n = strlen(z);
/* On windows and cygwin convert all \ characters to /
* and remove extended path prefix if present */
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -1389,12 +1388,11 @@
0, /* TEMP */
0, /* TMP */
".",
};
#else
- static const char *azDirs[] = {
- 0, /* TMPDIR */
+ static const char *const azDirs[] = {
"/var/tmp",
"/usr/tmp",
"/tmp",
"/temp",
".",
@@ -1416,13 +1414,12 @@
azDirs[0] = fossil_path_to_utf8(zTmpPath);
}
azDirs[1] = fossil_getenv("TEMP");
azDirs[2] = fossil_getenv("TMP");
-#else
- azDirs[0] = fossil_getenv("TMPDIR");
#endif
+
for(i=0; i=0 );
#if defined(_WIN32)
fossil_path_free((char *)azDirs[0]);
fossil_path_free((char *)azDirs[1]);
fossil_path_free((char *)azDirs[2]);
-#else
- fossil_path_free((char *)azDirs[0]);
#endif
}
/*
Index: src/http.c
==================================================================
--- src/http.c
+++ src/http.c
@@ -176,11 +176,11 @@
}else{
prompt_user("Basic Authorization user: ", &x);
zUser = mprintf("%b", &x);
zPrompt = mprintf("HTTP password for %b: ", &x);
blob_reset(&x);
- prompt_for_password(zPrompt, &x, 0);
+ prompt_for_password(zPrompt, &x, 1);
zPw = mprintf("%b", &x);
zHttpAuth = mprintf("%s:%s", zUser, zPw);
free(zUser);
free(zPw);
free(zPrompt);
Index: src/info.c
==================================================================
--- src/info.c
+++ src/info.c
@@ -130,11 +130,11 @@
*/
static void extraRepoInfo(void){
Stmt s;
db_prepare(&s, "SELECT substr(name,7), date(mtime,'unixepoch')"
" FROM config"
- " WHERE name GLOB 'ckout:*' ORDER BY mtime DESC");
+ " WHERE name GLOB 'ckout:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
const char *zName;
const char *zCkout = db_column_text(&s, 0);
if( g.localOpen ){
if( fossil_strcmp(zCkout, g.zLocalRoot)==0 ) continue;
@@ -146,11 +146,11 @@
db_column_text(&s, 1));
}
db_finalize(&s);
db_prepare(&s, "SELECT substr(name,9), date(mtime,'unixepoch')"
" FROM config"
- " WHERE name GLOB 'baseurl:*' ORDER BY mtime DESC");
+ " WHERE name GLOB 'baseurl:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
fossil_print("access-url: %-54s %s\n", db_column_text(&s, 0),
db_column_text(&s, 1));
}
db_finalize(&s);
@@ -2946,11 +2946,11 @@
pzNewTags = find_repeatable_option("tag",0,&nTags);
pzCancelTags = find_repeatable_option("cancel",0,&nCancels);
fClose = find_option("close",0,0)!=0;
fHide = find_option("hide",0,0)!=0;
zChngTime = find_option("chngtime",0,1);
- db_find_and_open_repository(0,0);
+ db_must_be_within_tree();
user_select();
verify_all_options();
if( g.argc<3 || g.argc>=4 ) usage(AMEND_USAGE_STMT);
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 && !is_a_version(rid) ) fossil_fatal("no such check-in");
Index: src/login.c
==================================================================
--- src/login.c
+++ src/login.c
@@ -1458,11 +1458,11 @@
if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){
/* Here lies the reason I don't use zErrMsg - it would not substitute
* this %s(zUsername), or at least I don't know how to force it to.*/
@
- @ %h(zUsername) already exists.
+ @ %s(zUsername) already exists.
@
}else{
char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
int uid;
db_multi_exec(
Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -1061,11 +1061,11 @@
Blob versionInfo;
int verboseFlag;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
- verboseFlag = PD("verbose", 0) != 0;
+ verboseFlag = atoi(PD("verbose","0"));
style_header("Version Information");
style_submenu_element("Stat", "stat");
get_version_blob(&versionInfo, verboseFlag);
@
@ %h(blob_str(&versionInfo))
Index: src/main.mk
==================================================================
--- src/main.mk
+++ src/main.mk
@@ -569,11 +569,11 @@
SQLITE3_SHELL_SRC.0 = shell.c
SQLITE3_SHELL_SRC.1 = shell-see.c
SQLITE3_SHELL_SRC. = shell.c
SQLITE3_SHELL_SRC = $(SRCDIR)/$(SQLITE3_SHELL_SRC.$(USE_SEE))
SEE_FLAGS.0 =
-SEE_FLAGS.1 = -DSQLITE_HAS_CODEC -DSQLITE_SHELL_DBKEY_PROC=fossil_key
+SEE_FLAGS.1 = -DSQLITE_HAS_CODEC
SEE_FLAGS. =
SEE_FLAGS = $(SEE_FLAGS.$(USE_SEE))
EXTRAOBJ = \
@@ -1742,11 +1742,11 @@
$(OBJDIR)/sqlite3.o: $(SQLITE3_SRC)
$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) \
-c $(SQLITE3_SRC) -o $@
$(OBJDIR)/shell.o: $(SQLITE3_SHELL_SRC) $(SRCDIR)/sqlite3.h
- $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) $(LINENOISE_DEF.$(USE_LINENOISE)) -c $(SQLITE3_SHELL_SRC) -o $@
+ $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(LINENOISE_DEF.$(USE_LINENOISE)) -c $(SQLITE3_SHELL_SRC) -o $@
$(OBJDIR)/linenoise.o: $(SRCDIR)/linenoise.c $(SRCDIR)/linenoise.h
$(XTCC) -c $(SRCDIR)/linenoise.c -o $@
$(OBJDIR)/th.o: $(SRCDIR)/th.c
Index: src/makemake.tcl
==================================================================
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -387,11 +387,11 @@
SQLITE3_SHELL_SRC.0 = shell.c
SQLITE3_SHELL_SRC.1 = shell-see.c
SQLITE3_SHELL_SRC. = shell.c
SQLITE3_SHELL_SRC = $(SRCDIR)/$(SQLITE3_SHELL_SRC.$(USE_SEE))
SEE_FLAGS.0 =
-SEE_FLAGS.1 = -DSQLITE_HAS_CODEC -DSQLITE_SHELL_DBKEY_PROC=fossil_key
+SEE_FLAGS.1 = -DSQLITE_HAS_CODEC
SEE_FLAGS. =
SEE_FLAGS = $(SEE_FLAGS.$(USE_SEE))
}]
writeln [string map [list <<>> \\] {
@@ -458,11 +458,11 @@
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SQLITE3_SRC)"
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) \$(SEE_FLAGS) \\"
writeln "\t\t-c \$(SQLITE3_SRC) -o \$@"
writeln "\$(OBJDIR)/shell.o:\t\$(SQLITE3_SHELL_SRC) \$(SRCDIR)/sqlite3.h"
-writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) \$(SEE_FLAGS) \$(LINENOISE_DEF.\$(USE_LINENOISE)) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
+writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) \$(LINENOISE_DEF.\$(USE_LINENOISE)) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
writeln "\$(OBJDIR)/linenoise.o:\t\$(SRCDIR)/linenoise.c \$(SRCDIR)/linenoise.h"
writeln "\t\$(XTCC) -c \$(SRCDIR)/linenoise.c -o \$@\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
@@ -1072,11 +1072,11 @@
SQLITE3_SHELL_SRC.0 = shell.c
SQLITE3_SHELL_SRC.1 = shell-see.c
SQLITE3_SHELL_SRC. = shell.c
SQLITE3_SHELL_SRC = $(SRCDIR)/$(SQLITE3_SHELL_SRC.$(USE_SEE))
SEE_FLAGS.0 =
-SEE_FLAGS.1 = -DSQLITE_HAS_CODEC -DSQLITE_SHELL_DBKEY_PROC=fossil_key
+SEE_FLAGS.1 = -DSQLITE_HAS_CODEC
SEE_FLAGS. =
SEE_FLAGS = $(SEE_FLAGS.$(USE_SEE))
}
writeln [string map [list <<>> \\] {
@@ -1213,11 +1213,11 @@
writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/cson_amalgamation.c -o \$@\n"
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/jsos_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h\n"
writeln "\$(OBJDIR)/shell.o:\t\$(SQLITE3_SHELL_SRC) \$(SRCDIR)/sqlite3.h \$(SRCDIR)/../win/Makefile.mingw"
-writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) \$(SEE_FLAGS) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
+writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
@@ -1850,21 +1850,23 @@
codecheck1$E: $(SRCDIR)\codecheck1.c
$(BCC) $**
!if $(USE_SEE)!=0
-SEE_FLAGS = /DSQLITE_HAS_CODEC=1 /DSQLITE_SHELL_DBKEY_PROC=fossil_key
SQLITE3_SHELL_SRC = $(SRCDIR)\shell-see.c
-SQLITE3_SRC = $(SRCDIR)\sqlite3-see.c
!else
-SEE_FLAGS =
SQLITE3_SHELL_SRC = $(SRCDIR)\shell.c
-SQLITE3_SRC = $(SRCDIR)\sqlite3.c
!endif
$(OX)\shell$O : $(SQLITE3_SHELL_SRC) $B\win\Makefile.msc
- $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) -c $(SQLITE3_SHELL_SRC)
+ $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SQLITE3_SHELL_SRC)
+
+!if $(USE_SEE)!=0
+SQLITE3_SRC = $(SRCDIR)\sqlite3-see.c
+!else
+SQLITE3_SRC = $(SRCDIR)\sqlite3.c
+!endif
$(OX)\sqlite3$O : $(SQLITE3_SRC) $B\win\Makefile.msc
$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) $(SQLITE3_SRC)
$(OX)\th$O : $(SRCDIR)\th.c
Index: src/merge3.c
==================================================================
--- src/merge3.c
+++ src/merge3.c
@@ -368,11 +368,10 @@
** fossil commit
**
*/
void delta_3waymerge_cmd(void){
Blob pivot, v1, v2, merged;
- int nConflict;
/* We should be done with options.. */
verify_all_options();
if( g.argc!=6 ){
@@ -385,19 +384,18 @@
fossil_fatal("cannot read %s", g.argv[3]);
}
if( blob_read_from_file(&v2, g.argv[4])<0 ){
fossil_fatal("cannot read %s", g.argv[4]);
}
- nConflict = blob_merge(&pivot, &v1, &v2, &merged);
+ blob_merge(&pivot, &v1, &v2, &merged);
if( blob_write_to_file(&merged, g.argv[5])0 ) fossil_warning("WARNING: %d merge conflicts", nConflict);
}
/*
** aSubst is an array of string pairs. The first element of each pair is
** a string that begins with %. The second element is a replacement for that
Index: src/name.c
==================================================================
--- src/name.c
+++ src/name.c
@@ -467,11 +467,11 @@
@
@ %s(zUuid) -
@
@ Ticket
hyperlink_to_uuid(zUuid);
- @ - %h(zTitle).
+ @ - %s(zTitle).
@ -
object_description(rid, 0, 0);
@
@
}
Index: src/search.c
==================================================================
--- src/search.c
+++ src/search.c
@@ -597,11 +597,11 @@
}else{
width = -1;
}
db_find_and_open_repository(0, 0);
- if( g.argc<3 ) return;
+ if( g.argc<2 ) return;
blob_init(&pattern, g.argv[2], -1);
for(i=3; i%h(zErr)
+ @ %s(zErr)
@
@ [Bummer]
style_footer();
return;
}
Index: src/sha1.c
==================================================================
--- src/sha1.c
+++ src/sha1.c
@@ -17,10 +17,11 @@
**
** This implementation of SHA1.
*/
#include "config.h"
#include
+#include
#include "sha1.h"
/*
** SHA1 Implementation #1 is the hardened SHA1 implementation by
Index: src/sha3.c
==================================================================
--- src/sha3.c
+++ src/sha3.c
@@ -600,11 +600,10 @@
blob_resize(pCksum, iSize/4);
DigestToBase16(SHA3Final(&ctx), blob_buffer(pCksum), iSize/8);
return 0;
}
-#if 0 /* NOT USED */
/*
** Compute the SHA3 checksum of a zero-terminated string. The
** result is held in memory obtained from mprintf().
*/
char *sha3sum(const char *zIn, int iSize){
@@ -611,14 +610,13 @@
SHA3Context ctx;
char zDigest[132];
SHA3Init(&ctx, iSize);
SHA3Update(&ctx, (unsigned const char*)zIn, strlen(zIn));
- DigestToBase16(SHA3Final(&ctx), zDigest, iSize/8);
+ DigestToBase16(SHA3Final(&ctx), zDigest, iSize/4);
return mprintf("%s", zDigest);
}
-#endif
/*
** COMMAND: sha3sum*
**
** Usage: %fossil sha3sum FILE...
Index: src/shell.c
==================================================================
--- src/shell.c
+++ src/shell.c
@@ -425,40 +425,10 @@
utf8_printf(iotrace, "%s", z);
sqlite3_free(z);
}
#endif
-/*
-** Output string zUtf to stream pOut as w characters. If w is negative,
-** then right-justify the text. W is the width in UTF-8 characters, not
-** in bytes. This is different from the %*.*s specification in printf
-** since with %*.*s the width is measured in bytes, not characters.
-*/
-static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
- int i;
- int n;
- int aw = w<0 ? -w : w;
- char zBuf[1000];
- if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
- for(i=n=0; zUtf[i]; i++){
- if( (zUtf[i]&0xc0)!=0x80 ){
- n++;
- if( n==aw ){
- do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
- break;
- }
- }
- }
- if( n>=aw ){
- utf8_printf(pOut, "%.*s", i, zUtf);
- }else if( w<0 ){
- utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
- }else{
- utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
- }
-}
-
/*
** Determines if a string is a number of not.
*/
static int isNumber(const char *z, int *realnum){
@@ -742,14 +712,10 @@
unsigned nRate; /* Bytes of input accepted per Keccak iteration */
unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
};
-/* Allow the following routine to use the B0 variable, which is also
-** a macro in the termios.h header file */
-#undef B0
-
/*
** A single step of the Keccak mixing function for a 1600-bit state
*/
static void KeccakF1600Step(SHA3Context *p){
int i;
@@ -1521,128 +1487,57 @@
for(i=0; iactualWidth) ){
p->actualWidth[i] = w;
}
if( showHdr ){
- utf8_width_print(p->out, w, azCol[i]);
- utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
+ if( w<0 ){
+ utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
+ i==nArg-1 ? rowSep : " ");
+ }else{
+ utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
+ i==nArg-1 ? rowSep : " ");
+ }
}
}
if( showHdr ){
for(i=0; iiIndentnIndent ){
utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
}
p->iIndent++;
}
- utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
- utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
+ if( w<0 ){
+ utf8_printf(p->out,"%*.*s%s",-w,-w,
+ azArg[i] ? azArg[i] : p->nullValue,
+ i==nArg-1 ? rowSep : " ");
+ }else{
+ utf8_printf(p->out,"%-*.*s%s",w,w,
+ azArg[i] ? azArg[i] : p->nullValue,
+ i==nArg-1 ? rowSep : " ");
+ }
}
break;
}
case MODE_Semi: { /* .schema and .fullschema output */
printSchemaLine(p->out, azArg[0], ";\n");
@@ -2089,88 +1996,59 @@
utf8_printf(p->out, "%s", p->rowSeparator);
}
setTextMode(p->out, 1);
break;
}
+ case MODE_Quote:
case MODE_Insert: {
if( azArg==0 ) break;
- utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
- if( p->showHeader ){
- raw_printf(p->out,"(");
- for(i=0; i0 ) raw_printf(p->out, ",");
- if( quoteChar(azCol[i]) ){
- char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
- utf8_printf(p->out, "%s", z);
- sqlite3_free(z);
- }else{
- raw_printf(p->out, "%s", azCol[i]);
- }
- }
- raw_printf(p->out,")");
- }
- p->cnt++;
- for(i=0; iout, i>0 ? "," : " VALUES(");
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
- utf8_printf(p->out,"NULL");
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
- output_quoted_escaped_string(p->out, azArg[i]);
- }else if( aiType && aiType[i]==SQLITE_INTEGER ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
- char z[50];
- double r = sqlite3_column_double(p->pStmt, i);
- sqlite3_snprintf(50,z,"%!.20g", r);
- raw_printf(p->out, "%s", z);
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
- output_hex_blob(p->out, pBlob, nBlob);
- }else if( isNumber(azArg[i], 0) ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else{
- output_quoted_escaped_string(p->out, azArg[i]);
- }
- }
- raw_printf(p->out,");\n");
- break;
- }
- case MODE_Quote: {
- if( azArg==0 ) break;
- if( p->cnt==0 && p->showHeader ){
+ if( p->cMode==MODE_Insert ){
+ utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
+ if( p->showHeader ){
+ raw_printf(p->out,"(");
+ for(i=0; i0 ? ",": "";
+ utf8_printf(p->out, "%s%s", zSep, azCol[i]);
+ }
+ raw_printf(p->out,")");
+ }
+ raw_printf(p->out," VALUES(");
+ }else if( p->cnt==0 && p->showHeader ){
for(i=0; i0 ) raw_printf(p->out, ",");
output_quoted_string(p->out, azCol[i]);
}
raw_printf(p->out,"\n");
}
p->cnt++;
for(i=0; i0 ) raw_printf(p->out, ",");
+ char *zSep = i>0 ? ",": "";
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
- utf8_printf(p->out,"NULL");
+ utf8_printf(p->out,"%sNULL",zSep);
}else if( aiType && aiType[i]==SQLITE_TEXT ){
+ if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
output_quoted_string(p->out, azArg[i]);
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
- utf8_printf(p->out,"%s", azArg[i]);
+ utf8_printf(p->out,"%s%s",zSep, azArg[i]);
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
char z[50];
double r = sqlite3_column_double(p->pStmt, i);
sqlite3_snprintf(50,z,"%!.20g", r);
- raw_printf(p->out, "%s", z);
+ raw_printf(p->out, "%s%s", zSep, z);
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
+ if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
- utf8_printf(p->out,"%s", azArg[i]);
+ utf8_printf(p->out,"%s%s",zSep, azArg[i]);
}else{
+ if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
output_quoted_string(p->out, azArg[i]);
}
}
- raw_printf(p->out,"\n");
+ raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
break;
}
case MODE_Ascii: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
bVerbose = 1;
@@ -4523,14 +4400,11 @@
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc!=SQLITE_OK ) break;
if( SQLITE_ROW==sqlite3_step(pExplain) ){
const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
- res = (
- 0==sqlite3_strglob(zGlob, zPlan)
- || 0==sqlite3_strglob(zGlobIPK, zPlan)
- );
+ res = (0==sqlite3_strglob(zGlob, zPlan));
}
rc = sqlite3_finalize(pExplain);
if( rc!=SQLITE_OK ) break;
if( res<0 ){
@@ -4804,11 +4678,10 @@
}else
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
const char *zLike = 0;
int i;
- int savedShowHeader = p->showHeader;
ShellClearFlag(p, SHFLG_PreserveRowid);
for(i=1; iout, "PRAGMA foreign_keys=OFF;\n");
raw_printf(p->out, "BEGIN TRANSACTION;\n");
p->writableSchema = 0;
- p->showHeader = 0;
/* Set writable_schema=ON since doing so forces SQLite to initialize
** as much of the schema as it can even if the sqlite_master table is
** corrupt. */
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
p->nErr = 0;
@@ -4882,11 +4754,10 @@
p->writableSchema = 0;
}
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
- p->showHeader = savedShowHeader;
}else
if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
if( nArg==2 ){
setOrClearFlag(p, SHFLG_Echo, azArg[1]);
Index: src/skins.c
==================================================================
--- src/skins.c
+++ src/skins.c
@@ -158,20 +158,10 @@
}
}
return zOut;
}
-/*
-** Return the command-line option used to set the skin, or return NULL
-** if the default skin is being used.
-*/
-const char *skin_in_use(void){
- if( zAltSkinDir ) return zAltSkinDir;
- if( pAltSkin ) return pAltSkin->zLabel;
- return 0;
-}
-
/*
** Return a pointer to a SkinDetail element. Return 0 if not found.
*/
static struct SkinDetail *skin_detail_find(const char *zName){
int lwr = 0;
Index: src/sqlcmd.c
==================================================================
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -20,11 +20,10 @@
** is a copy of the "shell.c" code from SQLite. This file contains logic
** to initialize the code in shell.c.
*/
#include "config.h"
#include "sqlcmd.h"
-#include /* atexit() */
#if defined(FOSSIL_ENABLE_MINIZ)
# define MINIZ_HEADER_FILE_ONLY
# include "miniz.c"
#else
# include
@@ -151,83 +150,23 @@
search_sql_setup(db);
foci_register(db);
g.repositoryOpen = 1;
g.db = db;
sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository");
- db_maybe_set_encryption_key(db, g.zRepositoryName);
if( g.zLocalDbName ){
- char *zSql = sqlite3_mprintf("ATTACH %Q AS 'localdb' KEY ''",
- g.zLocalDbName);
+ char *zSql = sqlite3_mprintf("ATTACH %Q AS 'localdb'", g.zLocalDbName);
sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
if( g.zConfigDbName ){
- char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''",
- g.zConfigDbName);
+ char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb'", g.zConfigDbName);
sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
return SQLITE_OK;
}
-/*
-** atexit() handler that cleans up global state modified by this module.
-*/
-static void sqlcmd_atexit(void) {
- g.zConfigDbName = 0; /* prevent panic */
-}
-
-/*
-** This routine is called by the patched sqlite3 command-line shell in order
-** to load the name and database connection for the open Fossil database.
-*/
-void fossil_open(const char **pzRepoName){
- sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit);
- *pzRepoName = g.zRepositoryName;
-}
-
-#if USE_SEE
-/*
-** This routine is called by the patched sqlite3 command-line shell in order
-** to load the encryption key for the open Fossil database. The memory that
-** is pointed to by the value placed in pzKey must be obtained from SQLite.
-*/
-void fossil_key(const char **pzKey, int *pnKey){
- char *zSavedKey = db_get_saved_encryption_key();
- char *zKey;
- size_t savedKeySize = db_get_saved_encryption_key_size();
- size_t nByte;
-
- if( zSavedKey==0 || savedKeySize==0 ) return;
- nByte = savedKeySize * sizeof(char);
- zKey = sqlite3_malloc( (int)nByte );
- if( zKey ){
- memcpy(zKey, zSavedKey, nByte);
- *pzKey = zKey;
- if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
- *pnKey = (int)strlen(zKey);
- }else{
- *pnKey = -1;
- }
- }else{
- fossil_fatal("failed to allocate %u bytes for key", nByte);
- }
-}
-#endif
-
-/*
-** This routine closes the Fossil databases and/or invalidates the global
-** state variables that keep track of them.
-*/
-static void fossil_close(int bDb, int noRepository){
- if( bDb ) db_close(1);
- if( noRepository ) g.zRepositoryName = 0;
- g.db = 0;
- g.repositoryOpen = 0;
- g.localOpen = 0;
-}
-
/*
** COMMAND: sqlite3
**
** Usage: %fossil sql ?OPTIONS?
**
@@ -287,11 +226,31 @@
fossil_close(1, noRepository);
sqlite3_shutdown();
#ifndef _WIN32
linenoiseSetMultiLine(1);
#endif
- atexit(sqlcmd_atexit);
g.zConfigDbName = zConfigDb;
sqlite3_shell(g.argc-1, g.argv+1);
sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
fossil_close(0, noRepository);
}
+
+/*
+** This routine is called by the patched sqlite3 command-line shell in order
+** to load the name and database connection for the open Fossil database.
+*/
+void fossil_open(const char **pzRepoName){
+ sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit);
+ *pzRepoName = g.zRepositoryName;
+}
+
+/*
+** This routine closes the Fossil databases and/or invalidates the global
+** state variables that keep track of them.
+*/
+void fossil_close(int bDb, int noRepository){
+ if( bDb ) db_close(1);
+ if( noRepository ) g.zRepositoryName = 0;
+ g.db = 0;
+ g.repositoryOpen = 0;
+ g.localOpen = 0;
+}
Index: src/sqlite3.c
==================================================================
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.19.2. By combining all the individual C code files into this
+** version 3.18.0. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
@@ -396,13 +396,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.19.2"
-#define SQLITE_VERSION_NUMBER 3019002
-#define SQLITE_SOURCE_ID "2017-05-25 16:50:27 edb4e819b0c058c7d74d27ebd14cc5ceb2bad6a6144a486a970182b7afe3f8b9"
+#define SQLITE_VERSION "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -1132,11 +1132,11 @@
** of 25 milliseconds before the first retry and with the delay increasing
** by an additional 25 milliseconds with each subsequent retry. This
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer is the new retry count and the second
+** integers where the first integer i the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
** interrogated. The zDbName parameter is ignored.
**
@@ -2486,10 +2486,13 @@
** that are started after the running statement count reaches zero are
** not effected by the sqlite3_interrupt().
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
+**
+** If the database connection closes while [sqlite3_interrupt()]
+** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2948,11 +2951,10 @@
SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
-** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
@@ -2976,26 +2978,20 @@
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are either NULL pointers or zero-terminated strings
-** that contain additional details about the action to be authorized.
-** Applications must always be prepared to encounter a NULL pointer in any
-** of the third through the sixth parameters of the authorization callback.
+** to the callback are zero-terminated strings that contain additional
+** details about the action to be authorized.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
-** ^When a table is referenced by a [SELECT] but no column values are
-** extracted from that table (for example in a query like
-** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
-** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
**
** An authorizer is used when [sqlite3_prepare | preparing]
@@ -3984,11 +3980,11 @@
** Unprotected sqlite3_value objects may only be used with
** [sqlite3_result_value()] and [sqlite3_bind_value()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct sqlite3_value sqlite3_value;
+typedef struct Mem sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
@@ -5038,15 +5034,14 @@
** metadata associated with the pattern string.
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
-** value to the application-defined function. ^N is zero for the left-most
-** function argument. ^If there is no metadata
-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata() function with the Nth argument
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function. ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
@@ -5073,14 +5068,10 @@
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
-** The value of the N parameter to these interfaces should be non-negative.
-** Future enhancements may make use of negative N values to define new
-** kinds of function caching behavior.
-**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
@@ -9671,11 +9662,11 @@
**
** As well as the regular sqlite3changegroup_add() and
** sqlite3changegroup_output() functions, also available are the streaming
** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
*/
-SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
+int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
@@ -9748,11 +9739,11 @@
** function returns SQLITE_NOMEM. In all cases, if an error occurs the
** final contents of the changegroup is undefined.
**
** If no error occurs, SQLITE_OK is returned.
*/
-SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
@@ -9774,20 +9765,20 @@
** is returned and the output variables are set to the size of and a
** pointer to the output buffer, respectively. In this case it is the
** responsibility of the caller to eventually free the buffer using a
** call to sqlite3_free().
*/
-SQLITE_API int sqlite3changegroup_output(
+int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
);
/*
** CAPI3REF: Delete A Changegroup Object
*/
-SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
**
** Apply a changeset to a database. This function attempts to update the
@@ -10172,15 +10163,15 @@
SQLITE_API int sqlite3session_patchset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
+int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
@@ -11460,80 +11451,80 @@
#define TK_LP 22
#define TK_RP 23
#define TK_AS 24
#define TK_WITHOUT 25
#define TK_COMMA 26
-#define TK_ID 27
-#define TK_ABORT 28
-#define TK_ACTION 29
-#define TK_AFTER 30
-#define TK_ANALYZE 31
-#define TK_ASC 32
-#define TK_ATTACH 33
-#define TK_BEFORE 34
-#define TK_BY 35
-#define TK_CASCADE 36
-#define TK_CAST 37
-#define TK_COLUMNKW 38
-#define TK_CONFLICT 39
-#define TK_DATABASE 40
-#define TK_DESC 41
-#define TK_DETACH 42
-#define TK_EACH 43
-#define TK_FAIL 44
-#define TK_FOR 45
-#define TK_IGNORE 46
-#define TK_INITIALLY 47
-#define TK_INSTEAD 48
-#define TK_LIKE_KW 49
-#define TK_MATCH 50
-#define TK_NO 51
-#define TK_KEY 52
-#define TK_OF 53
-#define TK_OFFSET 54
-#define TK_PRAGMA 55
-#define TK_RAISE 56
-#define TK_RECURSIVE 57
-#define TK_REPLACE 58
-#define TK_RESTRICT 59
-#define TK_ROW 60
-#define TK_TRIGGER 61
-#define TK_VACUUM 62
-#define TK_VIEW 63
-#define TK_VIRTUAL 64
-#define TK_WITH 65
-#define TK_REINDEX 66
-#define TK_RENAME 67
-#define TK_CTIME_KW 68
-#define TK_ANY 69
-#define TK_OR 70
-#define TK_AND 71
-#define TK_IS 72
-#define TK_BETWEEN 73
-#define TK_IN 74
-#define TK_ISNULL 75
-#define TK_NOTNULL 76
-#define TK_NE 77
-#define TK_EQ 78
-#define TK_GT 79
-#define TK_LE 80
-#define TK_LT 81
-#define TK_GE 82
-#define TK_ESCAPE 83
-#define TK_BITAND 84
-#define TK_BITOR 85
-#define TK_LSHIFT 86
-#define TK_RSHIFT 87
-#define TK_PLUS 88
-#define TK_MINUS 89
-#define TK_STAR 90
-#define TK_SLASH 91
-#define TK_REM 92
-#define TK_CONCAT 93
-#define TK_COLLATE 94
-#define TK_BITNOT 95
-#define TK_INDEXED 96
+#define TK_OR 27
+#define TK_AND 28
+#define TK_IS 29
+#define TK_MATCH 30
+#define TK_LIKE_KW 31
+#define TK_BETWEEN 32
+#define TK_IN 33
+#define TK_ISNULL 34
+#define TK_NOTNULL 35
+#define TK_NE 36
+#define TK_EQ 37
+#define TK_GT 38
+#define TK_LE 39
+#define TK_LT 40
+#define TK_GE 41
+#define TK_ESCAPE 42
+#define TK_BITAND 43
+#define TK_BITOR 44
+#define TK_LSHIFT 45
+#define TK_RSHIFT 46
+#define TK_PLUS 47
+#define TK_MINUS 48
+#define TK_STAR 49
+#define TK_SLASH 50
+#define TK_REM 51
+#define TK_CONCAT 52
+#define TK_COLLATE 53
+#define TK_BITNOT 54
+#define TK_ID 55
+#define TK_INDEXED 56
+#define TK_ABORT 57
+#define TK_ACTION 58
+#define TK_AFTER 59
+#define TK_ANALYZE 60
+#define TK_ASC 61
+#define TK_ATTACH 62
+#define TK_BEFORE 63
+#define TK_BY 64
+#define TK_CASCADE 65
+#define TK_CAST 66
+#define TK_COLUMNKW 67
+#define TK_CONFLICT 68
+#define TK_DATABASE 69
+#define TK_DESC 70
+#define TK_DETACH 71
+#define TK_EACH 72
+#define TK_FAIL 73
+#define TK_FOR 74
+#define TK_IGNORE 75
+#define TK_INITIALLY 76
+#define TK_INSTEAD 77
+#define TK_NO 78
+#define TK_KEY 79
+#define TK_OF 80
+#define TK_OFFSET 81
+#define TK_PRAGMA 82
+#define TK_RAISE 83
+#define TK_RECURSIVE 84
+#define TK_REPLACE 85
+#define TK_RESTRICT 86
+#define TK_ROW 87
+#define TK_TRIGGER 88
+#define TK_VACUUM 89
+#define TK_VIEW 90
+#define TK_VIRTUAL 91
+#define TK_WITH 92
+#define TK_REINDEX 93
+#define TK_RENAME 94
+#define TK_CTIME_KW 95
+#define TK_ANY 96
#define TK_STRING 97
#define TK_JOIN_KW 98
#define TK_CONSTRAINT 99
#define TK_DEFAULT 100
#define TK_NULL 101
@@ -11593,15 +11584,14 @@
#define TK_UMINUS 155
#define TK_UPLUS 156
#define TK_REGISTER 157
#define TK_VECTOR 158
#define TK_SELECT_COLUMN 159
-#define TK_IF_NULL_ROW 160
-#define TK_ASTERISK 161
-#define TK_SPAN 162
-#define TK_SPACE 163
-#define TK_ILLEGAL 164
+#define TK_ASTERISK 160
+#define TK_SPAN 161
+#define TK_SPACE 162
+#define TK_ILLEGAL 163
/* The token codes above must all fit in 8 bits */
#define TKFLG_MASK 0xff
/* Flags that can be added to a token code when it is not
@@ -12468,11 +12458,11 @@
*/
struct BtreePayload {
const void *pKey; /* Key content for indexes. NULL for tables */
sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
const void *pData; /* Data for tables. NULL for indexes */
- sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
+ struct Mem *aMem; /* First of nMem value in the unpacked pKey */
u16 nMem; /* Number of aMem[] value. Might be zero */
int nData; /* Size of pData. 0 if none. */
int nZero; /* Extra zero data appended after pData,nData */
};
@@ -12598,11 +12588,11 @@
/*
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
-typedef struct sqlite3_value Mem;
+typedef struct Mem Mem;
typedef struct SubProgram SubProgram;
/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands. The instruction is recorded
@@ -12758,153 +12748,151 @@
#define OP_Jump 18
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
#define OP_Once 20
#define OP_If 21
#define OP_IfNot 22
-#define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
-#define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */
-#define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */
-#define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */
-#define OP_NotFound 29 /* synopsis: key=r[P3@P4] */
-#define OP_Found 30 /* synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */
-#define OP_NotExists 32 /* synopsis: intkey=r[P3] */
-#define OP_Last 33
-#define OP_IfSmaller 34
-#define OP_SorterSort 35
-#define OP_Sort 36
-#define OP_Rewind 37
-#define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */
-#define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 44
-#define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
-#define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */
-#define OP_IncrVacuum 49
-#define OP_VNext 50
-#define OP_Init 51 /* synopsis: Start at P2 */
-#define OP_Return 52
-#define OP_EndCoroutine 53
-#define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 55
-#define OP_Integer 56 /* synopsis: r[P2]=P1 */
-#define OP_Int64 57 /* synopsis: r[P2]=P4 */
-#define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 59 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 60 /* synopsis: r[P1]=NULL */
-#define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 68
-#define OP_Function0 69 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_Function 72 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_AddImm 73 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_RealAffinity 74
-#define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]=r[P1] */
-#define OP_ElseNotEq 83 /* same as TK_ESCAPE */
-#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
-#define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_SeekLT 23 /* synopsis: key=r[P3@P4] */
+#define OP_SeekLE 24 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGE 25 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGT 26 /* synopsis: key=r[P3@P4] */
+#define OP_Or 27 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 28 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_NoConflict 29 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 30 /* synopsis: key=r[P3@P4] */
+#define OP_Found 31 /* synopsis: key=r[P3@P4] */
+#define OP_SeekRowid 32 /* synopsis: intkey=r[P3] */
+#define OP_NotExists 33 /* synopsis: intkey=r[P3] */
+#define OP_IsNull 34 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 35 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 36 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 37 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 38 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 39 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 40 /* same as TK_LT, synopsis: IF r[P3]=r[P1] */
+#define OP_ElseNotEq 42 /* same as TK_ESCAPE */
+#define OP_BitAnd 43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_Last 53
+#define OP_BitNot 54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_IfSmaller 55
+#define OP_SorterSort 56
+#define OP_Sort 57
+#define OP_Rewind 58
+#define OP_IdxLE 59 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGT 60 /* synopsis: key=r[P3@P4] */
+#define OP_IdxLT 61 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 62 /* synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 63 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 64 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 65
+#define OP_FkIfZero 66 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 67 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 68 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_DecrJumpZero 69 /* synopsis: if (--r[P1])==0 goto P2 */
+#define OP_IncrVacuum 70
+#define OP_VNext 71
+#define OP_Init 72 /* synopsis: Start at P2 */
+#define OP_Return 73
+#define OP_EndCoroutine 74
+#define OP_HaltIfNull 75 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 76
+#define OP_Integer 77 /* synopsis: r[P2]=P1 */
+#define OP_Int64 78 /* synopsis: r[P2]=P4 */
+#define OP_String 79 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 80 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 81 /* synopsis: r[P1]=NULL */
+#define OP_Blob 82 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 83 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 84 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 85 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 86 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 87 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 88 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 89
+#define OP_Function0 90 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Function 91 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_AddImm 92 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 93
#define OP_Cast 94 /* synopsis: affinity(r[P1]) */
-#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_Permutation 96
+#define OP_Permutation 95
+#define OP_Compare 96 /* synopsis: r[P1@P3] <-> r[P2@P3] */
#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_Compare 98 /* synopsis: r[P1@P3] <-> r[P2@P3] */
-#define OP_Column 99 /* synopsis: r[P3]=PX */
-#define OP_Affinity 100 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 102 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 103
-#define OP_SetCookie 104
-#define OP_ReopenIdx 105 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 106 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 107 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenDup 108
-#define OP_OpenAutoindex 109 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 110 /* synopsis: nColumn=P2 */
-#define OP_SorterOpen 111
-#define OP_SequenceTest 112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_OpenPseudo 113 /* synopsis: P3 columns in r[P2] */
-#define OP_Close 114
-#define OP_ColumnsUsed 115
-#define OP_Sequence 116 /* synopsis: r[P2]=cursor[P1].ctr++ */
-#define OP_NewRowid 117 /* synopsis: r[P2]=rowid */
-#define OP_Insert 118 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_InsertInt 119 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 120
-#define OP_ResetCount 121
-#define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 123 /* synopsis: r[P2]=data */
-#define OP_RowData 124 /* synopsis: r[P2]=data */
-#define OP_Rowid 125 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 126
-#define OP_SorterInsert 127 /* synopsis: key=r[P2] */
-#define OP_IdxInsert 128 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 129 /* synopsis: key=r[P2@P3] */
-#define OP_Seek 130 /* synopsis: Move P3 to P1.rowid */
-#define OP_IdxRowid 131 /* synopsis: r[P2]=rowid */
+#define OP_Column 98 /* synopsis: r[P3]=PX */
+#define OP_Affinity 99 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 100 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 101 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 102
+#define OP_SetCookie 103
+#define OP_ReopenIdx 104 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 105 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 106 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 109
+#define OP_SequenceTest 110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 111 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 112
+#define OP_ColumnsUsed 113
+#define OP_Sequence 114 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 115 /* synopsis: r[P2]=rowid */
+#define OP_Insert 116 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 117 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 118
+#define OP_ResetCount 119
+#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 121 /* synopsis: r[P2]=data */
+#define OP_RowData 122 /* synopsis: r[P2]=data */
+#define OP_Rowid 123 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 124
+#define OP_SorterInsert 125 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 126 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */
+#define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */
+#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
+#define OP_Destroy 130
+#define OP_Clear 131
#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_Destroy 133
-#define OP_Clear 134
-#define OP_ResetSorter 135
-#define OP_CreateIndex 136 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_CreateTable 137 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_SqlExec 138
-#define OP_ParseSchema 139
-#define OP_LoadAnalysis 140
-#define OP_DropTable 141
-#define OP_DropIndex 142
-#define OP_DropTrigger 143
-#define OP_IntegrityCk 144
-#define OP_RowSetAdd 145 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Param 146
-#define OP_FkCounter 147 /* synopsis: fkctr[P1]+=P2 */
-#define OP_MemMax 148 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_OffsetLimit 149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggStep0 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggStep 151 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggFinal 152 /* synopsis: accum=r[P1] N=P2 */
-#define OP_Expire 153
-#define OP_TableLock 154 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 155
-#define OP_VCreate 156
-#define OP_VDestroy 157
-#define OP_VOpen 158
-#define OP_VColumn 159 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 160
-#define OP_Pagecount 161
-#define OP_MaxPgcnt 162
-#define OP_CursorHint 163
-#define OP_Noop 164
-#define OP_Explain 165
+#define OP_ResetSorter 133
+#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_SqlExec 136
+#define OP_ParseSchema 137
+#define OP_LoadAnalysis 138
+#define OP_DropTable 139
+#define OP_DropIndex 140
+#define OP_DropTrigger 141
+#define OP_IntegrityCk 142
+#define OP_RowSetAdd 143 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 144
+#define OP_FkCounter 145 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 146 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggStep0 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggFinal 150 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 151
+#define OP_TableLock 152 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 153
+#define OP_VCreate 154
+#define OP_VDestroy 155
+#define OP_VOpen 156
+#define OP_VColumn 157 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 158
+#define OP_Pagecount 159
+#define OP_MaxPgcnt 160
+#define OP_CursorHint 161
+#define OP_Noop 162
+#define OP_Explain 163
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
@@ -12915,37 +12903,37 @@
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
/* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
-/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
-/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
-/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
-/* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\
-/* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\
-/* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
-/* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
-/* 72 */ 0x00, 0x02, 0x02, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
-/* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\
-/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x02, 0x12,\
-/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
+/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x09,\
+/* 24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\
+/* 32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
+/* 40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/* 48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\
+/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23,\
+/* 64 */ 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\
+/* 72 */ 0x01, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\
+/* 80 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\
+/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\
+/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04,\
-/* 128 */ 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\
-/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,}
+/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
+/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
+/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\
+/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 160 */ 0x10, 0x00, 0x00, 0x00,}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
** JUMP opcode the better, so the mkopcodeh.tcl script that
** generated this include file strives to group all JUMP opcodes
** together near the beginning of the list.
*/
-#define SQLITE_MX_JUMP_OPCODE 83 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 72 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
@@ -15221,11 +15209,10 @@
** of the result column in the form: DATABASE.TABLE.COLUMN. This later
** form is used for name resolution with nested FROM clauses.
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
- int nAlloc; /* Number of a[] slots allocated */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The parse tree for this expression */
char *zName; /* Token associated with this expression */
char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
@@ -15237,11 +15224,11 @@
u16 iOrderByCol; /* For ORDER BY, column number in result set */
u16 iAlias; /* Index into Parse.aAlias[] for zName */
} x;
int iConstExprReg; /* Register in which Expr value is cached */
} u;
- } a[1]; /* One slot for each expression in the list */
+ } *a; /* Alloc a power of two greater or equal to nExpr */
};
/*
** An instance of this structure is used by the parser to record both
** the parse tree for an expression and the span of input text for an
@@ -16094,21 +16081,18 @@
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
int walkerDepth; /* Number of subqueries */
u8 eCode; /* A small processing code */
union { /* Extra data for callback */
- NameContext *pNC; /* Naming context */
- int n; /* A counter */
- int iCur; /* A cursor number */
- SrcList *pSrcList; /* FROM clause */
- struct SrcCount *pSrcCount; /* Counting column references */
- struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
- int *aiCol; /* array of column indexes */
- struct IdxCover *pIdxCover; /* Check for index coverage */
- struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */
- ExprList *pGroupBy; /* GROUP BY clause */
- struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */
+ NameContext *pNC; /* Naming context */
+ int n; /* A counter */
+ int iCur; /* A cursor number */
+ SrcList *pSrcList; /* FROM clause */
+ struct SrcCount *pSrcCount; /* Counting column references */
+ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
+ int *aiCol; /* array of column indexes */
+ struct IdxCover *pIdxCover; /* Check for index coverage */
} u;
};
/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
@@ -16258,11 +16242,10 @@
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
-SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
SQLITE_PRIVATE int sqlite3MallocSize(void*);
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
SQLITE_PRIVATE void sqlite3ScratchFree(void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
@@ -16574,11 +16557,10 @@
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
@@ -17284,20 +17266,13 @@
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
-**
-** URI filenames are enabled by default if SQLITE_HAS_CODEC is
-** enabled.
*/
#ifndef SQLITE_USE_URI
-# ifdef SQLITE_HAS_CODEC
-# define SQLITE_USE_URI 1
-# else
-# define SQLITE_USE_URI 0
-# endif
+# define SQLITE_USE_URI 0
#endif
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
@@ -18117,11 +18092,11 @@
/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
-struct sqlite3_value {
+struct Mem {
union MemValue {
double r; /* Real value used when MEM_Real is set in flags */
i64 i; /* Integer value used when MEM_Int is set in flags */
int nZero; /* Used when bit MEM_Zero is set in flags */
FuncDef *pDef; /* Used only when flags==MEM_Agg */
@@ -18219,15 +18194,15 @@
** of this structure. All such structures associated with a single VM
** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
** when the VM is halted (if not before).
*/
struct AuxData {
- int iAuxOp; /* Instruction number of OP_Function opcode */
- int iAuxArg; /* Index of function argument. */
+ int iOp; /* Instruction number of OP_Function opcode */
+ int iArg; /* Index of function argument. */
void *pAux; /* Aux data pointer */
- void (*xDeleteAux)(void*); /* Destructor for the aux data */
- AuxData *pNextAux; /* Next element in list */
+ void (*xDelete)(void *); /* Destructor for the aux data */
+ AuxData *pNext; /* Next element in list */
};
/*
** The "context" argument for an installable function. A pointer to an
** instance of this structure is the first argument to the routines used
@@ -19247,14 +19222,12 @@
if( p->validYMD ) return;
if( !p->validJD ){
p->Y = 2000;
p->M = 1;
p->D = 1;
- }else if( !validJulianDay(p->iJD) ){
- datetimeError(p);
- return;
}else{
+ assert( validJulianDay(p->iJD) );
Z = (int)((p->iJD + 43200000)/86400000);
A = (int)((Z - 1867216.25)/36524.25);
A = Z + 1 + A - (A/4);
B = A + 1524;
C = (int)((B - 122.1)/365.25);
@@ -24686,16 +24659,15 @@
*db->pnBytesFreed += sqlite3DbMallocSize(db,p);
}
/*
** Free memory that might be associated with a particular database
-** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
-** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
+** connection.
*/
-SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
+SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
- assert( p!=0 );
+ if( p==0 ) return;
if( db ){
if( db->pnBytesFreed ){
measureAllocationSize(db, p);
return;
}
@@ -24715,14 +24687,10 @@
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
}
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( p ) sqlite3DbFreeNN(db, p);
-}
/*
** Change the size of an existing memory allocation
*/
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
@@ -26411,24 +26379,19 @@
** Generate a human-readable explanation of an expression tree.
*/
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
- char zFlgs[60];
+ char zFlgs[30];
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil");
sqlite3TreeViewPop(pView);
return;
}
if( pExpr->flags ){
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
- sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x iRJT=%d",
- pExpr->flags, pExpr->iRightJoinTable);
- }else{
- sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
- }
+ sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
}else{
zFlgs[0] = 0;
}
switch( pExpr->op ){
case TK_AGG_COLUMN: {
@@ -26643,15 +26606,10 @@
case TK_SELECT_COLUMN: {
sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn);
sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
break;
}
- case TK_IF_NULL_ROW: {
- sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
- sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
- break;
- }
default: {
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
break;
}
}
@@ -28367,11 +28325,10 @@
}else{
return 0;
}
}
#endif
- if( !sqlite3Isdigit(zNum[0]) ) return 0;
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
@@ -29531,153 +29488,151 @@
/* 18 */ "Jump" OpHelp(""),
/* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
/* 20 */ "Once" OpHelp(""),
/* 21 */ "If" OpHelp(""),
/* 22 */ "IfNot" OpHelp(""),
- /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
- /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"),
- /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"),
- /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"),
- /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"),
- /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"),
- /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"),
- /* 30 */ "Found" OpHelp("key=r[P3@P4]"),
- /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"),
- /* 32 */ "NotExists" OpHelp("intkey=r[P3]"),
- /* 33 */ "Last" OpHelp(""),
- /* 34 */ "IfSmaller" OpHelp(""),
- /* 35 */ "SorterSort" OpHelp(""),
- /* 36 */ "Sort" OpHelp(""),
- /* 37 */ "Rewind" OpHelp(""),
- /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"),
- /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"),
- /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 44 */ "Program" OpHelp(""),
- /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
- /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 49 */ "IncrVacuum" OpHelp(""),
- /* 50 */ "VNext" OpHelp(""),
- /* 51 */ "Init" OpHelp("Start at P2"),
- /* 52 */ "Return" OpHelp(""),
- /* 53 */ "EndCoroutine" OpHelp(""),
- /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 55 */ "Halt" OpHelp(""),
- /* 56 */ "Integer" OpHelp("r[P2]=P1"),
- /* 57 */ "Int64" OpHelp("r[P2]=P4"),
- /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 68 */ "CollSeq" OpHelp(""),
- /* 69 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
- /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 72 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 73 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 74 */ "RealAffinity" OpHelp(""),
- /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 81 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
- /* 83 */ "ElseNotEq" OpHelp(""),
- /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
- /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
+ /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
+ /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
+ /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
+ /* 27 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 28 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
+ /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 34 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 35 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 36 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 37 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 38 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 39 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 40 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
+ /* 42 */ "ElseNotEq" OpHelp(""),
+ /* 43 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 44 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 45 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 47 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 48 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 49 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 50 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 51 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 52 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 53 */ "Last" OpHelp(""),
+ /* 54 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 55 */ "IfSmaller" OpHelp(""),
+ /* 56 */ "SorterSort" OpHelp(""),
+ /* 57 */ "Sort" OpHelp(""),
+ /* 58 */ "Rewind" OpHelp(""),
+ /* 59 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 60 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 61 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 62 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 63 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 64 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 65 */ "Program" OpHelp(""),
+ /* 66 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 67 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 68 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 69 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 70 */ "IncrVacuum" OpHelp(""),
+ /* 71 */ "VNext" OpHelp(""),
+ /* 72 */ "Init" OpHelp("Start at P2"),
+ /* 73 */ "Return" OpHelp(""),
+ /* 74 */ "EndCoroutine" OpHelp(""),
+ /* 75 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 76 */ "Halt" OpHelp(""),
+ /* 77 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 78 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 79 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 80 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 81 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 82 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 83 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 84 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 85 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 86 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 87 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 88 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 89 */ "CollSeq" OpHelp(""),
+ /* 90 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 91 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 92 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 93 */ "RealAffinity" OpHelp(""),
/* 94 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 96 */ "Permutation" OpHelp(""),
+ /* 95 */ "Permutation" OpHelp(""),
+ /* 96 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
/* 97 */ "String8" OpHelp("r[P2]='P4'"),
- /* 98 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
- /* 99 */ "Column" OpHelp("r[P3]=PX"),
- /* 100 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 102 */ "Count" OpHelp("r[P2]=count()"),
- /* 103 */ "ReadCookie" OpHelp(""),
- /* 104 */ "SetCookie" OpHelp(""),
- /* 105 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 106 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 107 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 108 */ "OpenDup" OpHelp(""),
- /* 109 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 110 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 111 */ "SorterOpen" OpHelp(""),
- /* 112 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 113 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
- /* 114 */ "Close" OpHelp(""),
- /* 115 */ "ColumnsUsed" OpHelp(""),
- /* 116 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
- /* 117 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 118 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 119 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 120 */ "Delete" OpHelp(""),
- /* 121 */ "ResetCount" OpHelp(""),
- /* 122 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 123 */ "SorterData" OpHelp("r[P2]=data"),
- /* 124 */ "RowData" OpHelp("r[P2]=data"),
- /* 125 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 126 */ "NullRow" OpHelp(""),
- /* 127 */ "SorterInsert" OpHelp("key=r[P2]"),
- /* 128 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 129 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 130 */ "Seek" OpHelp("Move P3 to P1.rowid"),
- /* 131 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 98 */ "Column" OpHelp("r[P3]=PX"),
+ /* 99 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 100 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 101 */ "Count" OpHelp("r[P2]=count()"),
+ /* 102 */ "ReadCookie" OpHelp(""),
+ /* 103 */ "SetCookie" OpHelp(""),
+ /* 104 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 105 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 106 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 107 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 108 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 109 */ "SorterOpen" OpHelp(""),
+ /* 110 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 111 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 112 */ "Close" OpHelp(""),
+ /* 113 */ "ColumnsUsed" OpHelp(""),
+ /* 114 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 115 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 116 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 117 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 118 */ "Delete" OpHelp(""),
+ /* 119 */ "ResetCount" OpHelp(""),
+ /* 120 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 121 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 122 */ "RowData" OpHelp("r[P2]=data"),
+ /* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 124 */ "NullRow" OpHelp(""),
+ /* 125 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 126 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"),
+ /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 130 */ "Destroy" OpHelp(""),
+ /* 131 */ "Clear" OpHelp(""),
/* 132 */ "Real" OpHelp("r[P2]=P4"),
- /* 133 */ "Destroy" OpHelp(""),
- /* 134 */ "Clear" OpHelp(""),
- /* 135 */ "ResetSorter" OpHelp(""),
- /* 136 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
- /* 137 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
- /* 138 */ "SqlExec" OpHelp(""),
- /* 139 */ "ParseSchema" OpHelp(""),
- /* 140 */ "LoadAnalysis" OpHelp(""),
- /* 141 */ "DropTable" OpHelp(""),
- /* 142 */ "DropIndex" OpHelp(""),
- /* 143 */ "DropTrigger" OpHelp(""),
- /* 144 */ "IntegrityCk" OpHelp(""),
- /* 145 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 146 */ "Param" OpHelp(""),
- /* 147 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 148 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 149 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
- /* 150 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 151 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 152 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 153 */ "Expire" OpHelp(""),
- /* 154 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 155 */ "VBegin" OpHelp(""),
- /* 156 */ "VCreate" OpHelp(""),
- /* 157 */ "VDestroy" OpHelp(""),
- /* 158 */ "VOpen" OpHelp(""),
- /* 159 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 160 */ "VRename" OpHelp(""),
- /* 161 */ "Pagecount" OpHelp(""),
- /* 162 */ "MaxPgcnt" OpHelp(""),
- /* 163 */ "CursorHint" OpHelp(""),
- /* 164 */ "Noop" OpHelp(""),
- /* 165 */ "Explain" OpHelp(""),
+ /* 133 */ "ResetSorter" OpHelp(""),
+ /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 136 */ "SqlExec" OpHelp(""),
+ /* 137 */ "ParseSchema" OpHelp(""),
+ /* 138 */ "LoadAnalysis" OpHelp(""),
+ /* 139 */ "DropTable" OpHelp(""),
+ /* 140 */ "DropIndex" OpHelp(""),
+ /* 141 */ "DropTrigger" OpHelp(""),
+ /* 142 */ "IntegrityCk" OpHelp(""),
+ /* 143 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 144 */ "Param" OpHelp(""),
+ /* 145 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 146 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 147 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 148 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 149 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 150 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 151 */ "Expire" OpHelp(""),
+ /* 152 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 153 */ "VBegin" OpHelp(""),
+ /* 154 */ "VCreate" OpHelp(""),
+ /* 155 */ "VDestroy" OpHelp(""),
+ /* 156 */ "VOpen" OpHelp(""),
+ /* 157 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 158 */ "VRename" OpHelp(""),
+ /* 159 */ "Pagecount" OpHelp(""),
+ /* 160 */ "MaxPgcnt" OpHelp(""),
+ /* 161 */ "CursorHint" OpHelp(""),
+ /* 162 */ "Noop" OpHelp(""),
+ /* 163 */ "Explain" OpHelp(""),
};
return azName[i];
}
#endif
@@ -45288,20 +45243,21 @@
}
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
sqlite3EndBenignMalloc();
if( zBulk ){
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
- do{
+ int i;
+ for(i=0; iszPage];
pX->page.pBuf = zBulk;
pX->page.pExtra = &pX[1];
pX->isBulkLocal = 1;
pX->isAnchor = 0;
pX->pNext = pCache->pFree;
pCache->pFree = pX;
zBulk += pCache->szAlloc;
- }while( --nBulk );
+ }
}
return pCache->pFree!=0;
}
/*
@@ -46213,11 +46169,11 @@
*/
SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
int nFree = 0;
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
assert( sqlite3_mutex_notheld(pcache1.mutex) );
- if( sqlite3GlobalConfig.pPage==0 ){
+ if( sqlite3GlobalConfig.nPage==0 ){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
while( (nReq<0 || nFreeisAnchor==0
@@ -49173,15 +49129,10 @@
Pgno pgno; /* The page number of a page in journal */
u32 cksum; /* Checksum used for sanity checking */
char *aData; /* Temporary storage for the page */
sqlite3_file *jfd; /* The file descriptor for the journal file */
int isSynced; /* True if journal page is synced */
-#ifdef SQLITE_HAS_CODEC
- /* The jrnlEnc flag is true if Journal pages should be passed through
- ** the codec. It is false for pure in-memory journals. */
- const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
-#endif
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */
assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */
@@ -49301,38 +49252,18 @@
&& isSynced
){
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
assert( !pagerUseWal(pPager) );
-
- /* Write the data read from the journal back into the database file.
- ** This is usually safe even for an encrypted database - as the data
- ** was encrypted before it was written to the journal file. The exception
- ** is if the data was just read from an in-memory sub-journal. In that
- ** case it must be encrypted here before it is copied into the database
- ** file. */
-#ifdef SQLITE_HAS_CODEC
- if( !jrnlEnc ){
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
- rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
- }else
-#endif
- rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
-
+ rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
-#ifdef SQLITE_HAS_CODEC
- if( jrnlEnc ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
- }else
-#endif
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
}
}else if( !isMainJrnl && pPg==0 ){
/* If this is a rollback of a savepoint and data was not written to
** the database and the page is not in-memory, there is a potential
** problem. When the page is next fetched by the b-tree layer, it
@@ -49380,13 +49311,11 @@
if( pgno==1 ){
memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
}
/* Decode the page just read from disk */
-#if SQLITE_HAS_CODEC
- if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
-#endif
+ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3PcacheRelease(pPg);
}
return rc;
}
@@ -51394,17 +51323,12 @@
** write the journal record into the file. */
if( rc==SQLITE_OK ){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
-
-#if SQLITE_HAS_CODEC
- if( !pPager->subjInMemory ){
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
- }else
-#endif
- pData2 = pData;
+
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
}
@@ -58552,14 +58476,14 @@
/* All fields above are zeroed when the cursor is allocated. See
** sqlite3BtreeCursorZero(). Fields that follow must be manually
** initialized. */
i8 iPage; /* Index of current page in apPage */
u8 curIntKey; /* Value of apPage[0]->intKey */
- u16 ix; /* Current index for apPage[iPage] */
- u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
- struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
+ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
+ void *padding1; /* Make object size a multiple of 16 */
+ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
+ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
};
/*
** Legal values for BtCursor.curFlags
*/
@@ -59531,11 +59455,10 @@
** rowid iRow is being replaced or deleted. In this case invalidate
** only those incrblob cursors open on that specific row.
*/
static void invalidateIncrblobCursors(
Btree *pBtree, /* The database file to check */
- Pgno pgnoRoot, /* The table that might be changing */
i64 iRow, /* The rowid that might be changing */
int isClearTable /* True if all rows are being deleted */
){
BtCursor *p;
if( pBtree->hasIncrblobCur==0 ) return;
@@ -59542,20 +59465,20 @@
assert( sqlite3BtreeHoldsMutex(pBtree) );
pBtree->hasIncrblobCur = 0;
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
if( (p->curFlags & BTCF_Incrblob)!=0 ){
pBtree->hasIncrblobCur = 1;
- if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){
+ if( isClearTable || p->info.nKey==iRow ){
p->eState = CURSOR_INVALID;
}
}
}
}
#else
/* Stub function when INCRBLOB is omitted */
- #define invalidateIncrblobCursors(w,x,y,z)
+ #define invalidateIncrblobCursors(x,y,z)
#endif /* SQLITE_OMIT_INCRBLOB */
/*
** Set bit pgno of the BtShared.pHasContent bitvec. This is called
** when a page that previously contained data becomes a free-list leaf
@@ -63349,21 +63272,21 @@
#ifndef NDEBUG
static void assertCellInfo(BtCursor *pCur){
CellInfo info;
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
+ btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
#define assertCellInfo(x)
#endif
static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
if( pCur->info.nSize==0 ){
int iPage = pCur->iPage;
pCur->curFlags |= BTCF_ValidNKey;
- btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
+ btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
}else{
assertCellInfo(pCur);
}
}
@@ -63566,11 +63489,11 @@
#endif
assert( pPage );
assert( eOp==0 || eOp==1 );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->ixnCell );
+ assert( pCur->aiIdx[pCur->iPage]nCell );
assert( cursorHoldsMutex(pCur) );
getCellInfo(pCur);
aPayload = pCur->info.pPayload;
assert( offset+amt <= pCur->info.nPayload );
@@ -63753,11 +63676,11 @@
*/
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->ixapPage[pCur->iPage]->nCell );
+ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell );
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}
/*
** This variant of sqlite3BtreePayload() works even if the cursor has not
@@ -63815,11 +63738,11 @@
u32 amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->ixapPage[pCur->iPage]->nCell );
+ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
if( pCur->info.nLocalinfo.nLocal;
@@ -63866,12 +63789,12 @@
if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
return SQLITE_CORRUPT_BKPT;
}
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->aiIdx[pCur->iPage++] = pCur->ix;
- pCur->ix = 0;
+ pCur->iPage++;
+ pCur->aiIdx[pCur->iPage] = 0;
return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
pCur, pCur->curPagerFlags);
}
#ifdef SQLITE_DEBUG
@@ -63915,11 +63838,10 @@
pCur->apPage[pCur->iPage]->pgno
);
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->ix = pCur->aiIdx[pCur->iPage-1];
releasePageNotNull(pCur->apPage[pCur->iPage--]);
}
/*
** Move the cursor to point to the root page of its b-tree structure.
@@ -63997,11 +63919,11 @@
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
return SQLITE_CORRUPT_BKPT;
}
skip_init:
- pCur->ix = 0;
+ pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
pRoot = pCur->apPage[0];
if( pRoot->nCell>0 ){
@@ -64031,12 +63953,12 @@
MemPage *pPage;
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- assert( pCur->ixnCell );
- pgno = get4byte(findCell(pPage, pCur->ix));
+ assert( pCur->aiIdx[pCur->iPage]nCell );
+ pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
rc = moveToChild(pCur, pgno);
}
return rc;
}
@@ -64057,15 +63979,15 @@
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- pCur->ix = pPage->nCell;
+ pCur->aiIdx[pCur->iPage] = pPage->nCell;
rc = moveToChild(pCur, pgno);
if( rc ) return rc;
}
- pCur->ix = pPage->nCell-1;
+ pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
return SQLITE_OK;
}
@@ -64109,11 +64031,11 @@
** to the last entry in the b-tree. */
int ii;
for(ii=0; iiiPage; ii++){
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
- assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
+ assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
assert( pCur->apPage[pCur->iPage]->leaf );
#endif
return SQLITE_OK;
}
@@ -64256,11 +64178,11 @@
assert( pPage->intKey==(pIdxKey==0) );
lwr = 0;
upr = pPage->nCell-1;
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
- pCur->ix = (u16)idx;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
if( xRecordCompare==0 ){
for(;;){
i64 nCellKey;
pCell = findCellPastPtr(pPage, idx);
if( pPage->intKeyLeaf ){
@@ -64275,11 +64197,11 @@
}else if( nCellKey>intKey ){
upr = idx-1;
if( lwr>upr ){ c = +1; break; }
}else{
assert( nCellKey==intKey );
- pCur->ix = (u16)idx;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
if( !pPage->leaf ){
lwr = idx;
goto moveto_next_layer;
}else{
pCur->curFlags |= BTCF_ValidNKey;
@@ -64344,11 +64266,11 @@
pCellKey = sqlite3Malloc( nCell+18 );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
- pCur->ix = (u16)idx;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
@@ -64366,11 +64288,11 @@
upr = idx-1;
}else{
assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
- pCur->ix = (u16)idx;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
if( lwr>upr ) break;
assert( lwr+upr>=0 );
@@ -64378,12 +64300,12 @@
}
}
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- assert( pCur->ixapPage[pCur->iPage]->nCell );
- pCur->ix = (u16)idx;
+ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell );
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
}
moveto_next_layer:
@@ -64390,11 +64312,11 @@
if( lwr>=pPage->nCell ){
chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
}else{
chldPg = get4byte(findCell(pPage, lwr));
}
- pCur->ix = (u16)lwr;
+ pCur->aiIdx[pCur->iPage] = (u16)lwr;
rc = moveToChild(pCur, chldPg);
if( rc ) break;
}
moveto_finish:
pCur->info.nSize = 0;
@@ -64491,11 +64413,11 @@
pCur->skipNext = 0;
}
}
pPage = pCur->apPage[pCur->iPage];
- idx = ++pCur->ix;
+ idx = ++pCur->aiIdx[pCur->iPage];
assert( pPage->isInit );
/* If the database file is corrupt, it is possible for the value of idx
** to be invalid here. This can only occur if a second cursor modifies
** the page while cursor pCur is holding a reference to it. Which can
@@ -64515,11 +64437,11 @@
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}
moveToParent(pCur);
pPage = pCur->apPage[pCur->iPage];
- }while( pCur->ix>=pPage->nCell );
+ }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
if( pPage->intKey ){
return sqlite3BtreeNext(pCur, pRes);
}else{
return SQLITE_OK;
}
@@ -64539,12 +64461,12 @@
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
*pRes = 0;
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
pPage = pCur->apPage[pCur->iPage];
- if( (++pCur->ix)>=pPage->nCell ){
- pCur->ix--;
+ if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
+ pCur->aiIdx[pCur->iPage]--;
return btreeNext(pCur, pRes);
}
if( pPage->leaf ){
return SQLITE_OK;
}else{
@@ -64604,16 +64526,16 @@
}
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
if( !pPage->leaf ){
- int idx = pCur->ix;
+ int idx = pCur->aiIdx[pCur->iPage];
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
- while( pCur->ix==0 ){
+ while( pCur->aiIdx[pCur->iPage]==0 ){
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
*pRes = 1;
return SQLITE_OK;
}
@@ -64620,11 +64542,11 @@
moveToParent(pCur);
}
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
- pCur->ix--;
+ pCur->aiIdx[pCur->iPage]--;
pPage = pCur->apPage[pCur->iPage];
if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, pRes);
}else{
rc = SQLITE_OK;
@@ -64639,16 +64561,16 @@
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
*pRes = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
- || pCur->ix==0
+ || pCur->aiIdx[pCur->iPage]==0
|| pCur->apPage[pCur->iPage]->leaf==0
){
return btreePrevious(pCur, pRes);
}
- pCur->ix--;
+ pCur->aiIdx[pCur->iPage]--;
return SQLITE_OK;
}
/*
** Allocate a new page from the database file.
@@ -66966,12 +66888,12 @@
assert( balance_deeper_called==0 );
VVA_ONLY( balance_deeper_called++ );
rc = balance_deeper(pPage, &pCur->apPage[1]);
if( rc==SQLITE_OK ){
pCur->iPage = 1;
- pCur->ix = 0;
pCur->aiIdx[0] = 0;
+ pCur->aiIdx[1] = 0;
assert( pCur->apPage[1]->nOverflow );
}
}else{
break;
}
@@ -67144,11 +67066,11 @@
if( pCur->pKeyInfo==0 ){
assert( pX->pKey==0 );
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
- invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
+ invalidateIncrblobCursors(p, pX->nKey, 0);
/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
** to a row with the same key as the new entry being inserted. */
assert( (flags & BTREE_SAVEPOSITION)==0 ||
((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
@@ -67156,10 +67078,13 @@
/* If the cursor is currently on the last row and we are appending a
** new row onto the end, set the "loc" to avoid an unnecessary
** btreeMoveto() call */
if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
loc = 0;
+ }else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0
+ && pCur->info.nKey==pX->nKey-1 ){
+ loc = -1;
}else if( loc==0 ){
rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
if( rc ) return rc;
}
}else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
@@ -67193,11 +67118,11 @@
assert( newCell!=0 );
rc = fillInCell(pPage, newCell, pX, &szNew);
if( rc ) goto end_insert;
assert( szNew==pPage->xCellSize(pPage, newCell) );
assert( szNew <= MX_CELL_SIZE(pBt) );
- idx = pCur->ix;
+ idx = pCur->aiIdx[pCur->iPage];
if( loc==0 ){
CellInfo info;
assert( idxnCell );
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ){
@@ -67221,12 +67146,11 @@
}
dropCell(pPage, idx, info.nSize, &rc);
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
- idx = ++pCur->ix;
- pCur->curFlags &= ~BTCF_ValidNKey;
+ idx = ++pCur->aiIdx[pCur->iPage];
}else{
assert( pPage->leaf );
}
insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
assert( pPage->nOverflow==0 || rc==SQLITE_OK );
@@ -67318,16 +67242,16 @@
assert( pBt->inTransaction==TRANS_WRITE );
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
assert( pCur->curFlags & BTCF_WriteFlag );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
- assert( pCur->ixapPage[pCur->iPage]->nCell );
+ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell );
assert( pCur->eState==CURSOR_VALID );
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
iCellDepth = pCur->iPage;
- iCellIdx = pCur->ix;
+ iCellIdx = pCur->aiIdx[iCellDepth];
pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx);
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
@@ -67372,11 +67296,11 @@
}
/* If this is a delete operation to remove a row from a table b-tree,
** invalidate any incrblob cursors open on the row being deleted. */
if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
+ invalidateIncrblobCursors(p, pCur->info.nKey, 0);
}
/* Make the page containing the entry to be deleted writable. Then free any
** overflow pages associated with the entry and finally remove the cell
** itself from within the page. */
@@ -67440,11 +67364,11 @@
assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
pCur->eState = CURSOR_SKIPNEXT;
if( iCellIdx>=pPage->nCell ){
pCur->skipNext = -1;
- pCur->ix = pPage->nCell-1;
+ pCur->aiIdx[iCellDepth] = pPage->nCell-1;
}else{
pCur->skipNext = 1;
}
}else{
rc = moveToRoot(pCur);
@@ -67699,11 +67623,11 @@
if( SQLITE_OK==rc ){
/* Invalidate all incrblob cursors open on table iTable (assuming iTable
** is the root of a table b-tree - if it is not, the following call is
** a no-op). */
- invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
+ invalidateIncrblobCursors(p, 0, 1);
rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
}
sqlite3BtreeLeave(p);
return rc;
}
@@ -67953,20 +67877,20 @@
/* All pages of the b-tree have been visited. Return successfully. */
*pnEntry = nEntry;
return moveToRoot(pCur);
}
moveToParent(pCur);
- }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
+ }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
- pCur->ix++;
+ pCur->aiIdx[pCur->iPage]++;
pPage = pCur->apPage[pCur->iPage];
}
/* Descend to the child node of the cell that the cursor currently
** points at. This is the right-child if (iIdx==pPage->nCell).
*/
- iIdx = pCur->ix;
+ iIdx = pCur->aiIdx[pCur->iPage];
if( iIdx==pPage->nCell ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
}else{
rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
}
@@ -68347,11 +68271,10 @@
if( pPage->intKey ){
if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){
checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
}
maxKey = info.nKey;
- keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */
}
/* Check the content overflow list */
if( info.nPayload>info.nLocal ){
int nPage; /* Number of pages on the overflow chain */
@@ -69733,14 +69656,10 @@
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
- /* Cannot be both MEM_Null and some other type */
- assert( (p->flags & MEM_Null)==0 ||
- (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 );
-
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
/* If p holds a string or blob, the Mem.z must point to exactly
@@ -69822,28 +69741,30 @@
assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
testcase( bPreserve && pMem->z==0 );
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
- if( n<32 ) n = 32;
- if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
- pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- bPreserve = 0;
- }else{
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
- pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
- }
- if( pMem->zMalloc==0 ){
- sqlite3VdbeMemSetNull(pMem);
- pMem->z = 0;
- pMem->szMalloc = 0;
- return SQLITE_NOMEM_BKPT;
- }else{
- pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
- }
-
- if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
+ if( pMem->szMallocszMalloc>0 && pMem->z==pMem->zMalloc ){
+ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
+ bPreserve = 0;
+ }else{
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
+ pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
+ }
+ if( pMem->zMalloc==0 ){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->z = 0;
+ pMem->szMalloc = 0;
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+ }
+ }
+
+ if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
pMem->xDel((void *)(pMem->z));
@@ -70036,11 +69957,11 @@
ctx.pOut = &t;
ctx.pMem = pMem;
ctx.pFunc = pFunc;
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( (pMem->flags & MEM_Dyn)==0 );
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
rc = ctx.isError;
}
return rc;
}
@@ -70087,11 +70008,11 @@
static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
if( VdbeMemDynamic(p) ){
vdbeMemClearExternAndSetNull(p);
}
if( p->szMalloc ){
- sqlite3DbFreeNN(p->db, p->zMalloc);
+ sqlite3DbFree(p->db, p->zMalloc);
p->szMalloc = 0;
}
p->z = 0;
}
@@ -70115,11 +70036,11 @@
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is out of range of a 64-bit signed integer then
** return the closest available 64-bit signed integer.
*/
-static SQLITE_NOINLINE i64 doubleToInt64(double r){
+static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
#else
/*
@@ -70151,15 +70072,10 @@
** it into an integer and return that. If pMem represents an
** an SQL-NULL value, return 0.
**
** If pMem represents a string value, its encoding might be changed.
*/
-static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
- i64 value = 0;
- sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
- return value;
-}
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
int flags;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
@@ -70166,12 +70082,14 @@
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
}else if( flags & (MEM_Str|MEM_Blob) ){
+ i64 value = 0;
assert( pMem->z || pMem->n==0 );
- return memIntValue(pMem);
+ sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
+ return value;
}else{
return 0;
}
}
@@ -70179,25 +70097,22 @@
** Return the best representation of pMem that we can get into a
** double. If pMem is already a double or an integer, return its
** value. If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
-static SQLITE_NOINLINE double memRealValue(Mem *pMem){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- double val = (double)0;
- sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
- return val;
-}
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->u.r;
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- return memRealValue(pMem);
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ double val = (double)0;
+ sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
+ return val;
}else{
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return (double)0;
}
}
@@ -70818,11 +70733,11 @@
for(i=0; iaMem[i].flags = MEM_Null;
pRec->aMem[i].db = db;
}
}else{
- sqlite3DbFreeNN(db, pRec);
+ sqlite3DbFree(db, pRec);
pRec = 0;
}
}
if( pRec==0 ) return 0;
p->ppRec[0] = pRec;
@@ -70930,11 +70845,11 @@
}
if( apVal ){
for(i=0; ipKeyInfo);
- sqlite3DbFreeNN(db, pRec);
+ sqlite3DbFree(db, pRec);
}
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */
/*
@@ -71380,11 +71295,11 @@
** Free an sqlite3_value object
*/
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return;
sqlite3VdbeMemRelease((Mem *)v);
- sqlite3DbFreeNN(((Mem*)v)->db, v);
+ sqlite3DbFree(((Mem*)v)->db, v);
}
/*
** The sqlite3ValueBytes() routine returns the number of bytes in the
** sqlite3_value object assuming that it uses the encoding "enc".
@@ -72223,11 +72138,11 @@
** If the input FuncDef structure is ephemeral, then free it. If
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3DbFreeNN(db, pDef);
+ sqlite3DbFree(db, pDef);
}
}
static void vdbeFreeOpArray(sqlite3 *, Op *, int);
@@ -72234,15 +72149,15 @@
/*
** Delete a P4 value if necessary.
*/
static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
freeEphemeralFunction(db, p->pFunc);
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
static void freeP4(sqlite3 *db, int p4type, void *p4){
assert( db );
switch( p4type ){
case P4_FUNCCTX: {
@@ -72291,18 +72206,18 @@
** nOp entries.
*/
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
if( aOp ){
Op *pOp;
- for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
+ for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
- sqlite3DbFreeNN(db, aOp);
}
+ sqlite3DbFree(db, aOp);
}
/*
** Link the SubProgram object passed as the second argument into the linked
** list at Vdbe.pSubProgram. This list is used to delete all sub-program
@@ -72971,11 +72886,11 @@
testcase( p->flags & MEM_Frame );
testcase( p->flags & MEM_RowSet );
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
}else if( p->szMalloc ){
- sqlite3DbFreeNN(db, p->zMalloc);
+ sqlite3DbFree(db, p->zMalloc);
p->szMalloc = 0;
}
p->flags = MEM_Undefined;
}while( (++p)db, pCx);
break;
}
case CURTYPE_BTREE: {
- if( pCx->isEphemeral ){
- if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx);
+ if( pCx->pBtx ){
+ sqlite3BtreeClose(pCx->pBtx);
/* The pCx->pCursor will be close automatically, if it exists, by
** the call above. */
}else{
assert( pCx->uc.pCursor!=0 );
sqlite3BtreeCloseCursor(pCx->uc.pCursor);
@@ -74342,10 +74257,11 @@
}
fclose(out);
}
}
#endif
+ p->iCurrentTime = 0;
p->magic = VDBE_MAGIC_RESET;
return p->rc & db->errMask;
}
/*
@@ -74380,22 +74296,20 @@
*/
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
- || (pAux->iAuxOp==iOp
- && pAux->iAuxArg>=0
- && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
+ || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
){
- testcase( pAux->iAuxArg==31 );
- if( pAux->xDeleteAux ){
- pAux->xDeleteAux(pAux->pAux);
+ testcase( pAux->iArg==31 );
+ if( pAux->xDelete ){
+ pAux->xDelete(pAux->pAux);
}
- *pp = pAux->pNextAux;
+ *pp = pAux->pNext;
sqlite3DbFree(db, pAux);
}else{
- pp= &pAux->pNextAux;
+ pp= &pAux->pNext;
}
}
}
/*
@@ -74453,11 +74367,11 @@
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
/*
** The cursor "p" has a pending seek operation that has not yet been
** carried out. Seek the cursor now. If an error occurs, return
@@ -76012,11 +75926,11 @@
int i;
for(i=0; iaMem[i];
if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
}
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -76079,11 +75993,11 @@
if( preupdate.aNew ){
int i;
for(i=0; inField; i++){
sqlite3VdbeMemRelease(&preupdate.aNew[i]);
}
- sqlite3DbFreeNN(db, preupdate.aNew);
+ sqlite3DbFree(db, preupdate.aNew);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
/************** End of vdbeaux.c *********************************************/
@@ -76892,16 +76806,10 @@
}
/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
-**
-** The left-most argument is 0.
-**
-** Undocumented behavior: If iArg is negative then access a cache of
-** auxiliary data pointers that is available to all functions within a
-** single prepared statement. The iArg values must match.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
@@ -76908,28 +76816,21 @@
#if SQLITE_ENABLE_STAT3_OR_STAT4
if( pCtx->pVdbe==0 ) return 0;
#else
assert( pCtx->pVdbe!=0 );
#endif
- for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
- if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
- return pAuxData->pAux;
- }
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
- return 0;
+
+ return (pAuxData ? pAuxData->pAux : 0);
}
/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
-**
-** The left-most argument is 0.
-**
-** Undocumented behavior: If iArg is negative then make the data available
-** to all functions within the current prepared statement using iArg as an
-** access code.
*/
SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
@@ -76937,38 +76838,37 @@
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ if( iArg<0 ) goto failed;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pVdbe==0 ) goto failed;
#else
assert( pVdbe!=0 );
#endif
- for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
- if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
- break;
- }
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
if( pAuxData==0 ){
pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
if( !pAuxData ) goto failed;
- pAuxData->iAuxOp = pCtx->iOp;
- pAuxData->iAuxArg = iArg;
- pAuxData->pNextAux = pVdbe->pAuxData;
+ pAuxData->iOp = pCtx->iOp;
+ pAuxData->iArg = iArg;
+ pAuxData->pNext = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
if( pCtx->fErrorOrAux==0 ){
pCtx->isError = 0;
pCtx->fErrorOrAux = 1;
}
- }else if( pAuxData->xDeleteAux ){
- pAuxData->xDeleteAux(pAuxData->pAux);
+ }else if( pAuxData->xDelete ){
+ pAuxData->xDelete(pAuxData->pAux);
}
pAuxData->pAux = pAux;
- pAuxData->xDeleteAux = xDelete;
+ pAuxData->xDelete = xDelete;
return;
failed:
if( xDelete ){
xDelete(pAux);
@@ -78679,11 +78579,10 @@
}
static void registerTrace(int iReg, Mem *p){
printf("REG[%d] = ", iReg);
memTracePrint(p);
printf("\n");
- sqlite3VdbeCheckMemInvariants(p);
}
#endif
#ifdef SQLITE_DEBUG
# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
@@ -79046,11 +78945,11 @@
case OP_Goto: { /* jump */
jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
- ** OP_VNext, or OP_SorterNext) all jump here upon
+ ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
** completion. Check to see if sqlite3_interrupt() has been called
** or if the progress callback needs to be invoked.
**
** This code uses unstructured "goto" statements and does not look clean.
** But that is not due to sloppy coding habits. The code is written this
@@ -79434,11 +79333,11 @@
** previously copied using OP_SCopy, the copies will continue to be valid.
*/
case OP_SoftNull: {
assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
pOut = &aMem[pOp->p1];
- pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null;
+ pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
break;
}
/* Opcode: Blob P1 P2 * P4 *
** Synopsis: r[P2]=P4 (len=P1)
@@ -79777,10 +79676,11 @@
type1 = numericType(pIn1);
pIn2 = &aMem[pOp->p2];
type2 = numericType(pIn2);
pOut = &aMem[pOp->p3];
flags = pIn1->flags | pIn2->flags;
+ if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
bIntint = 1;
switch( pOp->opcode ){
@@ -79800,12 +79700,10 @@
break;
}
}
pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
- }else if( (flags & MEM_Null)!=0 ){
- goto arithmetic_result_is_null;
}else{
bIntint = 0;
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
rB = sqlite3VdbeRealValue(pIn2);
@@ -79849,11 +79747,11 @@
break;
}
/* Opcode: CollSeq P1 * * P4
**
-** P4 is a pointer to a CollSeq object. If the next call to a user function
+** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** If P1 is not zero, then it is a register that a subsequent min() or
@@ -80130,15 +80028,15 @@
** Synopsis: affinity(r[P1])
**
** Force the value in register P1 to be the type defined by P2.
**
**
-** - P2=='A' → BLOB
-**
- P2=='B' → TEXT
-**
- P2=='C' → NUMERIC
-**
- P2=='D' → INTEGER
-**
- P2=='E' → REAL
+**
- TEXT
+**
- BLOB
+**
- NUMERIC
+**
- INTEGER
+**
- REAL
**
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_Cast: { /* in1 */
@@ -80713,28 +80611,10 @@
goto jump_to_p2;
}
break;
}
-/* Opcode: IfNullRow P1 P2 P3 * *
-** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2
-**
-** Check the cursor P1 to see if it is currently pointing at a NULL row.
-** If it is, then set register P3 to NULL and jump immediately to P2.
-** If P1 is not on a NULL row, then fall through without making any
-** changes.
-*/
-case OP_IfNullRow: { /* jump */
- assert( pOp->p1>=0 && pOp->p1nCursor );
- assert( p->apCsr[pOp->p1]!=0 );
- if( p->apCsr[pOp->p1]->nullRow ){
- sqlite3VdbeMemSetNull(aMem + pOp->p3);
- goto jump_to_p2;
- }
- break;
-}
-
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
@@ -80742,20 +80622,20 @@
** from this record. If there are less that (P2+1)
** values in the record, extract a NULL.
**
** The value extracted is stored in register P3.
**
-** If the record contains fewer than P2 fields, then extract a NULL. Or,
+** If the column contains fewer than P2 fields, then extract a NULL. Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
**
-** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
+** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively. The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
@@ -81006,28 +80886,28 @@
/* Opcode: Affinity P1 P2 * P4 *
** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
-** P4 is a string that is P2 characters long. The N-th character of the
-** string indicates the column affinity that should be used for the N-th
+** P4 is a string that is P2 characters long. The nth character of the
+** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
const char *zAffinity; /* The affinity to be applied */
+ char cAff; /* A single character of affinity */
zAffinity = pOp->p4.z;
assert( zAffinity!=0 );
- assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- do{
+ while( (cAff = *(zAffinity++))!=0 ){
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
- applyAffinity(pIn1, *(zAffinity++), encoding);
+ applyAffinity(pIn1, cAff, encoding);
pIn1++;
- }while( zAffinity[0] );
+ }
break;
}
/* Opcode: MakeRecord P1 P2 P3 P4 *
** Synopsis: r[P3]=mkrec(r[P1@P2])
@@ -81034,12 +80914,12 @@
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
** in an index. The OP_Column opcode can decode the record later.
**
-** P4 may be a string that is P2 characters long. The N-th character of the
-** string indicates the column affinity that should be used for the N-th
+** P4 may be a string that is P2 characters long. The nth character of the
+** string indicates the column affinity that should be used for the nth
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
@@ -81194,10 +81074,11 @@
pOut->flags = MEM_Blob;
if( nZero ){
pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
+ pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -81822,41 +81703,10 @@
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
if( rc ) goto abort_due_to_error;
break;
}
-
-/* Opcode: OpenDup P1 P2 * * *
-**
-** Open a new cursor P1 that points to the same ephemeral table as
-** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral
-** opcode. Only ephemeral cursors may be duplicated.
-**
-** Duplicate ephemeral cursors are used for self-joins of materialized views.
-*/
-case OP_OpenDup: {
- VdbeCursor *pOrig; /* The original cursor to be duplicated */
- VdbeCursor *pCx; /* The new cursor */
-
- pOrig = p->apCsr[pOp->p2];
- assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */
-
- pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->isEphemeral = 1;
- pCx->pKeyInfo = pOrig->pKeyInfo;
- pCx->isTable = pOrig->isTable;
- rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
- pCx->pKeyInfo, pCx->uc.pCursor);
- /* The sqlite3BtreeCursor() routine can only fail for the first cursor
- ** opened for a database. Since there is already an open cursor when this
- ** opcode is run, the sqlite3BtreeCursor() cannot fail */
- assert( rc==SQLITE_OK );
- break;
-}
-
/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
@@ -82389,16 +82239,14 @@
}
#endif
pIdxKey = &r;
pFree = 0;
}else{
- assert( pIn3->flags & MEM_Blob );
- rc = ExpandBlob(pIn3);
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- if( rc ) goto no_mem;
pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
+ assert( pIn3->flags & MEM_Blob );
+ (void)ExpandBlob(pIn3);
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
takeJump = 0;
if( pOp->opcode==OP_NoConflict ){
@@ -82411,11 +82259,11 @@
break;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
- if( pFree ) sqlite3DbFreeNN(db, pFree);
+ if( pFree ) sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pC->seekResult = res;
alreadyExists = (res==0);
@@ -83721,21 +83569,14 @@
**
** If AUTOVACUUM is enabled then it is possible that another root page
** might be moved into the newly deleted root page in order to keep all
** root pages contiguous at the beginning of the database. The former
** value of the root page that moved - its value before the move occurred -
-** is stored in register P2. If no page movement was required (because the
-** table being dropped was already the last one in the database) then a
-** zero is stored in register P2. If AUTOVACUUM is disabled then a zero
-** is stored in register P2.
-**
-** This opcode throws an error if there are any active reader VMs when
-** it is invoked. This is done to avoid the difficulty associated with
-** updating existing cursors when a root page is moved in an AUTOVACUUM
-** database. This error is thrown even if the database is not an AUTOVACUUM
-** db in order to avoid introducing an incompatibility between autovacuum
-** and non-autovacuum modes.
+** is stored in register P2. If no page
+** movement was required (because the table being dropped was already
+** the last one in the database) then a zero is stored in register P2.
+** If AUTOVACUUM is disabled then a zero is stored in register P2.
**
** See also: Clear
*/
case OP_Destroy: { /* out2 */
int iMoved;
@@ -83936,11 +83777,11 @@
db->init.busy = 1;
initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFreeNN(db, zSql);
+ sqlite3DbFree(db, zSql);
db->init.busy = 0;
}
}
if( rc ){
sqlite3ResetAllSchemasOfConnection(db);
@@ -84064,11 +83905,11 @@
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
** Synopsis: rowset(P1)=r[P2]
**
-** Insert the integer value held by register P2 into a RowSet object
+** Insert the integer value held by register P2 into a boolean index
** held in register P1.
**
** An assertion fails if P2 is not an integer.
*/
case OP_RowSetAdd: { /* in1, in2 */
@@ -84084,13 +83925,12 @@
}
/* Opcode: RowSetRead P1 P2 P3 * *
** Synopsis: r[P3]=rowset(P1)
**
-** Extract the smallest value from the RowSet object in P1
-** and put that value into register P3.
-** Or, if RowSet object P1 is initially empty, leave P3
+** Extract the smallest value from boolean index P1 and put that value into
+** register P3. Or, if boolean index P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: { /* jump, in1, out3 */
i64 val;
@@ -84117,18 +83957,19 @@
** contains a RowSet object and that RowSet object contains
** the value held in P3, jump to register P2. Otherwise, insert the
** integer in P3 into the RowSet and continue on to the
** next opcode.
**
-** The RowSet object is optimized for the case where sets of integers
-** are inserted in distinct phases, which each set contains no duplicates.
-** Each set is identified by a unique P4 value. The first set
-** must have P4==0, the final set must have P4==-1, and for all other sets
-** must have P4>0.
+** The RowSet object is optimized for the case where successive sets
+** of integers, where each set contains no duplicates. Each set
+** of values is identified by a unique P4 value. The first set
+** must have P4==0, the final set P4=-1. P4 must be either -1 or
+** non-negative. For non-negative values of P4 only the lower 4
+** bits are significant.
**
** This allows optimizations: (a) when P4==0 there is no need to test
-** the RowSet object for P3, as it is guaranteed not to contain it,
+** the rowset object for P3, as it is guaranteed not to contain it,
** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
** previously inserted as part of set X (only if it was previously
** inserted as part of some other set).
@@ -86864,40 +86705,41 @@
int res; /* Return value */
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
- if( s1==s2 ){
- /* The two values have the same sign. Compare using memcmp(). */
- static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
- const u8 n = aLen[s1];
- int i;
- res = 0;
- for(i=0; i7 && s2>7 ){
- res = s1 - s2;
- }else{
- if( s2>7 ){
- res = +1;
- }else if( s1>7 ){
- res = -1;
- }else{
- res = s1 - s2;
- }
- assert( res!=0 );
-
- if( res>0 ){
- if( *v1 & 0x80 ) res = -1;
- }else{
- if( *v2 & 0x80 ) res = +1;
+ if( s1>7 && s2>7 ){
+ res = s1 - s2;
+ }else{
+ if( s1==s2 ){
+ if( (*v1 ^ *v2) & 0x80 ){
+ /* The two values have different signs */
+ res = (*v1 & 0x80) ? -1 : +1;
+ }else{
+ /* The two values have the same sign. Compare using memcmp(). */
+ static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
+ int i;
+ res = 0;
+ for(i=0; i7 ){
+ res = +1;
+ }else if( s1>7 ){
+ res = -1;
+ }else{
+ res = s1 - s2;
+ }
+ assert( res!=0 );
+
+ if( res>0 ){
+ if( *v1 & 0x80 ) res = -1;
+ }else{
+ if( *v2 & 0x80 ) res = +1;
+ }
}
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
@@ -90948,11 +90790,11 @@
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
+ if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
}
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft->flags&EP_xIsSelect );
return sqlite3ExprAffinity(
@@ -91242,10 +91084,11 @@
}else{
return 1;
}
}
+#ifndef SQLITE_OMIT_SUBQUERY
/*
** Return a pointer to a subexpression of pVector that is the i-th
** column of the vector (numbered starting with 0). The caller must
** ensure that i is within range.
**
@@ -91269,11 +91112,13 @@
return pVector->x.pList->a[i].pExpr;
}
}
return pVector;
}
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) */
+#ifndef SQLITE_OMIT_SUBQUERY
/*
** Compute and return a new Expr object which when passed to
** sqlite3ExprCode() will generate all necessary code to compute
** the iField-th column of the vector expression pVector.
**
@@ -91327,10 +91172,11 @@
if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
pRet = sqlite3ExprDup(pParse->db, pVector, 0);
}
return pRet;
}
+#endif /* !define(SQLITE_OMIT_SUBQUERY) */
/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the
** sub-select returns more than one column, the first in an array
@@ -91842,11 +91688,11 @@
if( pExpr==0 ) return;
assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
- assert( n==(u32)sqlite3Strlen30(z) );
+ assert( n==sqlite3Strlen30(z) );
if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
x = (ynVar)(++pParse->nVar);
}else{
@@ -91924,11 +91770,11 @@
sqlite3ExprListDelete(db, p->x.pList);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
}
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
@@ -92191,15 +92037,19 @@
struct ExprList_item *pItem, *pOldItem;
int i;
Expr *pPriorSelectCol = 0;
assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db,
- sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
if( pNew==0 ) return 0;
- pNew->nAlloc = pNew->nExpr = p->nExpr;
- pItem = pNew->a;
+ pNew->nExpr = i = p->nExpr;
+ if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){}
+ pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) );
+ if( pItem==0 ){
+ sqlite3DbFree(db, pNew);
+ return 0;
+ }
pOldItem = p->a;
for(i=0; inExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
Expr *pNewExpr;
pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
@@ -92286,11 +92136,11 @@
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
if( pNew==0 ) return 0;
pNew->nId = p->nId;
pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ){
- sqlite3DbFreeNN(db, pNew);
+ sqlite3DbFree(db, pNew);
return 0;
}
/* Note that because the size of the allocation for p->a[] is not
** necessarily a power of two, sqlite3IdListAppend() may not be called
** on the duplicate created by this function. */
@@ -92357,33 +92207,35 @@
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
Expr *pExpr /* Expression to be appended. Might be NULL */
){
- struct ExprList_item *pItem;
sqlite3 *db = pParse->db;
assert( db!=0 );
if( pList==0 ){
pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) );
if( pList==0 ){
goto no_mem;
}
pList->nExpr = 0;
- pList->nAlloc = 1;
- }else if( pList->nExpr==pList->nAlloc ){
- ExprList *pNew;
- pNew = sqlite3DbRealloc(db, pList,
- sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
- if( pNew==0 ){
+ pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0]));
+ if( pList->a==0 ) goto no_mem;
+ }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
+ struct ExprList_item *a;
+ assert( pList->nExpr>0 );
+ a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
+ if( a==0 ){
goto no_mem;
}
- pList = pNew;
- pList->nAlloc *= 2;
+ pList->a = a;
}
- pItem = &pList->a[pList->nExpr++];
- memset(pItem, 0, sizeof(*pItem));
- pItem->pExpr = pExpr;
+ assert( pList->a!=0 );
+ if( 1 ){
+ struct ExprList_item *pItem = &pList->a[pList->nExpr++];
+ memset(pItem, 0, sizeof(*pItem));
+ pItem->pExpr = pExpr;
+ }
return pList;
no_mem:
/* Avoid leaking memory if malloc has failed. */
sqlite3ExprDelete(db, pExpr);
@@ -92436,23 +92288,24 @@
pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
pColumns->a[i].zName = 0;
}
}
- if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
- Expr *pFirst = pList->a[iFirst].pExpr;
- assert( pFirst!=0 );
- assert( pFirst->op==TK_SELECT_COLUMN );
-
- /* Store the SELECT statement in pRight so it will be deleted when
- ** sqlite3ExprListDelete() is called */
- pFirst->pRight = pExpr;
- pExpr = 0;
-
- /* Remember the size of the LHS in iTable so that we can check that
- ** the RHS and LHS sizes match during code generation. */
- pFirst->iTable = pColumns->nId;
+ if( pExpr->op==TK_SELECT ){
+ if( pList && pList->a[iFirst].pExpr ){
+ Expr *pFirst = pList->a[iFirst].pExpr;
+ assert( pFirst->op==TK_SELECT_COLUMN );
+
+ /* Store the SELECT statement in pRight so it will be deleted when
+ ** sqlite3ExprListDelete() is called */
+ pFirst->pRight = pExpr;
+ pExpr = 0;
+
+ /* Remember the size of the LHS in iTable so that we can check that
+ ** the RHS and LHS sizes match during code generation. */
+ pFirst->iTable = pColumns->nId;
+ }
}
vector_append_error:
sqlite3ExprDelete(db, pExpr);
sqlite3IdListDelete(db, pColumns);
@@ -92542,20 +92395,20 @@
/*
** Delete an entire expression list.
*/
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
- int i = pList->nExpr;
- struct ExprList_item *pItem = pList->a;
- assert( pList->nExpr>0 );
- do{
+ int i;
+ struct ExprList_item *pItem;
+ assert( pList->a!=0 || pList->nExpr==0 );
+ for(pItem=pList->a, i=0; inExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zSpan);
- pItem++;
- }while( --i>0 );
- sqlite3DbFreeNN(db, pList);
+ }
+ sqlite3DbFree(db, pList->a);
+ sqlite3DbFree(db, pList);
}
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
if( pList ) exprListDeleteNN(db, pList);
}
@@ -92630,16 +92483,14 @@
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
return WRC_Continue;
+ }else{
+ pWalker->eCode = 0;
+ return WRC_Abort;
}
- /* Fall through */
- case TK_IF_NULL_ROW:
- testcase( pExpr->op==TK_IF_NULL_ROW );
- pWalker->eCode = 0;
- return WRC_Abort;
case TK_VARIABLE:
if( pWalker->eCode==5 ){
/* Silently convert bound parameters that appear inside of CREATE
** statements into a NULL when parsing the CREATE statement text out
** of the sqlite_master table */
@@ -92703,69 +92554,10 @@
*/
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(p, 3, iCur);
}
-
-/*
-** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
-*/
-static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
- ExprList *pGroupBy = pWalker->u.pGroupBy;
- int i;
-
- /* Check if pExpr is identical to any GROUP BY term. If so, consider
- ** it constant. */
- for(i=0; inExpr; i++){
- Expr *p = pGroupBy->a[i].pExpr;
- if( sqlite3ExprCompare(pExpr, p, -1)<2 ){
- CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
- if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
- return WRC_Prune;
- }
- }
- }
-
- /* Check if pExpr is a sub-select. If so, consider it variable. */
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- pWalker->eCode = 0;
- return WRC_Abort;
- }
-
- return exprNodeIsConstant(pWalker, pExpr);
-}
-
-/*
-** Walk the expression tree passed as the first argument. Return non-zero
-** if the expression consists entirely of constants or copies of terms
-** in pGroupBy that sort with the BINARY collation sequence.
-**
-** This routine is used to determine if a term of the HAVING clause can
-** be promoted into the WHERE clause. In order for such a promotion to work,
-** the value of the HAVING clause term must be the same for all members of
-** a "group". The requirement that the GROUP BY term must be BINARY
-** assumes that no other collating sequence will have a finer-grained
-** grouping than binary. In other words (A=B COLLATE binary) implies
-** A=B in every other collating sequence. The requirement that the
-** GROUP BY be BINARY is stricter than necessary. It would also work
-** to promote HAVING clauses that use the same alternative collating
-** sequence as the GROUP BY term, but that is much harder to check,
-** alternative collating sequences are uncommon, and this is only an
-** optimization, so we take the easy way out and simply require the
-** GROUP BY to use the BINARY collating sequence.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.eCode = 1;
- w.xExprCallback = exprNodeIsConstantOrGroupBy;
- w.u.pGroupBy = pGroupBy;
- w.pParse = pParse;
- sqlite3WalkExpr(&w, p);
- return w.eCode;
-}
-
/*
** Walk an expression tree. Return non-zero if the expression is constant
** or a function call with constant arguments. Return and 0 if there
** are any variables.
**
@@ -94139,14 +93931,10 @@
Table *pTab, /* The table containing the value */
int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
int regOut /* Extract the value into this register */
){
- if( pTab==0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
- return;
- }
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
int x = iCol;
@@ -94299,15 +94087,11 @@
if( nResult==1 ){
iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
}else{
*piFreeable = 0;
if( p->op==TK_SELECT ){
-#if SQLITE_OMIT_SUBQUERY
- iResult = 0;
-#else
iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
-#endif
}else{
int i;
iResult = pParse->nMem+1;
pParse->nMem += nResult;
for(i=0; iiTable);
- sqlite3ExprCachePush(pParse);
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- sqlite3ExprCachePop(pParse);
- sqlite3VdbeJumpHere(v, addrINR);
- sqlite3VdbeChangeP3(v, addrINR, inReg);
- break;
- }
-
/*
** Form A:
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
**
** Form B:
@@ -99628,22 +99401,10 @@
}
if( db->xAuth==0 ){
return SQLITE_OK;
}
-
- /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
- ** callback are either NULL pointers or zero-terminated strings that
- ** contain additional details about the action to be authorized.
- **
- ** The following testcase() macros show that any of the 3rd through 6th
- ** parameters can be either NULL or a string. */
- testcase( zArg1==0 );
- testcase( zArg2==0 );
- testcase( zArg3==0 );
- testcase( pParse->zAuthContext==0 );
-
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
#endif
);
@@ -103311,11 +103072,11 @@
if( pList==0 ) return;
for(i=0; inId; i++){
sqlite3DbFree(db, pList->a[i].zName);
}
sqlite3DbFree(db, pList->a);
- sqlite3DbFreeNN(db, pList);
+ sqlite3DbFree(db, pList);
}
/*
** Return the index in pList of the identifier named zId. Return -1
** if not found.
@@ -103501,11 +103262,11 @@
sqlite3DeleteTable(db, pItem->pTab);
sqlite3SelectDelete(db, pItem->pSelect);
sqlite3ExprDelete(db, pItem->pOn);
sqlite3IdListDelete(db, pItem->pUsing);
}
- sqlite3DbFreeNN(db, pList);
+ sqlite3DbFree(db, pList);
}
/*
** This routine is called by the parser to add a new term to the
** end of a growing FROM clause. The "p" parameter is the part of
@@ -104975,18 +104736,11 @@
#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
/* Special case: A DELETE without a WHERE clause deletes everything.
** It is easier just to erase the whole table. Prior to version 3.6.5,
** this optimization caused the row change count (the value returned by
- ** API function sqlite3_count_changes) to be set incorrectly.
- **
- ** The "rcauth==SQLITE_OK" terms is the
- ** IMPLEMENATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
- ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
- ** the truncate optimization is disabled and all rows are deleted
- ** individually.
- */
+ ** API function sqlite3_count_changes) to be set incorrectly. */
if( rcauth==SQLITE_OK
&& pWhere==0
&& !bComplex
&& !IsVirtual(pTab)
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -108492,57 +108246,42 @@
** entry in the aChange[] array is set to -1. If the column is modified,
** the value is 0 or greater. Parameter chngRowid is set to true if the
** UPDATE statement modifies the rowid fields of the table.
**
** If any foreign key processing will be required, this function returns
-** non-zero. If there is no foreign key related processing, this function
-** returns zero.
-**
-** For an UPDATE, this function returns 2 if:
-**
-** * There are any FKs for which pTab is the child and the parent table, or
-** * the UPDATE modifies one or more parent keys for which the action is
-** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
-**
-** Or, assuming some other foreign key processing is required, 1.
+** true. If there is no foreign key related processing, this function
+** returns false.
*/
SQLITE_PRIVATE int sqlite3FkRequired(
Parse *pParse, /* Parse context */
Table *pTab, /* Table being modified */
int *aChange, /* Non-NULL for UPDATE operations */
int chngRowid /* True for UPDATE that affects rowid */
){
- int eRet = 0;
if( pParse->db->flags&SQLITE_ForeignKeys ){
if( !aChange ){
/* A DELETE operation. Foreign key processing is required if the
** table in question is either the child or parent table for any
** foreign key constraint. */
- eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
+ return (sqlite3FkReferences(pTab) || pTab->pFKey);
}else{
/* This is an UPDATE. Foreign key processing is only required if the
** operation modifies one or more child or parent key columns. */
FKey *p;
/* Check if any child key columns are being modified. */
for(p=pTab->pFKey; p; p=p->pNextFrom){
- if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
- if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
- eRet = 1;
- }
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
}
/* Check if any parent key columns are being modified. */
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
- if( p->aAction[1]!=OE_None ) return 2;
- eRet = 1;
- }
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
}
}
}
- return eRet;
+ return 0;
}
/*
** This function is called when an UPDATE or DELETE operation is being
** compiled on table pTab, which is the parent table of foreign-key pFKey.
@@ -113048,11 +112787,11 @@
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "optimize",
/* ePragTyp: */ PragTyp_OPTIMIZE,
- /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
+ /* ePragFlg: */ PragFlg_Result1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "page_count",
/* ePragTyp: */ PragTyp_PAGE_COUNT,
@@ -114548,41 +114287,37 @@
if( pParent ){
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
assert( x==0 );
}
addrOk = sqlite3VdbeMakeLabel(v);
-
- /* Generate code to read the child key values into registers
- ** regRow..regRow+n. If any of the child key values are NULL, this
- ** row cannot cause an FK violation. Jump directly to addrOk in
- ** this case. */
- for(j=0; jnCol; j++){
- int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
- sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
- }
-
- /* Generate code to query the parent index for a matching parent
- ** key. If a match is found, jump to addrOk. */
- if( pIdx ){
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
- sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
- sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
- VdbeCoverage(v);
- }else if( pParent ){
- int jmp = sqlite3VdbeCurrentAddr(v)+2;
- sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
+ if( pParent && pIdx==0 ){
+ int iKey = pFK->aCol[0].iFrom;
+ assert( iKey>=0 && iKeynCol );
+ if( iKey!=pTab->iPKey ){
+ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
+ sqlite3ColumnDefault(v, pTab, iKey, regRow);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
+ }
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
sqlite3VdbeGoto(v, addrOk);
- assert( pFK->nCol==1 );
- }
-
- /* Generate code to report an FK violation to the caller. */
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
- }
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ }else{
+ for(j=0; jnCol; j++){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
+ aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+ }
+ if( pParent ){
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
sqlite3VdbeResolveLabel(v, addrOk);
sqlite3DbFree(db, aiCols);
}
@@ -114764,32 +114499,29 @@
integrityCheckResultRow(v, 3);
sqlite3VdbeJumpHere(v, jmp2);
}
/* Verify CHECK constraints */
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
- ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
- if( db->mallocFailed==0 ){
- int addrCkFault = sqlite3VdbeMakeLabel(v);
- int addrCkOk = sqlite3VdbeMakeLabel(v);
- char *zErr;
- int k;
- pParse->iSelfTab = iDataCur;
- sqlite3ExprCachePush(pParse);
- for(k=pCheck->nExpr-1; k>0; k--){
- sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
- }
- sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
- SQLITE_JUMPIFNULL);
- sqlite3VdbeResolveLabel(v, addrCkFault);
- zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
- pTab->zName);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- integrityCheckResultRow(v, 3);
- sqlite3VdbeResolveLabel(v, addrCkOk);
- sqlite3ExprCachePop(pParse);
- }
- sqlite3ExprListDelete(db, pCheck);
+ int addrCkFault = sqlite3VdbeMakeLabel(v);
+ int addrCkOk = sqlite3VdbeMakeLabel(v);
+ ExprList *pCheck = pTab->pCheck;
+ char *zErr;
+ int k;
+ pParse->iSelfTab = iDataCur;
+ sqlite3ExprCachePush(pParse);
+ for(k=pCheck->nExpr-1; k>0; k--){
+ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+ }
+ sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
+ SQLITE_JUMPIFNULL);
+ sqlite3VdbeResolveLabel(v, addrCkFault);
+ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
+ pTab->zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ integrityCheckResultRow(v, 3);
+ sqlite3VdbeResolveLabel(v, addrCkOk);
+ sqlite3ExprCachePop(pParse);
}
/* Validate index entries for the current row */
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
int ckUniq = sqlite3VdbeMakeLabel(v);
@@ -116589,11 +116321,11 @@
sqlite3ExprDelete(db, p->pHaving);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
sqlite3ExprDelete(db, p->pOffset);
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
- if( bFree ) sqlite3DbFreeNN(db, p);
+ if( bFree ) sqlite3DbFree(db, p);
p = pPrior;
bFree = 1;
}
}
@@ -116625,17 +116357,18 @@
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
Select *pNew;
Select standin;
- pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
+ sqlite3 *db = pParse->db;
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
if( pNew==0 ){
- assert( pParse->db->mallocFailed );
+ assert( db->mallocFailed );
pNew = &standin;
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
}
pNew->pEList = pEList;
pNew->op = TK_SELECT;
pNew->selFlags = selFlags;
pNew->iLimit = 0;
@@ -116644,11 +116377,11 @@
pNew->zSelName[0] = 0;
#endif
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = 0;
- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
pNew->pGroupBy = pGroupBy;
pNew->pHaving = pHaving;
pNew->pOrderBy = pOrderBy;
@@ -116655,13 +116388,13 @@
pNew->pPrior = 0;
pNew->pNext = 0;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
pNew->pWith = 0;
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
- if( pParse->db->mallocFailed ) {
- clearSelect(pParse->db, pNew, pNew!=&standin);
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
+ if( db->mallocFailed ) {
+ clearSelect(db, pNew, pNew!=&standin);
pNew = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
}
assert( pNew!=&standin );
@@ -117567,11 +117300,11 @@
*/
SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
if( p ){
assert( p->nRef>0 );
p->nRef--;
- if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
+ if( p->nRef==0 ) sqlite3DbFree(p->db, p);
}
}
/*
** Make a new pointer to a KeyInfo object
@@ -118042,11 +117775,10 @@
Vdbe *v = pParse->pVdbe;
int i;
NameContext sNC;
sNC.pSrcList = pTabList;
sNC.pParse = pParse;
- sNC.pNext = 0;
for(i=0; inExpr; i++){
Expr *p = pEList->a[i].pExpr;
const char *zType;
#ifdef SQLITE_ENABLE_COLUMN_METADATA
const char *zOrigDb = 0;
@@ -118066,23 +117798,10 @@
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
-
-/*
-** Return the Table objecct in the SrcList that has cursor iCursor.
-** Or return NULL if no such Table object exists in the SrcList.
-*/
-static Table *tableWithCursor(SrcList *pList, int iCursor){
- int j;
- for(j=0; jnSrc; j++){
- if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
- }
- return 0;
-}
-
/*
** Generate code that will tell the VDBE the names of columns
** in the result set. This information is used to provide the
** azCol[] values in the callback.
@@ -118091,12 +117810,11 @@
Parse *pParse, /* Parser context */
SrcList *pTabList, /* List of tables */
ExprList *pEList /* Expressions defining the result set */
){
Vdbe *v = pParse->pVdbe;
- int i;
- Table *pTab;
+ int i, j;
sqlite3 *db = pParse->db;
int fullNames, shortNames;
#ifndef SQLITE_OMIT_EXPLAIN
/* If this is an EXPLAIN, skip this step */
@@ -118117,15 +117835,19 @@
p = pEList->a[i].pExpr;
if( NEVER(p==0) ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
- && (pTab = tableWithCursor(pTabList, p->iTable))!=0
- ){
+ }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
+ Table *pTab;
char *zCol;
int iCol = p->iColumn;
+ for(j=0; ALWAYS(jnSrc); j++){
+ if( pTabList->a[j].iCursor==p->iTable ) break;
+ }
+ assert( jnSrc );
+ pTab = pTabList->a[j].pTab;
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iColnCol) );
if( iCol<0 ){
zCol = "rowid";
}else{
@@ -118203,11 +117925,11 @@
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ){
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
- if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
+ if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
pTab = pColExpr->pTab;
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
@@ -119423,11 +119145,11 @@
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
- p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+ pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
}
@@ -119657,28 +119379,13 @@
return pParse->nErr!=0;
}
#endif
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-
-/* An instance of the SubstContext object describes an substitution edit
-** to be performed on a parse tree.
-**
-** All references to columns in table iTable are to be replaced by corresponding
-** expressions in pEList.
-*/
-typedef struct SubstContext {
- Parse *pParse; /* The parsing context */
- int iTable; /* Replace references to this table */
- int iNewTable; /* New table number */
- int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
- ExprList *pEList; /* Replacement expressions */
-} SubstContext;
-
/* Forward Declarations */
-static void substExprList(SubstContext*, ExprList*);
-static void substSelect(SubstContext*, Select*, int);
+static void substExprList(Parse*, ExprList*, int, ExprList*);
+static void substSelect(Parse*, Select *, int, ExprList*, int);
/*
** Scan through the expression pExpr. Replace every reference to
** a column in table number iTable with a copy of the iColumn-th
** entry in pEList. (But leave references to the ROWID column
@@ -119685,42 +119392,33 @@
** unchanged.)
**
** This routine is part of the flattening procedure. A subquery
** whose result set is defined by pEList appears as entry in the
** FROM clause of a SELECT such that the VDBE cursor assigned to that
-** FORM clause entry is iTable. This routine makes the necessary
+** FORM clause entry is iTable. This routine make the necessary
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
static Expr *substExpr(
- SubstContext *pSubst, /* Description of the substitution */
- Expr *pExpr /* Expr in which substitution occurs */
+ Parse *pParse, /* Report errors here */
+ Expr *pExpr, /* Expr in which substitution occurs */
+ int iTable, /* Table to be substituted */
+ ExprList *pEList /* Substitute expressions */
){
+ sqlite3 *db = pParse->db;
if( pExpr==0 ) return 0;
- if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
- pExpr->iRightJoinTable = pSubst->iNewTable;
- }
- if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
- Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
- Expr ifNullRow;
- assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr );
+ Expr *pCopy = pEList->a[pExpr->iColumn].pExpr;
+ assert( pEList!=0 && pExpr->iColumnnExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
if( sqlite3ExprIsVector(pCopy) ){
- sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
+ sqlite3VectorErrorMsg(pParse, pCopy);
}else{
- sqlite3 *db = pSubst->pParse->db;
- if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
- memset(&ifNullRow, 0, sizeof(ifNullRow));
- ifNullRow.op = TK_IF_NULL_ROW;
- ifNullRow.pLeft = pCopy;
- ifNullRow.iTable = pSubst->iNewTable;
- pCopy = &ifNullRow;
- }
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && (pExpr->flags & EP_FromJoin) ){
pNew->iRightJoinTable = pExpr->iRightJoinTable;
pNew->flags |= EP_FromJoin;
}
@@ -119727,54 +119425,55 @@
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
}
}else{
- if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
- pExpr->iTable = pSubst->iNewTable;
- }
- pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
- pExpr->pRight = substExpr(pSubst, pExpr->pRight);
+ pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList);
+ pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- substSelect(pSubst, pExpr->x.pSelect, 1);
+ substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1);
}else{
- substExprList(pSubst, pExpr->x.pList);
+ substExprList(pParse, pExpr->x.pList, iTable, pEList);
}
}
return pExpr;
}
static void substExprList(
- SubstContext *pSubst, /* Description of the substitution */
- ExprList *pList /* List to scan and in which to make substitutes */
+ Parse *pParse, /* Report errors here */
+ ExprList *pList, /* List to scan and in which to make substitutes */
+ int iTable, /* Table to be substituted */
+ ExprList *pEList /* Substitute values */
){
int i;
if( pList==0 ) return;
for(i=0; inExpr; i++){
- pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
+ pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList);
}
}
static void substSelect(
- SubstContext *pSubst, /* Description of the substitution */
- Select *p, /* SELECT statement in which to make substitutions */
- int doPrior /* Do substitutes on p->pPrior too */
+ Parse *pParse, /* Report errors here */
+ Select *p, /* SELECT statement in which to make substitutions */
+ int iTable, /* Table to be replaced */
+ ExprList *pEList, /* Substitute values */
+ int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
struct SrcList_item *pItem;
int i;
if( !p ) return;
do{
- substExprList(pSubst, p->pEList);
- substExprList(pSubst, p->pGroupBy);
- substExprList(pSubst, p->pOrderBy);
- p->pHaving = substExpr(pSubst, p->pHaving);
- p->pWhere = substExpr(pSubst, p->pWhere);
+ substExprList(pParse, p->pEList, iTable, pEList);
+ substExprList(pParse, p->pGroupBy, iTable, pEList);
+ substExprList(pParse, p->pOrderBy, iTable, pEList);
+ p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList);
+ p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(pSubst, pItem->pSelect, 1);
+ substSelect(pParse, pItem->pSelect, iTable, pEList, 1);
if( pItem->fg.isTabFunc ){
- substExprList(pSubst, pItem->u1.pFuncArg);
+ substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList);
}
}
}while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
@@ -119813,13 +119512,12 @@
** (2) The subquery is not an aggregate or (2a) the outer query is not a join
** and (2b) the outer query does not use subqueries other than the one
** FROM-clause subquery that is a candidate for flattening. (2b is
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
**
-** (3) The subquery is not the right operand of a LEFT JOIN
-** or the subquery is not itself a join and the outer query is not
-** an aggregate.
+** (3) The subquery is not the right operand of a left outer join
+** (Originally ticket #306. Strengthened by ticket #3300)
**
** (4) The subquery is not DISTINCT.
**
** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
** sub-queries that were excluded from this optimization. Restriction
@@ -119827,11 +119525,11 @@
**
** (6) The subquery does not use aggregates or the outer query is not
** DISTINCT.
**
** (7) The subquery has a FROM clause. TODO: For subqueries without
-** A FROM clause, consider adding a FROM clause with the special
+** A FROM clause, consider adding a FROM close with the special
** table sqlite_once that consists of a single row containing a
** single NULL.
**
** (8) The subquery does not use LIMIT or the outer query is not a join.
**
@@ -119933,12 +119631,10 @@
Select *pSub1; /* Pointer to the rightmost select in sub-query */
SrcList *pSrc; /* The FROM clause of the outer query */
SrcList *pSubSrc; /* The FROM clause of the subquery */
ExprList *pList; /* The result set of the outer query */
int iParent; /* VDBE cursor number of the pSub result set temp table */
- int iNewParent = -1;/* Replacement table for iParent */
- int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
int i; /* Loop counter */
Expr *pWhere; /* The WHERE clause */
struct SrcList_item *pSubitem; /* The subquery */
sqlite3 *db = pParse->db;
@@ -119961,11 +119657,11 @@
|| (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
){
return 0; /* Restriction (2b) */
}
}
-
+
pSubSrc = pSub->pSrc;
assert( pSubSrc );
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
** because they could be computed at compile-time. But when LIMIT and OFFSET
@@ -119999,43 +119695,45 @@
}
if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
return 0; /* Restriction (23) */
}
- /*
- ** If the subquery is the right operand of a LEFT JOIN, then the
- ** subquery may not be a join itself. Example of why this is not allowed:
+ /* OBSOLETE COMMENT 1:
+ ** Restriction 3: If the subquery is a join, make sure the subquery is
+ ** not used as the right operand of an outer join. Examples of why this
+ ** is not allowed:
**
** t1 LEFT OUTER JOIN (t2 JOIN t3)
**
** If we flatten the above, we would get
**
** (t1 LEFT OUTER JOIN t2) JOIN t3
**
** which is not at all the same thing.
**
- ** If the subquery is the right operand of a LEFT JOIN, then the outer
- ** query cannot be an aggregate. This is an artifact of the way aggregates
- ** are processed - there is not mechanism to determine if the LEFT JOIN
- ** table should be all-NULL.
+ ** OBSOLETE COMMENT 2:
+ ** Restriction 12: If the subquery is the right operand of a left outer
+ ** join, make sure the subquery has no WHERE clause.
+ ** An examples of why this is not allowed:
**
- ** See also tickets #306, #350, and #3300.
+ ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
+ **
+ ** But the t2.x>0 test will always fail on a NULL row of t2, which
+ ** effectively converts the OUTER JOIN into an INNER JOIN.
+ **
+ ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
+ ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
+ ** is fraught with danger. Best to avoid the whole thing. If the
+ ** subquery is the right term of a LEFT JOIN, then do not flatten.
*/
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
- isLeftJoin = 1;
- if( pSubSrc->nSrc>1 || isAgg ){
- return 0; /* Restriction (3) */
- }
- }
-#ifdef SQLITE_EXTRA_IFNULLROW
- else if( iFrom>0 && !isAgg ){
- /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
- ** every reference to any result column from subquery in a join, even though
- ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */
- isLeftJoin = -1;
- }
-#endif
+ return 0;
+ }
/* Restriction 17: If the sub-query is a compound SELECT, then it must
** use only the UNION ALL operator. And none of the simple select queries
** that make up the compound SELECT are allowed to be aggregate or distinct
** queries.
@@ -120239,11 +119937,10 @@
*/
for(i=0; ia[i+iFrom].pUsing);
assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
pSrc->a[i+iFrom] = pSubSrc->a[i];
- iNewParent = pSubSrc->a[i].iCursor;
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
pSrc->a[iFrom].fg.jointype = jointype;
/* Now begin substituting subquery result set expressions for
@@ -120285,13 +119982,10 @@
assert( pSub->pPrior==0 );
pParent->pOrderBy = pOrderBy;
pSub->pOrderBy = 0;
}
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
- if( isLeftJoin>0 ){
- setJoinExpr(pWhere, iNewParent);
- }
if( subqueryIsAgg ){
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
pParent->pHaving = sqlite3ExprAnd(db,
@@ -120301,17 +119995,11 @@
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
}
if( db->mallocFailed==0 ){
- SubstContext x;
- x.pParse = pParse;
- x.iTable = iParent;
- x.iNewTable = iNewParent;
- x.isLeftJoin = isLeftJoin;
- x.pEList = pSub->pEList;
- substSelect(&x, pParent, 0);
+ substSelect(pParse, pParent, iParent, pSub->pEList, 0);
}
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
*/
@@ -120410,18 +120098,12 @@
}
if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
- SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
- x.pParse = pParse;
- x.iTable = iCursor;
- x.iNewTable = iCursor;
- x.isLeftJoin = 0;
- x.pEList = pSubq->pEList;
- pNew = substExpr(&x, pNew);
+ pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList);
pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
pSubq = pSubq->pPrior;
}
}
return nChng;
@@ -121409,107 +121091,10 @@
}
#else
# define explainSimpleCount(a,b,c)
#endif
-/*
-** Context object for havingToWhereExprCb().
-*/
-struct HavingToWhereCtx {
- Expr **ppWhere;
- ExprList *pGroupBy;
-};
-
-/*
-** sqlite3WalkExpr() callback used by havingToWhere().
-**
-** If the node passed to the callback is a TK_AND node, return
-** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
-**
-** Otherwise, return WRC_Prune. In this case, also check if the
-** sub-expression matches the criteria for being moved to the WHERE
-** clause. If so, add it to the WHERE clause and replace the sub-expression
-** within the HAVING expression with a constant "1".
-*/
-static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
- if( pExpr->op!=TK_AND ){
- struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
- if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
- sqlite3 *db = pWalker->pParse->db;
- Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
- if( pNew ){
- Expr *pWhere = *(p->ppWhere);
- SWAP(Expr, *pNew, *pExpr);
- pNew = sqlite3ExprAnd(db, pWhere, pNew);
- *(p->ppWhere) = pNew;
- }
- }
- return WRC_Prune;
- }
- return WRC_Continue;
-}
-
-/*
-** Transfer eligible terms from the HAVING clause of a query, which is
-** processed after grouping, to the WHERE clause, which is processed before
-** grouping. For example, the query:
-**
-** SELECT * FROM WHERE a=? GROUP BY b HAVING b=? AND c=?
-**
-** can be rewritten as:
-**
-** SELECT * FROM WHERE a=? AND b=? GROUP BY b HAVING c=?
-**
-** A term of the HAVING expression is eligible for transfer if it consists
-** entirely of constants and expressions that are also GROUP BY terms that
-** use the "BINARY" collation sequence.
-*/
-static void havingToWhere(
- Parse *pParse,
- ExprList *pGroupBy,
- Expr *pHaving,
- Expr **ppWhere
-){
- struct HavingToWhereCtx sCtx;
- Walker sWalker;
-
- sCtx.ppWhere = ppWhere;
- sCtx.pGroupBy = pGroupBy;
-
- memset(&sWalker, 0, sizeof(sWalker));
- sWalker.pParse = pParse;
- sWalker.xExprCallback = havingToWhereExprCb;
- sWalker.u.pHavingCtx = &sCtx;
- sqlite3WalkExpr(&sWalker, pHaving);
-}
-
-/*
-** Check to see if the pThis entry of pTabList is a self-join of a prior view.
-** If it is, then return the SrcList_item for the prior view. If it is not,
-** then return 0.
-*/
-static struct SrcList_item *isSelfJoinView(
- SrcList *pTabList, /* Search for self-joins in this FROM clause */
- struct SrcList_item *pThis /* Search for prior reference to this subquery */
-){
- struct SrcList_item *pItem;
- for(pItem = pTabList->a; pItempSelect==0 ) continue;
- if( pItem->fg.viaCoroutine ) continue;
- if( pItem->zName==0 ) continue;
- if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
- if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
- if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){
- /* The view was modified by some other optimization such as
- ** pushDownWhereTerms() */
- continue;
- }
- return pItem;
- }
- return 0;
-}
-
/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
@@ -121645,42 +121230,17 @@
#endif
return rc;
}
#endif
- /* For each term in the FROM clause, do two things:
- ** (1) Authorized unreferenced tables
- ** (2) Generate code for all sub-queries
+ /* Generate code for all sub-queries in the FROM clause
*/
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; inSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
- Select *pSub;
-
- /* Issue SQLITE_READ authorizations with a fake column name for any tables that
- ** are referenced but from which no values are extracted. Examples of where these
- ** kinds of null SQLITE_READ authorizations would occur:
- **
- ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
- ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2.""
- **
- ** The fake column name is an empty string. It is possible for a table to
- ** have a column named by the empty string, in which case there is no way to
- ** distinguish between an unreferenced table and an actual reference to the
- ** "" column. The original design was for the fake column name to be a NULL,
- ** which would be unambiguous. But legacy authorization callbacks might
- ** assume the column name is non-NULL and segfault. The use of an empty string
- ** for the fake column name seems safer.
- */
- if( pItem->colUsed==0 ){
- sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
- }
-
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
- /* Generate code for all sub-queries in the FROM clause
- */
- pSub = pItem->pSelect;
+ Select *pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
** for example. In that case, do not regenerate the code to manifest
@@ -121687,14 +121247,10 @@
** a view or the co-routine to implement a view. The first instance
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
if( pItem->fg.viaCoroutine==0 ){
- /* The subroutine that manifests the view might be a one-time routine,
- ** or it might need to be rerun on each iteration because it
- ** encodes a correlated subquery. */
- testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
}
@@ -121765,12 +121321,10 @@
** is a register allocated to hold the subroutine return address
*/
int topAddr;
int onceAddr = 0;
int retAddr;
- struct SrcList_item *pPrior;
-
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
if( pItem->fg.isCorrelated==0 ){
@@ -121780,29 +121334,24 @@
onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
- pPrior = isSelfJoinView(pTabList, pItem);
- if( pPrior ){
- sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
- }else{
- sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
- sqlite3Select(pParse, pSub, &dest);
- }
+ sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+ explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
sqlite3VdbeChangeP1(v, topAddr, retAddr);
sqlite3ClearTempRegCache(pParse);
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
+ }
#endif
- }
/* Various elements of the SELECT copied into local variables for
** convenience */
pEList = p->pEList;
pWhere = p->pWhere;
@@ -122006,15 +121555,10 @@
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
- if( pGroupBy ){
- assert( pWhere==p->pWhere );
- havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
- pWhere = p->pWhere;
- }
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; ipIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
+ if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; inKeyCol; i++){
@@ -124378,11 +123922,11 @@
** is the column index supplied by the user.
*/
assert( regNew==regNewRowid+1 );
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
- OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
+ OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
regNewRowid
);
if( eOnePass==ONEPASS_MULTI ){
assert( hasFK==0 && chngKey==0 );
sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
@@ -124389,11 +123933,11 @@
}
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
#else
- if( hasFK>1 || chngKey ){
+ if( hasFK || chngKey ){
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
#endif
if( bReplace || chngKey ){
sqlite3VdbeJumpHere(v, addr1);
@@ -126032,11 +125576,11 @@
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
- if( pTab==0 ) return pDef;
+ if( NEVER(pTab==0) ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
pMod = (sqlite3_module *)pVtab->pModule;
@@ -126367,11 +125911,10 @@
union {
struct { /* Information for internal btree tables */
u16 nEq; /* Number of equality constraints */
u16 nBtm; /* Size of BTM vector */
u16 nTop; /* Size of TOP vector */
- u16 nIdxCol; /* Index column used for ORDER BY */
Index *pIndex; /* Index used, or NULL */
} btree;
struct { /* Information for virtual tables */
int idxNum; /* Index number */
u8 needFree; /* True if sqlite3_free(idxStr) is needed */
@@ -126661,11 +126204,10 @@
struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
ExprList *pResultSet; /* Result set of the query */
- Expr *pWhere; /* The complete WHERE clause */
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
@@ -127822,73 +127364,10 @@
assert( nReg==1 );
sqlite3ExprCode(pParse, p, iReg);
}
}
-/* An instance of the IdxExprTrans object carries information about a
-** mapping from an expression on table columns into a column in an index
-** down through the Walker.
-*/
-typedef struct IdxExprTrans {
- Expr *pIdxExpr; /* The index expression */
- int iTabCur; /* The cursor of the corresponding table */
- int iIdxCur; /* The cursor for the index */
- int iIdxCol; /* The column for the index */
-} IdxExprTrans;
-
-/* The walker node callback used to transform matching expressions into
-** a reference to an index column for an index on an expression.
-**
-** If pExpr matches, then transform it into a reference to the index column
-** that contains the value of pExpr.
-*/
-static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
- IdxExprTrans *pX = p->u.pIdxTrans;
- if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
- pExpr->op = TK_COLUMN;
- pExpr->iTable = pX->iIdxCur;
- pExpr->iColumn = pX->iIdxCol;
- pExpr->pTab = 0;
- return WRC_Prune;
- }else{
- return WRC_Continue;
- }
-}
-
-/*
-** For an indexes on expression X, locate every instance of expression X in pExpr
-** and change that subexpression into a reference to the appropriate column of
-** the index.
-*/
-static void whereIndexExprTrans(
- Index *pIdx, /* The Index */
- int iTabCur, /* Cursor of the table that is being indexed */
- int iIdxCur, /* Cursor of the index itself */
- WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
-){
- int iIdxCol; /* Column number of the index */
- ExprList *aColExpr; /* Expressions that are indexed */
- Walker w;
- IdxExprTrans x;
- aColExpr = pIdx->aColExpr;
- if( aColExpr==0 ) return; /* Not an index on expressions */
- memset(&w, 0, sizeof(w));
- w.xExprCallback = whereIndexExprTransNode;
- w.u.pIdxTrans = &x;
- x.iTabCur = iTabCur;
- x.iIdxCur = iIdxCur;
- for(iIdxCol=0; iIdxColnExpr; iIdxCol++){
- if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
- assert( aColExpr->a[iIdxCol].pExpr!=0 );
- x.iIdxCol = iIdxCol;
- x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
- sqlite3WalkExpr(&w, pWInfo->pWhere);
- sqlite3WalkExprList(&w, pWInfo->pOrderBy);
- sqlite3WalkExprList(&w, pWInfo->pResultSet);
- }
-}
-
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
@@ -127912,12 +127391,10 @@
int addrBrk; /* Jump here to break out of the loop */
int addrHalt; /* addrBrk for the outermost loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
- Index *pIdx = 0; /* Index used by loop (if any) */
- int loopAgain; /* True if constraint generator loop should repeat */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
pWC = &pWInfo->sWC;
db = pParse->db;
@@ -128239,10 +127716,11 @@
WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
int startEq; /* True if range start uses ==, >= or <= */
int endEq; /* True if range end uses ==, >= or <= */
int start_constraints; /* Start of range is constrained */
int nConstraint; /* Number of constraint terms */
+ Index *pIdx; /* The index we will be using */
int iIdxCur; /* The VDBE cursor for the index */
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
char *zEndAff = 0; /* Affinity for end of range constraint */
@@ -128466,17 +127944,10 @@
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
}
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
-
- /* If pIdx is an index on one or more expressions, then look through
- ** all the expressions in pWInfo and try to transform matching expressions
- ** into reference to index columns.
- */
- whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
-
/* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
}else if( bRev ){
@@ -128489,11 +127960,10 @@
if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}else{
assert( pLevel->p5==0 );
}
- if( omitTable ) pIdx = 0;
}else
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
if( pLoop->wsFlags & WHERE_MULTI_OR ){
/* Case 5: Two or more separately indexed terms connected by OR
@@ -128807,60 +128277,47 @@
pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
#endif
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
- **
- ** This loop may run either once (pIdx==0) or twice (pIdx!=0). If
- ** it is run twice, then the first iteration codes those sub-expressions
- ** that can be computed using columns from pIdx only (without seeking
- ** the main table cursor).
*/
- do{
- loopAgain = 0;
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
- int skipLikeAddr = 0;
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
- testcase( pWInfo->untestedTerms==0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
- pWInfo->untestedTerms = 1;
- continue;
- }
- pE = pTerm->pExpr;
- assert( pE!=0 );
- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
- continue;
- }
- if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
- loopAgain = 1;
- continue;
- }
- if( pTerm->wtFlags & TERM_LIKECOND ){
- /* If the TERM_LIKECOND flag is set, that means that the range search
- ** is sufficient to guarantee that the LIKE operator is true, so we
- ** can skip the call to the like(A,B) function. But this only works
- ** for strings. So do not skip the call to the function on the pass
- ** that compares BLOBs. */
+ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+ Expr *pE;
+ int skipLikeAddr = 0;
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ testcase( pTerm->wtFlags & TERM_CODED );
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+ testcase( pWInfo->untestedTerms==0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
+ pWInfo->untestedTerms = 1;
+ continue;
+ }
+ pE = pTerm->pExpr;
+ assert( pE!=0 );
+ if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
+ continue;
+ }
+ if( pTerm->wtFlags & TERM_LIKECOND ){
+ /* If the TERM_LIKECOND flag is set, that means that the range search
+ ** is sufficient to guarantee that the LIKE operator is true, so we
+ ** can skip the call to the like(A,B) function. But this only works
+ ** for strings. So do not skip the call to the function on the pass
+ ** that compares BLOBs. */
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- continue;
+ continue;
#else
- u32 x = pLevel->iLikeRepCntr;
- assert( x>0 );
- skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
- VdbeCoverage(v);
+ u32 x = pLevel->iLikeRepCntr;
+ assert( x>0 );
+ skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1));
+ VdbeCoverage(v);
#endif
- }
- sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
- pTerm->wtFlags |= TERM_CODED;
}
- pIdx = 0;
- }while( loopAgain );
+ sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+ if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+ pTerm->wtFlags |= TERM_CODED;
+ }
/* Insert code to test for implied constraints based on transitivity
** of the "==" operator.
**
** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
@@ -129749,50 +129206,31 @@
/*
** Expression pExpr is one operand of a comparison operator that might
** be useful for indexing. This routine checks to see if pExpr appears
** in any index. Return TRUE (1) if pExpr is an indexed term and return
-** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
-** number of the table that is indexed and aiCurCol[1] to the column number
+** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
+** number of the table that is indexed and *piColumn to the column number
** of the column that is indexed, or XN_EXPR (-2) if an expression is being
** indexed.
**
** If pExpr is a TK_COLUMN column reference, then this routine always returns
** true even if that particular column is not indexed, because the column
** might be added to an automatic index later.
*/
-static SQLITE_NOINLINE int exprMightBeIndexed2(
+static int exprMightBeIndexed(
SrcList *pFrom, /* The FROM clause */
+ int op, /* The specific comparison operator */
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- int *aiCurCol, /* Write the referenced table cursor and column here */
- Expr *pExpr /* An operand of a comparison operator */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int *piCur, /* Write the referenced table cursor number here */
+ int *piColumn /* Write the referenced table column number here */
){
Index *pIdx;
int i;
int iCur;
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
- iCur = pFrom->a[i].iCursor;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->aColExpr==0 ) continue;
- for(i=0; inKeyCol; i++){
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
- if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
- aiCurCol[0] = iCur;
- aiCurCol[1] = XN_EXPR;
- return 1;
- }
- }
- }
- return 0;
-}
-static int exprMightBeIndexed(
- SrcList *pFrom, /* The FROM clause */
- Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- int *aiCurCol, /* Write the referenced table cursor & column here */
- Expr *pExpr, /* An operand of a comparison operator */
- int op /* The specific comparison operator */
-){
+
/* If this expression is a vector to the left or right of a
** inequality constraint (>, <, >= or <=), perform the processing
** on the first element of the vector. */
assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
pExpr = pExpr->x.pList->a[0].pExpr;
}
if( pExpr->op==TK_COLUMN ){
- aiCurCol[0] = pExpr->iTable;
- aiCurCol[1] = pExpr->iColumn;
+ *piCur = pExpr->iTable;
+ *piColumn = pExpr->iColumn;
return 1;
}
if( mPrereq==0 ) return 0; /* No table references */
if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
- return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; inKeyCol; i++){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ *piCur = iCur;
+ *piColumn = XN_EXPR;
+ return 1;
+ }
+ }
+ }
+ return 0;
}
/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in. The job of this routine is to analyze the
@@ -129886,11 +129337,11 @@
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
- int aiCurCol[2];
+ int iCur, iColumn;
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
if( pTerm->iField>0 ){
@@ -129897,18 +129348,18 @@
assert( op==TK_IN );
assert( pLeft->op==TK_VECTOR );
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
}
- if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
- pTerm->leftCursor = aiCurCol[0];
- pTerm->u.leftColumn = aiCurCol[1];
+ if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
+ pTerm->leftCursor = iCur;
+ pTerm->u.leftColumn = iColumn;
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
- && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
+ && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
){
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
assert( pTerm->iField==0 );
@@ -129934,12 +129385,12 @@
}else{
pDup = pExpr;
pNew = pTerm;
}
exprCommute(pParse, pDup);
- pNew->leftCursor = aiCurCol[0];
- pNew->u.leftColumn = aiCurCol[1];
+ pNew->leftCursor = iCur;
+ pNew->u.leftColumn = iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
}
@@ -130294,15 +129745,15 @@
*/
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
- return sqlite3WhereGetMask(pMaskSet, p->iTable);
+ mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
+ return mask;
}
- mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
assert( !ExprHasProperty(p, EP_TokenOnly) );
- if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
+ mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
}else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
@@ -132167,21 +131618,21 @@
sqlite3_free(p->u.vtab.idxStr);
p->u.vtab.needFree = 0;
p->u.vtab.idxStr = 0;
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
- sqlite3DbFreeNN(db, p->u.btree.pIndex);
+ sqlite3DbFree(db, p->u.btree.pIndex);
p->u.btree.pIndex = 0;
}
}
}
/*
** Deallocate internal memory used by a WhereLoop object
*/
static void whereLoopClear(sqlite3 *db, WhereLoop *p){
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
whereLoopClearUnion(db, p);
whereLoopInit(p);
}
/*
@@ -132192,11 +131643,11 @@
if( p->nLSlot>=n ) return SQLITE_OK;
n = (n+7)&~7;
paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
if( paNew==0 ) return SQLITE_NOMEM_BKPT;
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
p->aLTerm = paNew;
p->nLSlot = n;
return SQLITE_OK;
}
@@ -132222,11 +131673,11 @@
/*
** Delete a WhereLoop object
*/
static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
whereLoopClear(db, p);
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
/*
** Free a WhereInfo structure
*/
@@ -132243,11 +131694,11 @@
while( pWInfo->pLoops ){
WhereLoop *p = pWInfo->pLoops;
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
}
- sqlite3DbFreeNN(db, pWInfo);
+ sqlite3DbFree(db, pWInfo);
}
}
/*
** Return TRUE if all of the following are true:
@@ -133634,11 +133085,11 @@
pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
}
}
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
- sqlite3DbFreeNN(pParse->db, p);
+ sqlite3DbFree(pParse->db, p);
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/*
@@ -133818,11 +133269,11 @@
whereLoopClear(db, pNew);
return rc;
}
/*
-** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
+** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
** parameters) to see if it outputs rows in the requested ORDER BY
** (or GROUP BY) without requiring a separate sort operation. Return N:
**
** N>0: N terms of the ORDER BY clause are satisfied
** N==0: No terms of the ORDER BY clause are satisfied
@@ -133913,12 +133364,10 @@
pLoop = pLast;
}
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
if( pLoop->u.vtab.isOrdered ) obSat = obDone;
break;
- }else{
- pLoop->u.btree.nIdxCol = 0;
}
iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
/* Mark off any ORDER BY term X that is a column in the table of
** the current loop for which there is term in the WHERE
@@ -134060,11 +133509,10 @@
if( iColumn>=0 ){
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( !pColl ) pColl = db->pDfltColl;
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
}
- pLoop->u.btree.nIdxCol = j+1;
isMatch = 1;
break;
}
if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
/* Make sure the sort order is compatible in an ORDER BY clause.
@@ -134492,11 +133940,11 @@
nFrom = nTo;
}
if( nFrom==0 ){
sqlite3ErrorMsg(pParse, "no query solution");
- sqlite3DbFreeNN(db, pSpace);
+ sqlite3DbFree(db, pSpace);
return SQLITE_ERROR;
}
/* Find the lowest cost path. pFrom will be left pointing to that path */
pFrom = aFrom;
@@ -134568,11 +134016,11 @@
pWInfo->nRowOut = pFrom->nRow;
/* Free temporary memory and return success */
- sqlite3DbFreeNN(db, pSpace);
+ sqlite3DbFree(db, pSpace);
return SQLITE_OK;
}
/*
** Most queries use only a single table (they are not joins) and have
@@ -134646,12 +134094,11 @@
}
}
if( pLoop->wsFlags ){
pLoop->nOut = (LogEst)1;
pWInfo->a[0].pWLoop = pLoop;
- assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
- pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
+ pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
pWInfo->a[0].iTabCur = iCur;
pWInfo->nRowOut = 1;
if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
@@ -134831,11 +134278,10 @@
goto whereBeginError;
}
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
- pWInfo->pWhere = pWhere;
pWInfo->pResultSet = pResultSet;
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
pWInfo->wctrlFlags = wctrlFlags;
@@ -135142,11 +134588,10 @@
sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
- && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
}
VdbeComment((v, "%s", pIx->zName));
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
@@ -135231,47 +134676,18 @@
sqlite3ExprCacheClear(pParse);
for(i=pWInfo->nLevel-1; i>=0; i--){
int addr;
pLevel = &pWInfo->a[i];
pLoop = pLevel->pWLoop;
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
-#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
- int addrSeek = 0;
- Index *pIdx;
- int n;
- if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
- && (pLoop->wsFlags & WHERE_INDEXED)!=0
- && (pIdx = pLoop->u.btree.pIndex)->hasStat1
- && (n = pLoop->u.btree.nIdxCol)>0
- && pIdx->aiRowLogEst[n]>=36
- ){
- int r1 = pParse->nMem+1;
- int j, op;
- for(j=0; jiIdxCur, j, r1+j);
- }
- pParse->nMem += n+1;
- op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
- addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
- VdbeCoverageIf(v, op==OP_SeekLT);
- VdbeCoverageIf(v, op==OP_SeekGT);
- sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
- }
-#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
- /* The common case: Advance to the next row */
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
VdbeCoverageIf(v, pLevel->op==OP_Prev);
VdbeCoverageIf(v, pLevel->op==OP_VNext);
-#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
- if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
-#endif
- }else{
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
}
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
int j;
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
@@ -135390,12 +134806,10 @@
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
|| pWInfo->eOnePass );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
- }else if( pOp->opcode==OP_IfNullRow ){
- pOp->p1 = pLevel->iIdxCur;
}
}
}
}
@@ -135701,11 +135115,11 @@
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned char
#define YYNOCODE 252
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 69
+#define YYWILDCARD 96
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
Expr* yy72;
@@ -135808,419 +135222,419 @@
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1566)
+#define YY_ACTTAB_COUNT (1567)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 325, 411, 343, 752, 752, 203, 946, 354, 976, 98,
- /* 10 */ 98, 98, 98, 91, 96, 96, 96, 96, 95, 95,
- /* 20 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 813,
- /* 30 */ 978, 978, 98, 98, 98, 98, 20, 96, 96, 96,
- /* 40 */ 96, 95, 95, 94, 94, 94, 93, 351, 92, 89,
- /* 50 */ 178, 99, 100, 90, 853, 856, 845, 845, 97, 97,
- /* 60 */ 98, 98, 98, 98, 351, 96, 96, 96, 96, 95,
- /* 70 */ 95, 94, 94, 94, 93, 351, 325, 340, 976, 262,
- /* 80 */ 365, 251, 212, 169, 287, 405, 282, 404, 199, 791,
- /* 90 */ 242, 412, 21, 957, 379, 280, 93, 351, 792, 95,
- /* 100 */ 95, 94, 94, 94, 93, 351, 978, 978, 96, 96,
- /* 110 */ 96, 96, 95, 95, 94, 94, 94, 93, 351, 813,
- /* 120 */ 329, 242, 412, 913, 832, 913, 132, 99, 100, 90,
- /* 130 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98,
- /* 140 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94,
- /* 150 */ 93, 351, 325, 825, 349, 348, 120, 819, 120, 75,
- /* 160 */ 52, 52, 957, 958, 959, 760, 984, 146, 361, 262,
- /* 170 */ 370, 261, 957, 982, 961, 983, 92, 89, 178, 371,
- /* 180 */ 230, 371, 978, 978, 817, 361, 360, 101, 824, 824,
- /* 190 */ 826, 384, 24, 964, 381, 428, 413, 369, 985, 380,
- /* 200 */ 985, 708, 325, 99, 100, 90, 853, 856, 845, 845,
- /* 210 */ 97, 97, 98, 98, 98, 98, 373, 96, 96, 96,
- /* 220 */ 96, 95, 95, 94, 94, 94, 93, 351, 957, 132,
- /* 230 */ 897, 450, 978, 978, 896, 60, 94, 94, 94, 93,
- /* 240 */ 351, 957, 958, 959, 961, 103, 361, 957, 385, 334,
- /* 250 */ 702, 52, 52, 99, 100, 90, 853, 856, 845, 845,
- /* 260 */ 97, 97, 98, 98, 98, 98, 698, 96, 96, 96,
- /* 270 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 455,
- /* 280 */ 670, 450, 227, 61, 157, 243, 344, 114, 701, 888,
- /* 290 */ 147, 832, 957, 373, 747, 957, 320, 957, 958, 959,
- /* 300 */ 194, 10, 10, 402, 399, 398, 888, 890, 978, 978,
- /* 310 */ 762, 171, 170, 157, 397, 337, 957, 958, 959, 702,
- /* 320 */ 825, 310, 153, 957, 819, 321, 82, 23, 80, 99,
- /* 330 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
- /* 340 */ 98, 98, 894, 96, 96, 96, 96, 95, 95, 94,
- /* 350 */ 94, 94, 93, 351, 325, 824, 824, 826, 277, 231,
- /* 360 */ 300, 957, 958, 959, 957, 958, 959, 888, 194, 25,
- /* 370 */ 450, 402, 399, 398, 957, 355, 300, 450, 957, 74,
- /* 380 */ 450, 1, 397, 132, 978, 978, 957, 224, 224, 813,
- /* 390 */ 10, 10, 957, 958, 959, 968, 132, 52, 52, 415,
- /* 400 */ 52, 52, 739, 739, 339, 99, 100, 90, 853, 856,
- /* 410 */ 845, 845, 97, 97, 98, 98, 98, 98, 790, 96,
- /* 420 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
- /* 430 */ 325, 789, 428, 418, 706, 428, 427, 1270, 1270, 262,
- /* 440 */ 370, 261, 957, 957, 958, 959, 757, 957, 958, 959,
- /* 450 */ 450, 756, 450, 734, 713, 957, 958, 959, 443, 711,
- /* 460 */ 978, 978, 734, 394, 92, 89, 178, 447, 447, 447,
- /* 470 */ 51, 51, 52, 52, 439, 778, 700, 92, 89, 178,
- /* 480 */ 172, 99, 100, 90, 853, 856, 845, 845, 97, 97,
- /* 490 */ 98, 98, 98, 98, 198, 96, 96, 96, 96, 95,
- /* 500 */ 95, 94, 94, 94, 93, 351, 325, 428, 408, 916,
- /* 510 */ 699, 957, 958, 959, 92, 89, 178, 224, 224, 157,
- /* 520 */ 241, 221, 419, 299, 776, 917, 416, 375, 450, 415,
- /* 530 */ 58, 324, 737, 737, 920, 379, 978, 978, 379, 777,
- /* 540 */ 449, 918, 363, 740, 296, 686, 9, 9, 52, 52,
- /* 550 */ 234, 330, 234, 256, 417, 741, 280, 99, 100, 90,
- /* 560 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98,
- /* 570 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94,
- /* 580 */ 93, 351, 325, 423, 72, 450, 833, 120, 368, 450,
- /* 590 */ 10, 10, 5, 301, 203, 450, 177, 976, 253, 420,
- /* 600 */ 255, 776, 200, 175, 233, 10, 10, 842, 842, 36,
- /* 610 */ 36, 1299, 978, 978, 729, 37, 37, 349, 348, 425,
- /* 620 */ 203, 260, 776, 976, 232, 937, 1326, 876, 338, 1326,
- /* 630 */ 422, 854, 857, 99, 100, 90, 853, 856, 845, 845,
- /* 640 */ 97, 97, 98, 98, 98, 98, 268, 96, 96, 96,
- /* 650 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 846,
- /* 660 */ 450, 985, 818, 985, 1209, 450, 916, 976, 720, 350,
- /* 670 */ 350, 350, 935, 177, 450, 937, 1327, 254, 198, 1327,
- /* 680 */ 12, 12, 917, 403, 450, 27, 27, 250, 978, 978,
- /* 690 */ 118, 721, 162, 976, 38, 38, 268, 176, 918, 776,
- /* 700 */ 433, 1275, 946, 354, 39, 39, 317, 998, 325, 99,
- /* 710 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
- /* 720 */ 98, 98, 935, 96, 96, 96, 96, 95, 95, 94,
- /* 730 */ 94, 94, 93, 351, 450, 330, 450, 358, 978, 978,
- /* 740 */ 717, 317, 936, 341, 900, 900, 387, 673, 674, 675,
- /* 750 */ 275, 996, 318, 999, 40, 40, 41, 41, 268, 99,
- /* 760 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
- /* 770 */ 98, 98, 450, 96, 96, 96, 96, 95, 95, 94,
- /* 780 */ 94, 94, 93, 351, 325, 450, 356, 450, 999, 450,
- /* 790 */ 692, 331, 42, 42, 791, 270, 450, 273, 450, 228,
- /* 800 */ 450, 298, 450, 792, 450, 28, 28, 29, 29, 31,
- /* 810 */ 31, 450, 817, 450, 978, 978, 43, 43, 44, 44,
- /* 820 */ 45, 45, 11, 11, 46, 46, 893, 78, 893, 268,
- /* 830 */ 268, 105, 105, 47, 47, 99, 100, 90, 853, 856,
- /* 840 */ 845, 845, 97, 97, 98, 98, 98, 98, 450, 96,
- /* 850 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
- /* 860 */ 325, 450, 117, 450, 749, 158, 450, 696, 48, 48,
- /* 870 */ 229, 919, 450, 928, 450, 415, 450, 335, 450, 245,
- /* 880 */ 450, 33, 33, 49, 49, 450, 50, 50, 246, 817,
- /* 890 */ 978, 978, 34, 34, 122, 122, 123, 123, 124, 124,
- /* 900 */ 56, 56, 268, 81, 249, 35, 35, 197, 196, 195,
- /* 910 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97,
- /* 920 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
- /* 930 */ 95, 94, 94, 94, 93, 351, 450, 696, 450, 817,
- /* 940 */ 978, 978, 975, 884, 106, 106, 268, 886, 268, 944,
- /* 950 */ 2, 892, 268, 892, 336, 716, 53, 53, 107, 107,
- /* 960 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97,
- /* 970 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
- /* 980 */ 95, 94, 94, 94, 93, 351, 450, 746, 450, 742,
- /* 990 */ 978, 978, 715, 267, 108, 108, 446, 331, 332, 133,
- /* 1000 */ 223, 175, 301, 225, 386, 933, 104, 104, 121, 121,
- /* 1010 */ 325, 99, 88, 90, 853, 856, 845, 845, 97, 97,
- /* 1020 */ 98, 98, 98, 98, 817, 96, 96, 96, 96, 95,
- /* 1030 */ 95, 94, 94, 94, 93, 351, 450, 347, 450, 167,
- /* 1040 */ 978, 978, 932, 815, 372, 319, 202, 202, 374, 263,
- /* 1050 */ 395, 202, 74, 208, 726, 727, 119, 119, 112, 112,
- /* 1060 */ 325, 407, 100, 90, 853, 856, 845, 845, 97, 97,
- /* 1070 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
- /* 1080 */ 95, 94, 94, 94, 93, 351, 450, 757, 450, 345,
- /* 1090 */ 978, 978, 756, 278, 111, 111, 74, 719, 718, 709,
- /* 1100 */ 286, 883, 754, 1289, 257, 77, 109, 109, 110, 110,
- /* 1110 */ 908, 285, 810, 90, 853, 856, 845, 845, 97, 97,
- /* 1120 */ 98, 98, 98, 98, 911, 96, 96, 96, 96, 95,
- /* 1130 */ 95, 94, 94, 94, 93, 351, 86, 445, 450, 3,
- /* 1140 */ 1202, 450, 745, 132, 352, 120, 689, 86, 445, 785,
- /* 1150 */ 3, 767, 202, 377, 448, 352, 907, 120, 55, 55,
- /* 1160 */ 450, 57, 57, 828, 879, 448, 450, 208, 450, 709,
- /* 1170 */ 450, 883, 237, 434, 436, 120, 440, 429, 362, 120,
- /* 1180 */ 54, 54, 132, 450, 434, 832, 52, 52, 26, 26,
- /* 1190 */ 30, 30, 382, 132, 409, 444, 832, 694, 264, 390,
- /* 1200 */ 116, 269, 272, 32, 32, 83, 84, 120, 274, 120,
- /* 1210 */ 120, 276, 85, 352, 452, 451, 83, 84, 819, 730,
- /* 1220 */ 714, 428, 430, 85, 352, 452, 451, 120, 120, 819,
- /* 1230 */ 378, 218, 281, 828, 783, 816, 86, 445, 410, 3,
- /* 1240 */ 763, 774, 431, 432, 352, 302, 303, 823, 697, 824,
- /* 1250 */ 824, 826, 827, 19, 448, 691, 680, 679, 681, 951,
- /* 1260 */ 824, 824, 826, 827, 19, 289, 159, 291, 293, 7,
- /* 1270 */ 316, 173, 259, 434, 805, 364, 252, 910, 376, 713,
- /* 1280 */ 295, 435, 168, 993, 400, 832, 284, 881, 880, 205,
- /* 1290 */ 954, 308, 927, 86, 445, 990, 3, 925, 333, 144,
- /* 1300 */ 130, 352, 72, 135, 59, 83, 84, 761, 137, 366,
- /* 1310 */ 802, 448, 85, 352, 452, 451, 139, 226, 819, 140,
- /* 1320 */ 156, 62, 315, 314, 313, 215, 311, 367, 393, 683,
- /* 1330 */ 434, 185, 141, 912, 142, 160, 148, 812, 875, 383,
- /* 1340 */ 189, 67, 832, 180, 389, 248, 895, 775, 219, 824,
- /* 1350 */ 824, 826, 827, 19, 247, 190, 266, 154, 391, 271,
- /* 1360 */ 191, 192, 83, 84, 682, 406, 733, 182, 322, 85,
- /* 1370 */ 352, 452, 451, 732, 183, 819, 342, 132, 181, 711,
- /* 1380 */ 731, 421, 76, 445, 705, 3, 323, 704, 283, 724,
- /* 1390 */ 352, 771, 703, 966, 723, 71, 204, 6, 288, 290,
- /* 1400 */ 448, 772, 770, 769, 79, 292, 824, 824, 826, 827,
- /* 1410 */ 19, 294, 297, 438, 346, 442, 102, 861, 753, 434,
- /* 1420 */ 238, 426, 73, 305, 239, 304, 326, 240, 424, 306,
- /* 1430 */ 307, 832, 213, 688, 22, 952, 453, 214, 216, 217,
- /* 1440 */ 454, 677, 115, 676, 671, 125, 126, 235, 127, 669,
- /* 1450 */ 327, 83, 84, 359, 353, 244, 166, 328, 85, 352,
- /* 1460 */ 452, 451, 134, 179, 819, 357, 113, 891, 811, 889,
- /* 1470 */ 136, 128, 138, 743, 258, 184, 906, 143, 145, 63,
- /* 1480 */ 64, 65, 66, 129, 909, 905, 187, 186, 8, 13,
- /* 1490 */ 188, 265, 898, 149, 202, 824, 824, 826, 827, 19,
- /* 1500 */ 388, 987, 150, 161, 285, 685, 392, 396, 151, 722,
- /* 1510 */ 193, 68, 14, 401, 279, 15, 69, 236, 831, 830,
- /* 1520 */ 131, 859, 751, 70, 16, 414, 755, 4, 784, 220,
- /* 1530 */ 222, 174, 152, 437, 779, 201, 17, 77, 74, 18,
- /* 1540 */ 874, 860, 858, 915, 863, 914, 207, 206, 941, 163,
- /* 1550 */ 210, 942, 209, 164, 441, 862, 165, 211, 829, 695,
- /* 1560 */ 87, 312, 309, 947, 1291, 1290,
+ /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100,
+ /* 10 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98,
+ /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
+ /* 30 */ 94, 94, 94, 93, 351, 325, 976, 976, 824, 824,
+ /* 40 */ 826, 946, 354, 99, 100, 90, 978, 978, 853, 856,
+ /* 50 */ 845, 845, 97, 97, 98, 98, 98, 98, 338, 96,
+ /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 976, 976,
+ /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100,
+ /* 90 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98,
+ /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
+ /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325,
+ /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
+ /* 130 */ 978, 978, 853, 856, 845, 845, 97, 97, 98, 98,
+ /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
+ /* 150 */ 94, 94, 93, 351, 957, 957, 325, 268, 428, 413,
+ /* 160 */ 411, 61, 752, 752, 99, 100, 90, 978, 978, 853,
+ /* 170 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 60,
+ /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 190 */ 351, 325, 270, 329, 273, 277, 958, 959, 250, 99,
+ /* 200 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
+ /* 220 */ 95, 94, 94, 94, 93, 351, 325, 937, 1326, 698,
+ /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 978, 978, 853,
+ /* 240 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 347,
+ /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 260 */ 351, 325, 937, 1327, 384, 699, 1327, 381, 379, 99,
+ /* 270 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95,
+ /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
+ /* 300 */ 833, 935, 373, 700, 99, 100, 90, 978, 978, 853,
+ /* 310 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 375,
+ /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 330 */ 351, 325, 1275, 946, 354, 818, 935, 739, 739, 99,
+ /* 340 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
+ /* 360 */ 95, 94, 94, 94, 93, 351, 325, 968, 227, 92,
+ /* 370 */ 89, 178, 373, 300, 99, 100, 90, 978, 978, 853,
+ /* 380 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 920,
+ /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99,
+ /* 410 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
+ /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 957,
+ /* 440 */ 957, 158, 25, 422, 99, 100, 90, 978, 978, 853,
+ /* 450 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 450,
+ /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 470 */ 351, 443, 224, 224, 420, 957, 957, 961, 325, 52,
+ /* 480 */ 52, 958, 959, 176, 415, 78, 99, 100, 90, 978,
+ /* 490 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98,
+ /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
+ /* 510 */ 94, 93, 351, 325, 428, 418, 298, 958, 959, 961,
+ /* 520 */ 81, 99, 88, 90, 978, 978, 853, 856, 845, 845,
+ /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96,
+ /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 842,
+ /* 550 */ 842, 854, 857, 996, 318, 343, 379, 100, 90, 978,
+ /* 560 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98,
+ /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
+ /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
+ /* 590 */ 928, 52, 52, 90, 978, 978, 853, 856, 845, 845,
+ /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
+ /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
+ /* 620 */ 846, 3, 1202, 361, 360, 378, 344, 813, 957, 957,
+ /* 630 */ 1299, 86, 445, 729, 3, 212, 169, 287, 405, 282,
+ /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245,
+ /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
+ /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
+ /* 670 */ 958, 959, 194, 455, 670, 402, 399, 398, 448, 243,
+ /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224,
+ /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427,
+ /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452,
+ /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1270,
+ /* 720 */ 1270, 23, 957, 957, 86, 445, 397, 3, 228, 429,
+ /* 730 */ 894, 824, 824, 826, 827, 19, 203, 720, 52, 52,
+ /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229,
+ /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85,
+ /* 760 */ 352, 352, 120, 157, 958, 959, 58, 976, 409, 355,
+ /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86,
+ /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96,
+ /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 800 */ 832, 120, 452, 451, 813, 886, 819, 83, 84, 976,
+ /* 810 */ 813, 132, 410, 919, 85, 352, 352, 132, 407, 789,
+ /* 820 */ 957, 957, 92, 89, 178, 916, 448, 262, 370, 261,
+ /* 830 */ 82, 913, 80, 262, 370, 261, 776, 824, 824, 826,
+ /* 840 */ 827, 19, 933, 434, 96, 96, 96, 96, 95, 95,
+ /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 957,
+ /* 860 */ 957, 819, 958, 959, 120, 92, 89, 178, 944, 2,
+ /* 870 */ 917, 964, 268, 1, 975, 76, 445, 762, 3, 708,
+ /* 880 */ 900, 900, 387, 957, 957, 757, 918, 371, 740, 778,
+ /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450,
+ /* 900 */ 24, 958, 959, 83, 84, 369, 957, 957, 177, 226,
+ /* 910 */ 85, 352, 352, 884, 315, 314, 313, 215, 311, 10,
+ /* 920 */ 10, 683, 448, 349, 348, 958, 959, 908, 777, 157,
+ /* 930 */ 120, 957, 957, 337, 776, 416, 711, 310, 450, 434,
+ /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 958, 959,
+ /* 950 */ 907, 832, 792, 452, 451, 9, 9, 819, 10, 10,
+ /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171,
+ /* 970 */ 170, 167, 339, 958, 959, 247, 984, 702, 702, 450,
+ /* 980 */ 715, 233, 686, 982, 888, 983, 182, 913, 824, 824,
+ /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10,
+ /* 1000 */ 10, 888, 890, 749, 957, 957, 916, 268, 985, 198,
+ /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825,
+ /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91,
+ /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 1040 */ 351, 157, 810, 371, 382, 359, 958, 959, 358, 268,
+ /* 1050 */ 450, 917, 368, 324, 824, 824, 826, 450, 709, 450,
+ /* 1060 */ 264, 380, 888, 450, 876, 746, 253, 918, 255, 433,
+ /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12,
+ /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162,
+ /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450,
+ /* 1100 */ 709, 1209, 450, 132, 450, 39, 39, 450, 40, 40,
+ /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28,
+ /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450,
+ /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767,
+ /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47,
+ /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172,
+ /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122,
+ /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 897, 56, 56,
+ /* 1180 */ 450, 896, 35, 35, 450, 267, 450, 817, 450, 817,
+ /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817,
+ /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119,
+ /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111,
+ /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 911,
+ /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331,
+ /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 936, 197,
+ /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436,
+ /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 932,
+ /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202,
+ /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 883,
+ /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74,
+ /* 1300 */ 726, 727, 785, 783, 879, 202, 999, 208, 893, 892,
+ /* 1310 */ 893, 892, 694, 816, 763, 116, 774, 1289, 431, 432,
+ /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289,
+ /* 1330 */ 679, 883, 681, 951, 291, 218, 293, 7, 316, 828,
+ /* 1340 */ 173, 805, 259, 364, 252, 910, 376, 713, 295, 435,
+ /* 1350 */ 308, 168, 954, 993, 135, 400, 990, 284, 881, 880,
+ /* 1360 */ 205, 927, 925, 59, 333, 62, 144, 156, 130, 72,
+ /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383,
+ /* 1380 */ 67, 895, 140, 141, 142, 148, 389, 812, 775, 266,
+ /* 1390 */ 219, 190, 154, 391, 912, 875, 271, 406, 191, 322,
+ /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421,
+ /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346,
+ /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 966, 239,
+ /* 1430 */ 769, 102, 861, 438, 426, 240, 424, 442, 73, 213,
+ /* 1440 */ 688, 238, 22, 453, 952, 214, 217, 216, 454, 677,
+ /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166,
+ /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 891,
+ /* 1470 */ 327, 889, 811, 328, 134, 128, 136, 138, 743, 258,
+ /* 1480 */ 906, 184, 143, 129, 909, 186, 63, 64, 145, 187,
+ /* 1490 */ 905, 65, 8, 66, 13, 188, 202, 898, 265, 149,
+ /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396,
+ /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131,
+ /* 1520 */ 830, 859, 70, 751, 16, 414, 755, 4, 174, 220,
+ /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 874,
+ /* 1540 */ 860, 858, 915, 863, 914, 207, 206, 941, 163, 437,
+ /* 1550 */ 947, 942, 164, 209, 1002, 441, 862, 165, 210, 829,
+ /* 1560 */ 695, 87, 312, 211, 1291, 1290, 309,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 115, 19, 117, 118, 24, 1, 2, 27, 79,
- /* 10 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 20 */ 90, 91, 92, 93, 94, 144, 145, 146, 147, 58,
- /* 30 */ 49, 50, 79, 80, 81, 82, 22, 84, 85, 86,
- /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 221, 222,
- /* 50 */ 223, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 81, 82, 94, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 93, 94, 19, 94, 97, 108,
- /* 80 */ 109, 110, 99, 100, 101, 102, 103, 104, 105, 32,
- /* 90 */ 119, 120, 78, 27, 152, 112, 93, 94, 41, 88,
- /* 100 */ 89, 90, 91, 92, 93, 94, 49, 50, 84, 85,
- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 58,
- /* 120 */ 157, 119, 120, 163, 68, 163, 65, 70, 71, 72,
- /* 130 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 140 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 150 */ 93, 94, 19, 97, 88, 89, 196, 101, 196, 26,
- /* 160 */ 172, 173, 96, 97, 98, 210, 100, 22, 152, 108,
- /* 170 */ 109, 110, 27, 107, 27, 109, 221, 222, 223, 219,
- /* 180 */ 238, 219, 49, 50, 152, 169, 170, 54, 132, 133,
- /* 190 */ 134, 228, 232, 171, 231, 207, 208, 237, 132, 237,
- /* 200 */ 134, 179, 19, 70, 71, 72, 73, 74, 75, 76,
- /* 210 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
- /* 220 */ 87, 88, 89, 90, 91, 92, 93, 94, 27, 65,
- /* 230 */ 30, 152, 49, 50, 34, 52, 90, 91, 92, 93,
- /* 240 */ 94, 96, 97, 98, 97, 22, 230, 27, 48, 217,
- /* 250 */ 27, 172, 173, 70, 71, 72, 73, 74, 75, 76,
- /* 260 */ 77, 78, 79, 80, 81, 82, 172, 84, 85, 86,
- /* 270 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 148,
- /* 280 */ 149, 152, 218, 24, 152, 154, 207, 156, 172, 152,
- /* 290 */ 22, 68, 27, 152, 163, 27, 164, 96, 97, 98,
- /* 300 */ 99, 172, 173, 102, 103, 104, 169, 170, 49, 50,
- /* 310 */ 90, 88, 89, 152, 113, 186, 96, 97, 98, 96,
- /* 320 */ 97, 160, 57, 27, 101, 164, 137, 196, 139, 70,
- /* 330 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 340 */ 81, 82, 11, 84, 85, 86, 87, 88, 89, 90,
- /* 350 */ 91, 92, 93, 94, 19, 132, 133, 134, 23, 218,
- /* 360 */ 152, 96, 97, 98, 96, 97, 98, 230, 99, 22,
- /* 370 */ 152, 102, 103, 104, 27, 244, 152, 152, 27, 26,
- /* 380 */ 152, 22, 113, 65, 49, 50, 27, 194, 195, 58,
- /* 390 */ 172, 173, 96, 97, 98, 185, 65, 172, 173, 206,
- /* 400 */ 172, 173, 190, 191, 186, 70, 71, 72, 73, 74,
- /* 410 */ 75, 76, 77, 78, 79, 80, 81, 82, 175, 84,
- /* 420 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 430 */ 19, 175, 207, 208, 23, 207, 208, 119, 120, 108,
- /* 440 */ 109, 110, 27, 96, 97, 98, 116, 96, 97, 98,
- /* 450 */ 152, 121, 152, 179, 180, 96, 97, 98, 250, 106,
- /* 460 */ 49, 50, 188, 19, 221, 222, 223, 168, 169, 170,
- /* 470 */ 172, 173, 172, 173, 250, 124, 172, 221, 222, 223,
- /* 480 */ 26, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 490 */ 79, 80, 81, 82, 50, 84, 85, 86, 87, 88,
- /* 500 */ 89, 90, 91, 92, 93, 94, 19, 207, 208, 12,
- /* 510 */ 23, 96, 97, 98, 221, 222, 223, 194, 195, 152,
- /* 520 */ 199, 23, 19, 225, 26, 28, 152, 152, 152, 206,
- /* 530 */ 209, 164, 190, 191, 241, 152, 49, 50, 152, 124,
- /* 540 */ 152, 44, 219, 46, 152, 21, 172, 173, 172, 173,
- /* 550 */ 183, 107, 185, 16, 163, 58, 112, 70, 71, 72,
- /* 560 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 570 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 580 */ 93, 94, 19, 207, 130, 152, 23, 196, 64, 152,
- /* 590 */ 172, 173, 22, 152, 24, 152, 98, 27, 61, 96,
- /* 600 */ 63, 26, 211, 212, 186, 172, 173, 49, 50, 172,
- /* 610 */ 173, 23, 49, 50, 26, 172, 173, 88, 89, 186,
- /* 620 */ 24, 238, 124, 27, 238, 22, 23, 103, 187, 26,
- /* 630 */ 152, 73, 74, 70, 71, 72, 73, 74, 75, 76,
- /* 640 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
- /* 650 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 101,
- /* 660 */ 152, 132, 23, 134, 140, 152, 12, 97, 36, 168,
- /* 670 */ 169, 170, 69, 98, 152, 22, 23, 140, 50, 26,
- /* 680 */ 172, 173, 28, 51, 152, 172, 173, 193, 49, 50,
- /* 690 */ 22, 59, 24, 97, 172, 173, 152, 152, 44, 124,
- /* 700 */ 46, 0, 1, 2, 172, 173, 22, 23, 19, 70,
- /* 710 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 720 */ 81, 82, 69, 84, 85, 86, 87, 88, 89, 90,
- /* 730 */ 91, 92, 93, 94, 152, 107, 152, 193, 49, 50,
- /* 740 */ 181, 22, 23, 111, 108, 109, 110, 7, 8, 9,
- /* 750 */ 16, 247, 248, 69, 172, 173, 172, 173, 152, 70,
- /* 760 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 770 */ 81, 82, 152, 84, 85, 86, 87, 88, 89, 90,
- /* 780 */ 91, 92, 93, 94, 19, 152, 242, 152, 69, 152,
- /* 790 */ 166, 167, 172, 173, 32, 61, 152, 63, 152, 193,
- /* 800 */ 152, 152, 152, 41, 152, 172, 173, 172, 173, 172,
- /* 810 */ 173, 152, 152, 152, 49, 50, 172, 173, 172, 173,
- /* 820 */ 172, 173, 172, 173, 172, 173, 132, 138, 134, 152,
- /* 830 */ 152, 172, 173, 172, 173, 70, 71, 72, 73, 74,
- /* 840 */ 75, 76, 77, 78, 79, 80, 81, 82, 152, 84,
- /* 850 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 860 */ 19, 152, 22, 152, 195, 24, 152, 27, 172, 173,
- /* 870 */ 193, 193, 152, 152, 152, 206, 152, 217, 152, 152,
- /* 880 */ 152, 172, 173, 172, 173, 152, 172, 173, 152, 152,
- /* 890 */ 49, 50, 172, 173, 172, 173, 172, 173, 172, 173,
- /* 900 */ 172, 173, 152, 138, 152, 172, 173, 108, 109, 110,
- /* 910 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 920 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 930 */ 89, 90, 91, 92, 93, 94, 152, 97, 152, 152,
- /* 940 */ 49, 50, 26, 193, 172, 173, 152, 152, 152, 146,
- /* 950 */ 147, 132, 152, 134, 217, 181, 172, 173, 172, 173,
- /* 960 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 970 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 980 */ 89, 90, 91, 92, 93, 94, 152, 193, 152, 193,
- /* 990 */ 49, 50, 181, 193, 172, 173, 166, 167, 245, 246,
- /* 1000 */ 211, 212, 152, 22, 217, 152, 172, 173, 172, 173,
- /* 1010 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1020 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 1030 */ 89, 90, 91, 92, 93, 94, 152, 187, 152, 123,
- /* 1040 */ 49, 50, 23, 23, 23, 26, 26, 26, 23, 23,
- /* 1050 */ 23, 26, 26, 26, 7, 8, 172, 173, 172, 173,
- /* 1060 */ 19, 90, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1070 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 1080 */ 89, 90, 91, 92, 93, 94, 152, 116, 152, 217,
- /* 1090 */ 49, 50, 121, 23, 172, 173, 26, 100, 101, 27,
- /* 1100 */ 101, 27, 23, 122, 152, 26, 172, 173, 172, 173,
- /* 1110 */ 152, 112, 163, 72, 73, 74, 75, 76, 77, 78,
- /* 1120 */ 79, 80, 81, 82, 163, 84, 85, 86, 87, 88,
- /* 1130 */ 89, 90, 91, 92, 93, 94, 19, 20, 152, 22,
- /* 1140 */ 23, 152, 163, 65, 27, 196, 163, 19, 20, 23,
- /* 1150 */ 22, 213, 26, 19, 37, 27, 152, 196, 172, 173,
- /* 1160 */ 152, 172, 173, 27, 23, 37, 152, 26, 152, 97,
- /* 1170 */ 152, 97, 210, 56, 163, 196, 163, 163, 100, 196,
- /* 1180 */ 172, 173, 65, 152, 56, 68, 172, 173, 172, 173,
- /* 1190 */ 172, 173, 152, 65, 163, 163, 68, 23, 152, 234,
- /* 1200 */ 26, 152, 152, 172, 173, 88, 89, 196, 152, 196,
- /* 1210 */ 196, 152, 95, 96, 97, 98, 88, 89, 101, 152,
- /* 1220 */ 152, 207, 208, 95, 96, 97, 98, 196, 196, 101,
- /* 1230 */ 96, 233, 152, 97, 152, 152, 19, 20, 207, 22,
- /* 1240 */ 152, 152, 152, 191, 27, 152, 152, 152, 152, 132,
- /* 1250 */ 133, 134, 135, 136, 37, 152, 152, 152, 152, 152,
- /* 1260 */ 132, 133, 134, 135, 136, 210, 197, 210, 210, 198,
- /* 1270 */ 150, 184, 239, 56, 201, 214, 214, 201, 239, 180,
- /* 1280 */ 214, 227, 198, 38, 176, 68, 175, 175, 175, 122,
- /* 1290 */ 155, 200, 159, 19, 20, 40, 22, 159, 159, 22,
- /* 1300 */ 70, 27, 130, 243, 240, 88, 89, 90, 189, 18,
- /* 1310 */ 201, 37, 95, 96, 97, 98, 192, 5, 101, 192,
- /* 1320 */ 220, 240, 10, 11, 12, 13, 14, 159, 18, 17,
- /* 1330 */ 56, 158, 192, 201, 192, 220, 189, 189, 201, 159,
- /* 1340 */ 158, 137, 68, 31, 45, 33, 236, 159, 159, 132,
- /* 1350 */ 133, 134, 135, 136, 42, 158, 235, 22, 177, 159,
- /* 1360 */ 158, 158, 88, 89, 159, 107, 174, 55, 177, 95,
- /* 1370 */ 96, 97, 98, 174, 62, 101, 47, 65, 66, 106,
- /* 1380 */ 174, 125, 19, 20, 174, 22, 177, 176, 174, 182,
- /* 1390 */ 27, 216, 174, 174, 182, 107, 159, 22, 215, 215,
- /* 1400 */ 37, 216, 216, 216, 137, 215, 132, 133, 134, 135,
- /* 1410 */ 136, 215, 159, 177, 94, 177, 129, 224, 205, 56,
- /* 1420 */ 226, 126, 128, 203, 229, 204, 114, 229, 127, 202,
- /* 1430 */ 201, 68, 25, 162, 26, 13, 161, 153, 153, 6,
- /* 1440 */ 151, 151, 178, 151, 151, 165, 165, 178, 165, 4,
- /* 1450 */ 249, 88, 89, 141, 3, 142, 22, 249, 95, 96,
- /* 1460 */ 97, 98, 246, 15, 101, 67, 16, 23, 120, 23,
- /* 1470 */ 131, 111, 123, 20, 16, 125, 1, 123, 131, 78,
- /* 1480 */ 78, 78, 78, 111, 96, 1, 122, 35, 5, 22,
- /* 1490 */ 107, 140, 53, 53, 26, 132, 133, 134, 135, 136,
- /* 1500 */ 43, 60, 107, 24, 112, 20, 19, 52, 22, 29,
- /* 1510 */ 105, 22, 22, 52, 23, 22, 22, 52, 23, 23,
- /* 1520 */ 39, 23, 116, 26, 22, 26, 23, 22, 96, 23,
- /* 1530 */ 23, 122, 22, 24, 124, 35, 35, 26, 26, 35,
- /* 1540 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22,
- /* 1550 */ 122, 23, 26, 22, 24, 23, 22, 122, 23, 23,
- /* 1560 */ 22, 15, 23, 1, 122, 122,
-};
-#define YY_SHIFT_USE_DFLT (1566)
+ /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
+ /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
+ /* 30 */ 49, 50, 51, 52, 53, 19, 55, 55, 132, 133,
+ /* 40 */ 134, 1, 2, 27, 28, 29, 30, 31, 32, 33,
+ /* 50 */ 34, 35, 36, 37, 38, 39, 40, 41, 187, 43,
+ /* 60 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 70 */ 47, 48, 49, 50, 51, 52, 53, 61, 97, 97,
+ /* 80 */ 19, 49, 50, 51, 52, 53, 70, 26, 27, 28,
+ /* 90 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ /* 100 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
+ /* 110 */ 49, 50, 51, 52, 53, 144, 145, 146, 147, 19,
+ /* 120 */ 16, 22, 92, 172, 173, 52, 53, 27, 28, 29,
+ /* 130 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ /* 140 */ 40, 41, 81, 43, 44, 45, 46, 47, 48, 49,
+ /* 150 */ 50, 51, 52, 53, 55, 56, 19, 152, 207, 208,
+ /* 160 */ 115, 24, 117, 118, 27, 28, 29, 30, 31, 32,
+ /* 170 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 79,
+ /* 180 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 190 */ 53, 19, 88, 157, 90, 23, 97, 98, 193, 27,
+ /* 200 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ /* 210 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
+ /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 172,
+ /* 230 */ 23, 26, 119, 120, 27, 28, 29, 30, 31, 32,
+ /* 240 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 187,
+ /* 250 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 260 */ 53, 19, 22, 23, 228, 23, 26, 231, 152, 27,
+ /* 270 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ /* 280 */ 38, 39, 40, 41, 172, 43, 44, 45, 46, 47,
+ /* 290 */ 48, 49, 50, 51, 52, 53, 19, 221, 222, 223,
+ /* 300 */ 23, 96, 152, 172, 27, 28, 29, 30, 31, 32,
+ /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
+ /* 320 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 330 */ 53, 19, 0, 1, 2, 23, 96, 190, 191, 27,
+ /* 340 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ /* 350 */ 38, 39, 40, 41, 238, 43, 44, 45, 46, 47,
+ /* 360 */ 48, 49, 50, 51, 52, 53, 19, 185, 218, 221,
+ /* 370 */ 222, 223, 152, 152, 27, 28, 29, 30, 31, 32,
+ /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 241,
+ /* 390 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 400 */ 53, 19, 152, 168, 169, 170, 22, 190, 191, 27,
+ /* 410 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ /* 420 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
+ /* 430 */ 48, 49, 50, 51, 52, 53, 19, 19, 218, 55,
+ /* 440 */ 56, 24, 22, 152, 27, 28, 29, 30, 31, 32,
+ /* 450 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
+ /* 460 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 470 */ 53, 250, 194, 195, 56, 55, 56, 55, 19, 172,
+ /* 480 */ 173, 97, 98, 152, 206, 138, 27, 28, 29, 30,
+ /* 490 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ /* 500 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 510 */ 51, 52, 53, 19, 207, 208, 152, 97, 98, 97,
+ /* 520 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ /* 530 */ 36, 37, 38, 39, 40, 41, 181, 43, 44, 45,
+ /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 30,
+ /* 550 */ 31, 32, 33, 247, 248, 19, 152, 28, 29, 30,
+ /* 560 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ /* 570 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 580 */ 51, 52, 53, 19, 168, 169, 170, 238, 19, 53,
+ /* 590 */ 152, 172, 173, 29, 30, 31, 32, 33, 34, 35,
+ /* 600 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45,
+ /* 610 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 20,
+ /* 620 */ 101, 22, 23, 169, 170, 56, 207, 85, 55, 56,
+ /* 630 */ 23, 19, 20, 26, 22, 99, 100, 101, 102, 103,
+ /* 640 */ 104, 105, 238, 152, 152, 210, 47, 48, 112, 152,
+ /* 650 */ 108, 109, 110, 54, 55, 56, 221, 222, 223, 47,
+ /* 660 */ 48, 119, 120, 172, 173, 66, 54, 55, 56, 152,
+ /* 670 */ 97, 98, 99, 148, 149, 102, 103, 104, 66, 154,
+ /* 680 */ 23, 156, 83, 26, 230, 152, 113, 152, 163, 194,
+ /* 690 */ 195, 92, 92, 30, 95, 83, 97, 98, 207, 208,
+ /* 700 */ 101, 206, 179, 180, 92, 172, 173, 95, 152, 97,
+ /* 710 */ 98, 188, 99, 101, 219, 102, 103, 104, 152, 119,
+ /* 720 */ 120, 196, 55, 56, 19, 20, 113, 22, 193, 163,
+ /* 730 */ 11, 132, 133, 134, 135, 136, 24, 65, 172, 173,
+ /* 740 */ 207, 208, 250, 152, 132, 133, 134, 135, 136, 193,
+ /* 750 */ 78, 84, 47, 48, 49, 98, 199, 152, 86, 54,
+ /* 760 */ 55, 56, 196, 152, 97, 98, 209, 55, 163, 244,
+ /* 770 */ 107, 66, 152, 207, 208, 164, 175, 172, 173, 19,
+ /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
+ /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
+ /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
+ /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
+ /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134,
+ /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
+ /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55,
+ /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
+ /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179,
+ /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
+ /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152,
+ /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5,
+ /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
+ /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152,
+ /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83,
+ /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98,
+ /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173,
+ /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47,
+ /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152,
+ /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133,
+ /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172,
+ /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30,
+ /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97,
+ /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42,
+ /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152,
+ /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152,
+ /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75,
+ /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172,
+ /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24,
+ /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152,
+ /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173,
+ /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172,
+ /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
+ /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213,
+ /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172,
+ /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26,
+ /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173,
+ /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173,
+ /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152,
+ /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152,
+ /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173,
+ /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173,
+ /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163,
+ /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167,
+ /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108,
+ /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163,
+ /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23,
+ /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26,
+ /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55,
+ /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26,
+ /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132,
+ /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191,
+ /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210,
+ /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97,
+ /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227,
+ /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175,
+ /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130,
+ /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159,
+ /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235,
+ /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177,
+ /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125,
+ /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53,
+ /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229,
+ /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25,
+ /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151,
+ /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22,
+ /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23,
+ /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16,
+ /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122,
+ /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80,
+ /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79,
+ /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68,
+ /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23,
+ /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23,
+ /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
+ /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23,
+ /* 1560 */ 23, 22, 15, 122, 122, 122, 23,
+};
+#define YY_SHIFT_USE_DFLT (1567)
#define YY_SHIFT_COUNT (455)
-#define YY_SHIFT_MIN (-114)
-#define YY_SHIFT_MAX (1562)
+#define YY_SHIFT_MIN (-94)
+#define YY_SHIFT_MAX (1549)
static const short yy_shift_ofst[] = {
- /* 0 */ 5, 1117, 1312, 1128, 1274, 1274, 1274, 1274, 61, -19,
- /* 10 */ 57, 57, 183, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 20 */ 66, 66, 201, -29, 331, 318, 133, 259, 335, 411,
- /* 30 */ 487, 563, 639, 689, 765, 841, 891, 891, 891, 891,
- /* 40 */ 891, 891, 891, 891, 891, 891, 891, 891, 891, 891,
- /* 50 */ 891, 891, 891, 941, 891, 991, 1041, 1041, 1217, 1274,
- /* 60 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 70 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 90 */ 1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 100 */ 1274, 1274, 1274, 1274, -70, -47, -47, -47, -47, -47,
- /* 110 */ 24, 11, 146, 296, 524, 444, 529, 529, 296, 3,
- /* 120 */ 2, -30, 1566, 1566, 1566, -17, -17, -17, 145, 145,
- /* 130 */ 497, 497, 265, 603, 653, 296, 296, 296, 296, 296,
- /* 140 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- /* 150 */ 296, 296, 296, 296, 296, 701, 1078, 147, 147, 2,
- /* 160 */ 164, 164, 164, 164, 164, 164, 1566, 1566, 1566, 223,
- /* 170 */ 56, 56, 268, 269, 220, 347, 351, 415, 359, 296,
- /* 180 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- /* 190 */ 296, 296, 296, 296, 296, 632, 632, 632, 296, 296,
- /* 200 */ 498, 296, 296, 296, 570, 296, 296, 654, 296, 296,
- /* 210 */ 296, 296, 296, 296, 296, 296, 296, 296, 636, 200,
- /* 220 */ 596, 596, 596, 575, -114, 971, 740, 454, 503, 503,
- /* 230 */ 1134, 454, 1134, 353, 588, 628, 762, 503, 189, 762,
- /* 240 */ 762, 916, 330, 668, 1245, 1167, 1167, 1255, 1255, 1167,
- /* 250 */ 1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172,
- /* 260 */ 1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167,
- /* 270 */ 1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258,
- /* 280 */ 1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288,
- /* 290 */ 1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267,
- /* 300 */ 1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407,
- /* 310 */ 1408, 1422, 1422, 1433, 1433, 1433, 1433, 1566, 1566, 1566,
- /* 320 */ 1566, 1566, 1566, 1566, 1566, 558, 537, 684, 719, 734,
- /* 330 */ 799, 840, 1019, 14, 1020, 1021, 1025, 1026, 1027, 1070,
- /* 340 */ 1072, 997, 1047, 999, 1079, 1126, 1074, 1141, 694, 819,
- /* 350 */ 1174, 1136, 981, 1445, 1451, 1434, 1313, 1448, 1398, 1450,
- /* 360 */ 1444, 1446, 1348, 1339, 1360, 1349, 1453, 1350, 1458, 1475,
- /* 370 */ 1354, 1347, 1401, 1402, 1403, 1404, 1372, 1388, 1452, 1364,
- /* 380 */ 1484, 1483, 1467, 1383, 1351, 1439, 1468, 1440, 1441, 1457,
- /* 390 */ 1395, 1479, 1485, 1487, 1392, 1405, 1486, 1455, 1489, 1490,
- /* 400 */ 1491, 1493, 1461, 1480, 1494, 1465, 1481, 1495, 1496, 1498,
- /* 410 */ 1497, 1406, 1502, 1503, 1505, 1499, 1409, 1506, 1507, 1432,
- /* 420 */ 1500, 1510, 1410, 1511, 1501, 1512, 1504, 1517, 1511, 1518,
- /* 430 */ 1519, 1520, 1521, 1522, 1524, 1533, 1525, 1527, 1509, 1526,
- /* 440 */ 1528, 1531, 1530, 1526, 1532, 1534, 1535, 1536, 1538, 1428,
- /* 450 */ 1435, 1442, 1443, 1539, 1546, 1562,
+ /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
+ /* 10 */ 16, 16, 100, 760, 760, 760, 760, 760, 760, 760,
+ /* 20 */ 876, 876, 573, 542, 719, 600, 61, 137, 172, 207,
+ /* 30 */ 242, 277, 312, 347, 382, 417, 459, 459, 459, 459,
+ /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+ /* 50 */ 459, 459, 459, 494, 459, 529, 564, 564, 705, 760,
+ /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
+ /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73,
+ /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99,
+ /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949,
+ /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
+ /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113,
+ /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922,
+ /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949,
+ /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
+ /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949,
+ /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949,
+ /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118,
+ /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418,
+ /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882,
+ /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238,
+ /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239,
+ /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238,
+ /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290,
+ /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304,
+ /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280,
+ /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414,
+ /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567,
+ /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104,
+ /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273,
+ /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177,
+ /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452,
+ /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479,
+ /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367,
+ /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429,
+ /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491,
+ /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498,
+ /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475,
+ /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517,
+ /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
+ /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436,
+ /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549,
};
-#define YY_REDUCE_USE_DFLT (-174)
+#define YY_REDUCE_USE_DFLT (-130)
#define YY_REDUCE_COUNT (324)
-#define YY_REDUCE_MIN (-173)
-#define YY_REDUCE_MAX (1293)
+#define YY_REDUCE_MIN (-129)
+#define YY_REDUCE_MAX (1300)
static const short yy_reduce_ofst[] = {
- /* 0 */ -119, 1014, 131, 1031, -12, 225, 228, 300, -40, -45,
- /* 10 */ 243, 256, 293, 129, 218, 418, 79, 376, 433, 298,
- /* 20 */ 16, 137, 367, 323, -38, 391, -173, -173, -173, -173,
- /* 30 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- /* 40 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- /* 50 */ -173, -173, -173, -173, -173, -173, -173, -173, 374, 437,
- /* 60 */ 443, 508, 513, 522, 532, 582, 584, 620, 633, 635,
- /* 70 */ 637, 644, 646, 648, 650, 652, 659, 661, 696, 709,
- /* 80 */ 711, 714, 720, 722, 724, 726, 728, 733, 772, 784,
- /* 90 */ 786, 822, 834, 836, 884, 886, 922, 934, 936, 986,
- /* 100 */ 989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173,
- /* 110 */ -173, -173, -173, 544, -37, 274, 299, 501, 161, -173,
- /* 120 */ 193, -173, -173, -173, -173, 22, 22, 22, 64, 141,
- /* 130 */ 212, 342, 208, 504, 504, 132, 494, 606, 677, 678,
- /* 140 */ 750, 794, 796, -58, 32, 383, 660, 737, 386, 787,
- /* 150 */ 800, 441, 872, 224, 850, 803, 949, 624, 830, 669,
- /* 160 */ 961, 979, 983, 1011, 1013, 1032, 753, 789, 321, 94,
- /* 170 */ 116, 304, 375, 210, 388, 392, 478, 545, 649, 721,
- /* 180 */ 727, 736, 752, 795, 853, 952, 958, 1004, 1040, 1046,
- /* 190 */ 1049, 1050, 1056, 1059, 1067, 559, 774, 811, 1068, 1080,
- /* 200 */ 938, 1082, 1083, 1088, 962, 1089, 1090, 1052, 1093, 1094,
- /* 210 */ 1095, 388, 1096, 1103, 1104, 1105, 1106, 1107, 965, 998,
- /* 220 */ 1055, 1057, 1058, 938, 1069, 1071, 1120, 1073, 1061, 1062,
- /* 230 */ 1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112,
- /* 240 */ 1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139,
- /* 250 */ 1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132,
- /* 260 */ 1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189,
- /* 270 */ 1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206,
- /* 280 */ 1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183,
- /* 290 */ 1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194,
- /* 300 */ 1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271,
- /* 310 */ 1275, 1284, 1285, 1289, 1290, 1292, 1293, 1201, 1208, 1216,
- /* 320 */ 1280, 1281, 1264, 1269, 1283,
+ /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
+ /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790,
+ /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76,
+ /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898,
+ /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950,
+ /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984,
+ /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021,
+ /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062,
+ /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76,
+ /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76,
+ /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
+ /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
+ /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047,
+ /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808,
+ /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57,
+ /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
+ /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908,
+ /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101,
+ /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171,
+ /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102,
+ /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130,
+ /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183,
+ /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205,
+ /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193,
+ /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231,
+ /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
+ /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
+ /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
+ /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
+ /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
+ /* 320 */ 1288, 1291, 1276, 1277, 1295,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 1280, 1270, 1270, 1270, 1202, 1202, 1202, 1202, 1270, 1096,
/* 10 */ 1125, 1125, 1254, 1332, 1332, 1332, 1332, 1332, 1332, 1201,
/* 20 */ 1332, 1332, 1332, 1332, 1270, 1100, 1131, 1332, 1332, 1332,
@@ -136286,77 +135700,104 @@
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 27, /* EXPLAIN => ID */
- 27, /* QUERY => ID */
- 27, /* PLAN => ID */
- 27, /* BEGIN => ID */
+ 55, /* EXPLAIN => ID */
+ 55, /* QUERY => ID */
+ 55, /* PLAN => ID */
+ 55, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 27, /* DEFERRED => ID */
- 27, /* IMMEDIATE => ID */
- 27, /* EXCLUSIVE => ID */
+ 55, /* DEFERRED => ID */
+ 55, /* IMMEDIATE => ID */
+ 55, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 27, /* END => ID */
- 27, /* ROLLBACK => ID */
- 27, /* SAVEPOINT => ID */
- 27, /* RELEASE => ID */
+ 55, /* END => ID */
+ 55, /* ROLLBACK => ID */
+ 55, /* SAVEPOINT => ID */
+ 55, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 27, /* IF => ID */
+ 55, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 27, /* TEMP => ID */
+ 55, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
- 27, /* WITHOUT => ID */
+ 55, /* WITHOUT => ID */
0, /* COMMA => nothing */
+ 0, /* OR => nothing */
+ 0, /* AND => nothing */
+ 0, /* IS => nothing */
+ 55, /* MATCH => ID */
+ 55, /* LIKE_KW => ID */
+ 0, /* BETWEEN => nothing */
+ 0, /* IN => nothing */
+ 0, /* ISNULL => nothing */
+ 0, /* NOTNULL => nothing */
+ 0, /* NE => nothing */
+ 0, /* EQ => nothing */
+ 0, /* GT => nothing */
+ 0, /* LE => nothing */
+ 0, /* LT => nothing */
+ 0, /* GE => nothing */
+ 0, /* ESCAPE => nothing */
+ 0, /* BITAND => nothing */
+ 0, /* BITOR => nothing */
+ 0, /* LSHIFT => nothing */
+ 0, /* RSHIFT => nothing */
+ 0, /* PLUS => nothing */
+ 0, /* MINUS => nothing */
+ 0, /* STAR => nothing */
+ 0, /* SLASH => nothing */
+ 0, /* REM => nothing */
+ 0, /* CONCAT => nothing */
+ 0, /* COLLATE => nothing */
+ 0, /* BITNOT => nothing */
0, /* ID => nothing */
- 27, /* ABORT => ID */
- 27, /* ACTION => ID */
- 27, /* AFTER => ID */
- 27, /* ANALYZE => ID */
- 27, /* ASC => ID */
- 27, /* ATTACH => ID */
- 27, /* BEFORE => ID */
- 27, /* BY => ID */
- 27, /* CASCADE => ID */
- 27, /* CAST => ID */
- 27, /* COLUMNKW => ID */
- 27, /* CONFLICT => ID */
- 27, /* DATABASE => ID */
- 27, /* DESC => ID */
- 27, /* DETACH => ID */
- 27, /* EACH => ID */
- 27, /* FAIL => ID */
- 27, /* FOR => ID */
- 27, /* IGNORE => ID */
- 27, /* INITIALLY => ID */
- 27, /* INSTEAD => ID */
- 27, /* LIKE_KW => ID */
- 27, /* MATCH => ID */
- 27, /* NO => ID */
- 27, /* KEY => ID */
- 27, /* OF => ID */
- 27, /* OFFSET => ID */
- 27, /* PRAGMA => ID */
- 27, /* RAISE => ID */
- 27, /* RECURSIVE => ID */
- 27, /* REPLACE => ID */
- 27, /* RESTRICT => ID */
- 27, /* ROW => ID */
- 27, /* TRIGGER => ID */
- 27, /* VACUUM => ID */
- 27, /* VIEW => ID */
- 27, /* VIRTUAL => ID */
- 27, /* WITH => ID */
- 27, /* REINDEX => ID */
- 27, /* RENAME => ID */
- 27, /* CTIME_KW => ID */
+ 0, /* INDEXED => nothing */
+ 55, /* ABORT => ID */
+ 55, /* ACTION => ID */
+ 55, /* AFTER => ID */
+ 55, /* ANALYZE => ID */
+ 55, /* ASC => ID */
+ 55, /* ATTACH => ID */
+ 55, /* BEFORE => ID */
+ 55, /* BY => ID */
+ 55, /* CASCADE => ID */
+ 55, /* CAST => ID */
+ 55, /* COLUMNKW => ID */
+ 55, /* CONFLICT => ID */
+ 55, /* DATABASE => ID */
+ 55, /* DESC => ID */
+ 55, /* DETACH => ID */
+ 55, /* EACH => ID */
+ 55, /* FAIL => ID */
+ 55, /* FOR => ID */
+ 55, /* IGNORE => ID */
+ 55, /* INITIALLY => ID */
+ 55, /* INSTEAD => ID */
+ 55, /* NO => ID */
+ 55, /* KEY => ID */
+ 55, /* OF => ID */
+ 55, /* OFFSET => ID */
+ 55, /* PRAGMA => ID */
+ 55, /* RAISE => ID */
+ 55, /* RECURSIVE => ID */
+ 55, /* REPLACE => ID */
+ 55, /* RESTRICT => ID */
+ 55, /* ROW => ID */
+ 55, /* TRIGGER => ID */
+ 55, /* VACUUM => ID */
+ 55, /* VIEW => ID */
+ 55, /* VIRTUAL => ID */
+ 55, /* WITH => ID */
+ 55, /* REINDEX => ID */
+ 55, /* RENAME => ID */
+ 55, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
/* The following structure represents a single element of the
** parser's stack. Information stored includes:
@@ -136444,29 +135885,29 @@
"PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
"IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
"TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
- "AS", "WITHOUT", "COMMA", "ID",
- "ABORT", "ACTION", "AFTER", "ANALYZE",
- "ASC", "ATTACH", "BEFORE", "BY",
- "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "NO",
- "KEY", "OF", "OFFSET", "PRAGMA",
- "RAISE", "RECURSIVE", "REPLACE", "RESTRICT",
- "ROW", "TRIGGER", "VACUUM", "VIEW",
- "VIRTUAL", "WITH", "REINDEX", "RENAME",
- "CTIME_KW", "ANY", "OR", "AND",
- "IS", "BETWEEN", "IN", "ISNULL",
- "NOTNULL", "NE", "EQ", "GT",
- "LE", "LT", "GE", "ESCAPE",
- "BITAND", "BITOR", "LSHIFT", "RSHIFT",
- "PLUS", "MINUS", "STAR", "SLASH",
- "REM", "CONCAT", "COLLATE", "BITNOT",
- "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT",
+ "AS", "WITHOUT", "COMMA", "OR",
+ "AND", "IS", "MATCH", "LIKE_KW",
+ "BETWEEN", "IN", "ISNULL", "NOTNULL",
+ "NE", "EQ", "GT", "LE",
+ "LT", "GE", "ESCAPE", "BITAND",
+ "BITOR", "LSHIFT", "RSHIFT", "PLUS",
+ "MINUS", "STAR", "SLASH", "REM",
+ "CONCAT", "COLLATE", "BITNOT", "ID",
+ "INDEXED", "ABORT", "ACTION", "AFTER",
+ "ANALYZE", "ASC", "ATTACH", "BEFORE",
+ "BY", "CASCADE", "CAST", "COLUMNKW",
+ "CONFLICT", "DATABASE", "DESC", "DETACH",
+ "EACH", "FAIL", "FOR", "IGNORE",
+ "INITIALLY", "INSTEAD", "NO", "KEY",
+ "OF", "OFFSET", "PRAGMA", "RAISE",
+ "RECURSIVE", "REPLACE", "RESTRICT", "ROW",
+ "TRIGGER", "VACUUM", "VIEW", "VIRTUAL",
+ "WITH", "REINDEX", "RENAME", "CTIME_KW",
+ "ANY", "STRING", "JOIN_KW", "CONSTRAINT",
"DEFAULT", "NULL", "PRIMARY", "UNIQUE",
"CHECK", "REFERENCES", "AUTOINCR", "ON",
"INSERT", "DELETE", "UPDATE", "SET",
"DEFERRABLE", "FOREIGN", "DROP", "UNION",
"ALL", "EXCEPT", "INTERSECT", "SELECT",
@@ -140061,11 +139502,11 @@
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->pVList);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFree(db, p);
}
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
@@ -143555,22 +142996,20 @@
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
}
#endif
#if defined(SQLITE_HAS_CODEC)
if( rc==SQLITE_OK ){
- const char *zKey;
- if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
+ const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
+ if( zHexKey && zHexKey[0] ){
u8 iByte;
int i;
- char zDecoded[40];
- for(i=0, iByte=0; i=0 );
+ *pi = (int)(a | ((u32)(*p & 0x0F) << 28));
return 5;
}
/*
** Return the number of bytes required to encode v as a varint
@@ -147020,70 +146457,69 @@
struct Fts4Option *pOp = &aFts4Opt[iOpt];
if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){
break;
}
}
- switch( iOpt ){
- case 0: /* MATCHINFO */
- if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bNoDocsize = 1;
- break;
-
- case 1: /* PREFIX */
- sqlite3_free(zPrefix);
- zPrefix = zVal;
- zVal = 0;
- break;
-
- case 2: /* COMPRESS */
- sqlite3_free(zCompress);
- zCompress = zVal;
- zVal = 0;
- break;
-
- case 3: /* UNCOMPRESS */
- sqlite3_free(zUncompress);
- zUncompress = zVal;
- zVal = 0;
- break;
-
- case 4: /* ORDER */
- if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
- && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
- ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
- break;
-
- case 5: /* CONTENT */
- sqlite3_free(zContent);
- zContent = zVal;
- zVal = 0;
- break;
-
- case 6: /* LANGUAGEID */
- assert( iOpt==6 );
- sqlite3_free(zLanguageid);
- zLanguageid = zVal;
- zVal = 0;
- break;
-
- case 7: /* NOTINDEXED */
- azNotindexed[nNotindexed++] = zVal;
- zVal = 0;
- break;
-
- default:
- assert( iOpt==SizeofArray(aFts4Opt) );
- sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
- rc = SQLITE_ERROR;
- break;
+ if( iOpt==SizeofArray(aFts4Opt) ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
+ rc = SQLITE_ERROR;
+ }else{
+ switch( iOpt ){
+ case 0: /* MATCHINFO */
+ if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bNoDocsize = 1;
+ break;
+
+ case 1: /* PREFIX */
+ sqlite3_free(zPrefix);
+ zPrefix = zVal;
+ zVal = 0;
+ break;
+
+ case 2: /* COMPRESS */
+ sqlite3_free(zCompress);
+ zCompress = zVal;
+ zVal = 0;
+ break;
+
+ case 3: /* UNCOMPRESS */
+ sqlite3_free(zUncompress);
+ zUncompress = zVal;
+ zVal = 0;
+ break;
+
+ case 4: /* ORDER */
+ if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
+ && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
+ ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
+ break;
+
+ case 5: /* CONTENT */
+ sqlite3_free(zContent);
+ zContent = zVal;
+ zVal = 0;
+ break;
+
+ case 6: /* LANGUAGEID */
+ assert( iOpt==6 );
+ sqlite3_free(zLanguageid);
+ zLanguageid = zVal;
+ zVal = 0;
+ break;
+
+ case 7: /* NOTINDEXED */
+ azNotindexed[nNotindexed++] = zVal;
+ zVal = 0;
+ break;
+ }
}
sqlite3_free(zVal);
}
}
@@ -147648,12 +147084,11 @@
zCsr += fts3GetVarint32(zCsr, &nPrefix);
}
isFirstTerm = 0;
zCsr += fts3GetVarint32(zCsr, &nSuffix);
- assert( nPrefix>=0 && nSuffix>=0 );
- if( &zCsr[nSuffix]>zEnd ){
+ if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
if( nPrefix+nSuffix>nAlloc ){
char *zNew;
@@ -148459,11 +147894,11 @@
bWritten = 1;
}
fts3ColumnlistCopy(0, &p);
}
- while( ppVtab;
/* The column value supplied by SQLite must be in range. */
assert( iCol>=0 && iCol<=p->nColumn+2 );
- switch( iCol-p->nColumn ){
- case 0:
- /* The special 'table-name' column */
- sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT);
- sqlite3_result_subtype(pCtx, SQLITE_BLOB);
- break;
-
- case 1:
- /* The docid column */
- sqlite3_result_int64(pCtx, pCsr->iPrevId);
- break;
-
- case 2:
- if( pCsr->pExpr ){
- sqlite3_result_int64(pCtx, pCsr->iLangid);
- break;
- }else if( p->zLanguageid==0 ){
- sqlite3_result_int(pCtx, 0);
- break;
- }else{
- iCol = p->nColumn;
- /* fall-through */
- }
-
- default:
- /* A user column. Or, if this is a full-table scan, possibly the
- ** language-id column. Seek the cursor. */
- rc = fts3CursorSeek(0, pCsr);
- if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
+ if( iCol==p->nColumn+1 ){
+ /* This call is a request for the "docid" column. Since "docid" is an
+ ** alias for "rowid", use the xRowid() method to obtain the value.
+ */
+ sqlite3_result_int64(pCtx, pCsr->iPrevId);
+ }else if( iCol==p->nColumn ){
+ /* The extra column whose name is the same as the table.
+ ** Return a blob which is a pointer to the cursor. */
+ sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
+ }else if( iCol==p->nColumn+2 && pCsr->pExpr ){
+ sqlite3_result_int64(pCtx, pCsr->iLangid);
+ }else{
+ /* The requested column is either a user column (one that contains
+ ** indexed data), or the language-id column. */
+ rc = fts3CursorSeek(0, pCsr);
+
+ if( rc==SQLITE_OK ){
+ if( iCol==p->nColumn+2 ){
+ int iLangid = 0;
+ if( p->zLanguageid ){
+ iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
+ }
+ sqlite3_result_int(pCtx, iLangid);
+ }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
}
- break;
+ }
}
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
return rc;
}
@@ -149250,15 +148680,21 @@
** if an error occurs.
*/
static int fts3SetHasStat(Fts3Table *p){
int rc = SQLITE_OK;
if( p->bHasStat==2 ){
- char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
- if( zTbl ){
- int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
- sqlite3_free(zTbl);
- p->bHasStat = (res==SQLITE_OK);
+ const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
+ char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
+ if( zSql ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ if( rc==SQLITE_OK ){
+ int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
+ rc = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat;
+ }
+ sqlite3_free(zSql);
}else{
rc = SQLITE_NOMEM;
}
}
return rc;
@@ -149361,20 +148797,22 @@
sqlite3_context *pContext, /* SQL function call context */
const char *zFunc, /* Function name */
sqlite3_value *pVal, /* argv[0] passed to function */
Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
){
- int rc = SQLITE_OK;
- if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){
- *ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal);
- }else{
+ Fts3Cursor *pRet;
+ if( sqlite3_value_type(pVal)!=SQLITE_BLOB
+ || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
+ ){
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
sqlite3_result_error(pContext, zErr, -1);
sqlite3_free(zErr);
- rc = SQLITE_ERROR;
+ return SQLITE_ERROR;
}
- return rc;
+ memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
+ *ppCsr = pRet;
+ return SQLITE_OK;
}
/*
** Implementation of the snippet() function for FTS3
*/
@@ -149757,11 +149195,11 @@
rc = sqlite3Fts3ExprInitTestInterface(db);
}
#endif
/* Create the virtual table wrapper around the hash-table and overload
- ** the four scalar functions. If this is successful, register the
+ ** the two scalar functions. If this is successful, register the
** module with sqlite.
*/
if( SQLITE_OK==rc
&& SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
@@ -150340,11 +149778,11 @@
/* This is only called if it is guaranteed that the phrase has at least
** one incremental token. In which case the bIncr flag is set. */
assert( p->bIncr==1 );
- if( p->nToken==1 ){
+ if( p->nToken==1 && p->bIncr ){
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
&pDL->iDocid, &pDL->pList, &pDL->nList
);
if( pDL->pList==0 ) bEof = 1;
}else{
@@ -150573,11 +150011,10 @@
** of data that will fit on a single leaf page of an intkey table in
** this database, then the average docsize is 1. Otherwise, it is 1 plus
** the number of overflow pages consumed by a record B bytes in size.
*/
static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
- int rc = SQLITE_OK;
if( pCsr->nRowAvg==0 ){
/* The average document size, which is required to calculate the cost
** of each doclist, has not yet been determined. Read the required
** data from the %_stat table to calculate it.
**
@@ -150586,10 +150023,11 @@
** The first varint is the number of documents currently stored in
** the table. The following nCol varints contain the total amount of
** data stored in all rows of each column of the table, from left
** to right.
*/
+ int rc;
Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
sqlite3_stmt *pStmt;
sqlite3_int64 nDoc = 0;
sqlite3_int64 nByte = 0;
const char *pEnd;
@@ -150612,14 +150050,15 @@
pCsr->nDoc = nDoc;
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
assert( pCsr->nRowAvg>0 );
rc = sqlite3_reset(pStmt);
+ if( rc!=SQLITE_OK ) return rc;
}
*pnPage = pCsr->nRowAvg;
- return rc;
+ return SQLITE_OK;
}
/*
** This function is called to select the tokens (if any) that will be
** deferred. The array aTC[] has already been populated when this is
@@ -150965,12 +150404,11 @@
}
}
pExpr->iDocid = pLeft->iDocid;
pExpr->bEof = (pLeft->bEof || pRight->bEof);
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
- assert( pRight->eType==FTSQUERY_PHRASE );
- if( pRight->pPhrase->doclist.aAll ){
+ if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
memset(pDl->pList, 0, pDl->nList);
fts3EvalNextRow(pCsr, pRight, pRc);
}
@@ -150995,11 +150433,11 @@
assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
fts3EvalNextRow(pCsr, pLeft, pRc);
- }else if( pLeft->bEof || iCmp>0 ){
+ }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
fts3EvalNextRow(pCsr, pRight, pRc);
}else{
fts3EvalNextRow(pCsr, pLeft, pRc);
fts3EvalNextRow(pCsr, pRight, pRc);
}
@@ -151087,51 +150525,55 @@
** left-hand child may be either a phrase or a NEAR node. There are
** no exceptions to this - it's the way the parser in fts3_expr.c works.
*/
if( *pRc==SQLITE_OK
&& pExpr->eType==FTSQUERY_NEAR
+ && pExpr->bEof==0
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
){
Fts3Expr *p;
int nTmp = 0; /* Bytes of temp space */
char *aTmp; /* Temp space for PoslistNearMerge() */
/* Allocate temporary working space. */
for(p=pExpr; p->pLeft; p=p->pLeft){
- assert( p->pRight->pPhrase->doclist.nList>0 );
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
- aTmp = sqlite3_malloc(nTmp*2);
- if( !aTmp ){
- *pRc = SQLITE_NOMEM;
+ if( nTmp==0 ){
res = 0;
}else{
- char *aPoslist = p->pPhrase->doclist.pList;
- int nToken = p->pPhrase->nToken;
-
- for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
- Fts3Phrase *pPhrase = p->pRight->pPhrase;
- int nNear = p->nNear;
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
-
- aPoslist = pExpr->pRight->pPhrase->doclist.pList;
- nToken = pExpr->pRight->pPhrase->nToken;
- for(p=pExpr->pLeft; p && res; p=p->pLeft){
- int nNear;
- Fts3Phrase *pPhrase;
- assert( p->pParent && p->pParent->pLeft==p );
- nNear = p->pParent->nNear;
- pPhrase = (
- p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
- );
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
- }
-
- sqlite3_free(aTmp);
+ aTmp = sqlite3_malloc(nTmp*2);
+ if( !aTmp ){
+ *pRc = SQLITE_NOMEM;
+ res = 0;
+ }else{
+ char *aPoslist = p->pPhrase->doclist.pList;
+ int nToken = p->pPhrase->nToken;
+
+ for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
+ Fts3Phrase *pPhrase = p->pRight->pPhrase;
+ int nNear = p->nNear;
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+ }
+
+ aPoslist = pExpr->pRight->pPhrase->doclist.pList;
+ nToken = pExpr->pRight->pPhrase->nToken;
+ for(p=pExpr->pLeft; p && res; p=p->pLeft){
+ int nNear;
+ Fts3Phrase *pPhrase;
+ assert( p->pParent && p->pParent->pLeft==p );
+ nNear = p->pParent->nNear;
+ pPhrase = (
+ p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
+ );
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+ }
+ }
+
+ sqlite3_free(aTmp);
+ }
}
return res;
}
@@ -167234,40 +166676,16 @@
, pRtree->zDb, pRtree->zName, zNewName
, pRtree->zDb, pRtree->zName, zNewName
, pRtree->zDb, pRtree->zName, zNewName
);
if( zSql ){
- nodeBlobReset(pRtree);
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
return rc;
}
-/*
-** The xSavepoint method.
-**
-** This module does not need to do anything to support savepoints. However,
-** it uses this hook to close any open blob handle. This is done because a
-** DROP TABLE command - which fortunately always opens a savepoint - cannot
-** succeed if there are any open blob handles. i.e. if the blob handle were
-** not closed here, the following would fail:
-**
-** BEGIN;
-** INSERT INTO rtree...
-** DROP TABLE ; -- Would fail with SQLITE_LOCKED
-** COMMIT;
-*/
-static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
- Rtree *pRtree = (Rtree *)pVtab;
- int iwt = pRtree->inWrTrans;
- UNUSED_PARAMETER(iSavepoint);
- pRtree->inWrTrans = 0;
- nodeBlobReset(pRtree);
- pRtree->inWrTrans = iwt;
- return SQLITE_OK;
-}
/*
** This function populates the pRtree->nRowEst variable with an estimate
** of the number of rows in the virtual table. If possible, this is based
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
@@ -167310,11 +166728,11 @@
return rc;
}
static sqlite3_module rtreeModule = {
- 2, /* iVersion */
+ 0, /* iVersion */
rtreeCreate, /* xCreate - create a table */
rtreeConnect, /* xConnect - connect to an existing table */
rtreeBestIndex, /* xBestIndex - Determine search strategy */
rtreeDisconnect, /* xDisconnect - Disconnect from a table */
rtreeDestroy, /* xDestroy - Drop a table */
@@ -167330,11 +166748,11 @@
rtreeEndTransaction, /* xSync - sync transaction */
rtreeEndTransaction, /* xCommit - commit transaction */
rtreeEndTransaction, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
- rtreeSavepoint, /* xSavepoint */
+ 0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
};
static int rtreeSqlInit(
@@ -179487,11 +178905,10 @@
#ifndef SQLITE_AMALGAMATION
/* Unsigned integer types. These are already defined in the sqliteInt.h,
** but the definitions need to be repeated for separate compilation. */
typedef sqlite3_uint64 u64;
typedef unsigned int u32;
- typedef unsigned short int u16;
typedef unsigned char u8;
#endif
/* Objects */
typedef struct JsonString JsonString;
@@ -179567,23 +178984,12 @@
JsonNode *aNode; /* Array of nodes containing the parse */
const char *zJson; /* Original JSON string */
u32 *aUp; /* Index of parent of each node */
u8 oom; /* Set to true if out of memory */
u8 nErr; /* Number of errors seen */
- u16 iDepth; /* Nesting depth */
- int nJson; /* Length of the zJson string in bytes */
};
-/*
-** Maximum nesting depth of JSON for this implementation.
-**
-** This limit is needed to avoid a stack overflow in the recursive
-** descent parser. A depth of 2000 is far deeper than any sane JSON
-** should go.
-*/
-#define JSON_MAX_DEPTH 2000
-
/**************************************************************************
** Utility routines for dealing with JsonString objects
**************************************************************************/
/* Set the JsonString object to an empty string
@@ -179811,18 +179217,10 @@
pParse->nAlloc = 0;
sqlite3_free(pParse->aUp);
pParse->aUp = 0;
}
-/*
-** Free a JsonParse object that was obtained from sqlite3_malloc().
-*/
-static void jsonParseFree(JsonParse *pParse){
- jsonParseReset(pParse);
- sqlite3_free(pParse);
-}
-
/*
** Convert the JsonNode pNode into a pure JSON string and
** append to pOut. Subsubstructure is also included. Return
** the number of JsonNode objects that are encoded.
*/
@@ -180144,39 +179542,35 @@
char c;
u32 j;
int iThis;
int x;
JsonNode *pNode;
- const char *z = pParse->zJson;
- while( safe_isspace(z[i]) ){ i++; }
- if( (c = z[i])=='{' ){
+ while( safe_isspace(pParse->zJson[i]) ){ i++; }
+ if( (c = pParse->zJson[i])=='{' ){
/* Parse object */
iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
if( iThis<0 ) return -1;
for(j=i+1;;j++){
- while( safe_isspace(z[j]) ){ j++; }
- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j);
if( x<0 ){
- pParse->iDepth--;
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
return -1;
}
if( pParse->oom ) return -1;
pNode = &pParse->aNode[pParse->nNode-1];
if( pNode->eType!=JSON_STRING ) return -1;
pNode->jnFlags |= JNODE_LABEL;
j = x;
- while( safe_isspace(z[j]) ){ j++; }
- if( z[j]!=':' ) return -1;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ if( pParse->zJson[j]!=':' ) return -1;
j++;
x = jsonParseValue(pParse, j);
- pParse->iDepth--;
if( x<0 ) return -1;
j = x;
- while( safe_isspace(z[j]) ){ j++; }
- c = z[j];
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ c = pParse->zJson[j];
if( c==',' ) continue;
if( c!='}' ) return -1;
break;
}
pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
@@ -180184,21 +179578,19 @@
}else if( c=='[' ){
/* Parse array */
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
if( iThis<0 ) return -1;
for(j=i+1;;j++){
- while( safe_isspace(z[j]) ){ j++; }
- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j);
- pParse->iDepth--;
if( x<0 ){
if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
return -1;
}
j = x;
- while( safe_isspace(z[j]) ){ j++; }
- c = z[j];
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ c = pParse->zJson[j];
if( c==',' ) continue;
if( c!=']' ) return -1;
break;
}
pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
@@ -180206,83 +179598,75 @@
}else if( c=='"' ){
/* Parse string */
u8 jnFlags = 0;
j = i+1;
for(;;){
- c = z[j];
- if( (c & ~0x1f)==0 ){
- /* Control characters are not allowed in strings */
- return -1;
- }
+ c = pParse->zJson[j];
+ if( c==0 ) return -1;
if( c=='\\' ){
- c = z[++j];
+ c = pParse->zJson[++j];
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|| c=='n' || c=='r' || c=='t'
- || (c=='u' && jsonIs4Hex(z+j+1)) ){
+ || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
jnFlags = JNODE_ESCAPE;
}else{
return -1;
}
}else if( c=='"' ){
break;
}
j++;
}
- jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
+ jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
return j+1;
}else if( c=='n'
- && strncmp(z+i,"null",4)==0
- && !safe_isalnum(z[i+4]) ){
+ && strncmp(pParse->zJson+i,"null",4)==0
+ && !safe_isalnum(pParse->zJson[i+4]) ){
jsonParseAddNode(pParse, JSON_NULL, 0, 0);
return i+4;
}else if( c=='t'
- && strncmp(z+i,"true",4)==0
- && !safe_isalnum(z[i+4]) ){
+ && strncmp(pParse->zJson+i,"true",4)==0
+ && !safe_isalnum(pParse->zJson[i+4]) ){
jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
return i+4;
}else if( c=='f'
- && strncmp(z+i,"false",5)==0
- && !safe_isalnum(z[i+5]) ){
+ && strncmp(pParse->zJson+i,"false",5)==0
+ && !safe_isalnum(pParse->zJson[i+5]) ){
jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
return i+5;
}else if( c=='-' || (c>='0' && c<='9') ){
/* Parse number */
u8 seenDP = 0;
u8 seenE = 0;
- assert( '-' < '0' );
- if( c<='0' ){
- j = c=='-' ? i+1 : i;
- if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
- }
j = i+1;
for(;; j++){
- c = z[j];
+ c = pParse->zJson[j];
if( c>='0' && c<='9' ) continue;
if( c=='.' ){
- if( z[j-1]=='-' ) return -1;
+ if( pParse->zJson[j-1]=='-' ) return -1;
if( seenDP ) return -1;
seenDP = 1;
continue;
}
if( c=='e' || c=='E' ){
- if( z[j-1]<'0' ) return -1;
+ if( pParse->zJson[j-1]<'0' ) return -1;
if( seenE ) return -1;
seenDP = seenE = 1;
- c = z[j+1];
+ c = pParse->zJson[j+1];
if( c=='+' || c=='-' ){
j++;
- c = z[j+1];
+ c = pParse->zJson[j+1];
}
if( c<'0' || c>'9' ) return -1;
continue;
}
break;
}
- if( z[j-1]<'0' ) return -1;
+ if( pParse->zJson[j-1]<'0' ) return -1;
jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
- j - i, &z[i]);
+ j - i, &pParse->zJson[i]);
return j;
}else if( c=='}' ){
return -2; /* End of {...} */
}else if( c==']' ){
return -3; /* End of [...] */
@@ -180310,11 +179694,10 @@
if( zJson==0 ) return 1;
pParse->zJson = zJson;
i = jsonParseValue(pParse, 0);
if( pParse->oom ) i = -1;
if( i>0 ){
- assert( pParse->iDepth==0 );
while( safe_isspace(zJson[i]) ) i++;
if( zJson[i] ) i = -1;
}
if( i<=0 ){
if( pCtx!=0 ){
@@ -180370,53 +179753,10 @@
}
jsonParseFillInParentage(pParse, 0, 0);
return SQLITE_OK;
}
-/*
-** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
-*/
-#define JSON_CACHE_ID (-429938)
-
-/*
-** Obtain a complete parse of the JSON found in the first argument
-** of the argv array. Use the sqlite3_get_auxdata() cache for this
-** parse if it is available. If the cache is not available or if it
-** is no longer valid, parse the JSON again and return the new parse,
-** and also register the new parse so that it will be available for
-** future sqlite3_get_auxdata() calls.
-*/
-static JsonParse *jsonParseCached(
- sqlite3_context *pCtx,
- sqlite3_value **argv
-){
- const char *zJson = (const char*)sqlite3_value_text(argv[0]);
- int nJson = sqlite3_value_bytes(argv[0]);
- JsonParse *p;
- if( zJson==0 ) return 0;
- p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
- if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
- p->nErr = 0;
- return p; /* The cached entry matches, so return it */
- }
- p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
- if( p==0 ){
- sqlite3_result_error_nomem(pCtx);
- return 0;
- }
- memset(p, 0, sizeof(*p));
- p->zJson = (char*)&p[1];
- memcpy((char*)p->zJson, zJson, nJson+1);
- if( jsonParse(p, pCtx, p->zJson) ){
- sqlite3_free(p);
- return 0;
- }
- p->nJson = nJson;
- sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
- return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
-}
-
/*
** Compare the OBJECT label at pNode against zKey,nKey. Return true on
** a match.
*/
static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
@@ -180778,34 +180118,33 @@
static void jsonArrayLengthFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
- JsonParse *p; /* The parse */
+ JsonParse x; /* The parse */
sqlite3_int64 n = 0;
u32 i;
JsonNode *pNode;
- p = jsonParseCached(ctx, argv);
- if( p==0 ) return;
- assert( p->nNode );
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
if( argc==2 ){
const char *zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(p, zPath, 0, ctx);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
}else{
- pNode = p->aNode;
+ pNode = x.aNode;
}
if( pNode==0 ){
- return;
- }
- if( pNode->eType==JSON_ARRAY ){
+ x.nErr = 1;
+ }else if( pNode->eType==JSON_ARRAY ){
assert( (pNode->jnFlags & JNODE_APPEND)==0 );
for(i=1; i<=pNode->n; n++){
i += jsonNodeSize(&pNode[i]);
}
}
- sqlite3_result_int64(ctx, n);
+ if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
+ jsonParseReset(&x);
}
/*
** json_extract(JSON, PATH, ...)
**
@@ -180817,25 +180156,24 @@
static void jsonExtractFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
- JsonParse *p; /* The parse */
+ JsonParse x; /* The parse */
JsonNode *pNode;
const char *zPath;
JsonString jx;
int i;
if( argc<2 ) return;
- p = jsonParseCached(ctx, argv);
- if( p==0 ) return;
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
jsonInit(&jx, ctx);
jsonAppendChar(&jx, '[');
for(i=1; inErr ) break;
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) break;
if( argc>2 ){
jsonAppendSeparator(&jx);
if( pNode ){
jsonRenderNode(pNode, &jx, 0);
}else{
@@ -180849,17 +180187,18 @@
jsonAppendChar(&jx, ']');
jsonResult(&jx);
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
jsonReset(&jx);
+ jsonParseReset(&x);
}
/* This is the RFC 7396 MergePatch algorithm.
*/
static JsonNode *jsonMergePatch(
JsonParse *pParse, /* The JSON parser that contains the TARGET */
- u32 iTarget, /* Node of the TARGET in pParse */
+ int iTarget, /* Node of the TARGET in pParse */
JsonNode *pPatch /* The PATCH */
){
u32 i, j;
u32 iRoot;
JsonNode *pTarget;
@@ -182864,13 +182203,13 @@
i64 iDocid /* Docid to add or remove data from */
);
/*
** Flush any data stored in the in-memory hash tables to the database.
-** Also close any open blob handles.
+** If the bCommit flag is true, also close any open blob handles.
*/
-static int sqlite3Fts5IndexSync(Fts5Index *p);
+static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
/*
** Discard any data stored in the in-memory hash tables. Do not write it
** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
@@ -183036,11 +182375,11 @@
static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
-static int sqlite3Fts5StorageSync(Fts5Storage *p);
+static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
static int sqlite3Fts5StorageRollback(Fts5Storage *p);
static int sqlite3Fts5StorageConfigValue(
Fts5Storage *p, const char*, sqlite3_value*, int
);
@@ -183072,11 +182411,10 @@
};
/* Parse a MATCH expression. */
static int sqlite3Fts5ExprNew(
Fts5Config *pConfig,
- int iCol, /* Column on LHS of MATCH operator */
const char *zExpr,
Fts5Expr **ppNew,
char **pzErr
);
@@ -183157,11 +182495,11 @@
static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
-static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
+static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
/*
@@ -183214,16 +182552,16 @@
#define FTS5_OR 1
#define FTS5_AND 2
#define FTS5_NOT 3
#define FTS5_TERM 4
#define FTS5_COLON 5
-#define FTS5_MINUS 6
-#define FTS5_LCP 7
-#define FTS5_RCP 8
-#define FTS5_STRING 9
-#define FTS5_LP 10
-#define FTS5_RP 11
+#define FTS5_LP 6
+#define FTS5_RP 7
+#define FTS5_MINUS 8
+#define FTS5_LCP 9
+#define FTS5_RCP 10
+#define FTS5_STRING 11
#define FTS5_COMMA 12
#define FTS5_PLUS 13
#define FTS5_STAR 14
/*
@@ -183355,20 +182693,20 @@
#endif
#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
-#define fts5YYNSTATE 33
-#define fts5YYNRULE 27
-#define fts5YY_MAX_SHIFT 32
-#define fts5YY_MIN_SHIFTREDUCE 50
-#define fts5YY_MAX_SHIFTREDUCE 76
-#define fts5YY_MIN_REDUCE 77
-#define fts5YY_MAX_REDUCE 103
-#define fts5YY_ERROR_ACTION 104
-#define fts5YY_ACCEPT_ACTION 105
-#define fts5YY_NO_ACTION 106
+#define fts5YYNSTATE 29
+#define fts5YYNRULE 26
+#define fts5YY_MAX_SHIFT 28
+#define fts5YY_MIN_SHIFTREDUCE 45
+#define fts5YY_MAX_SHIFTREDUCE 70
+#define fts5YY_MIN_REDUCE 71
+#define fts5YY_MAX_REDUCE 96
+#define fts5YY_ERROR_ACTION 97
+#define fts5YY_ACCEPT_ACTION 98
+#define fts5YY_NO_ACTION 99
/************* End control #defines *******************************************/
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
@@ -183436,58 +182774,54 @@
** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
** shifting non-terminals after a reduce.
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (98)
+#define fts5YY_ACTTAB_COUNT (85)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 105, 19, 63, 6, 26, 66, 65, 24, 24, 17,
- /* 10 */ 63, 6, 26, 16, 65, 54, 24, 18, 63, 6,
- /* 20 */ 26, 10, 65, 12, 24, 75, 59, 63, 6, 26,
- /* 30 */ 13, 65, 75, 24, 20, 63, 6, 26, 74, 65,
- /* 40 */ 56, 24, 27, 63, 6, 26, 73, 65, 21, 24,
- /* 50 */ 23, 15, 30, 11, 1, 64, 22, 25, 9, 65,
- /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77,
- /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12,
- /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32,
- /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14,
+ /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15,
+ /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5,
+ /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53,
+ /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68,
+ /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27,
+ /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21,
+ /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59,
+ /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69,
+ /* 80 */ 25, 66, 8, 14, 2,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
- /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
- /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
- /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20,
- /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22,
- /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
- /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22,
- /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0,
- /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9,
- /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25,
- /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9,
+ /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17,
+ /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19,
+ /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20,
+ /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26,
+ /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21,
+ /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24,
+ /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11,
+ /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14,
+ /* 80 */ 13, 11, 5, 11, 3,
};
-#define fts5YY_SHIFT_USE_DFLT (98)
-#define fts5YY_SHIFT_COUNT (32)
+#define fts5YY_SHIFT_USE_DFLT (85)
+#define fts5YY_SHIFT_COUNT (28)
#define fts5YY_SHIFT_MIN (0)
-#define fts5YY_SHIFT_MAX (90)
+#define fts5YY_SHIFT_MAX (81)
static const unsigned char fts5yy_shift_ofst[] = {
- /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14,
- /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69,
- /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87,
- /* 30 */ 88, 39, 71,
+ /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1,
+ /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63,
+ /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81,
};
-#define fts5YY_REDUCE_USE_DFLT (-18)
-#define fts5YY_REDUCE_COUNT (16)
-#define fts5YY_REDUCE_MIN (-17)
-#define fts5YY_REDUCE_MAX (67)
+#define fts5YY_REDUCE_USE_DFLT (-17)
+#define fts5YY_REDUCE_COUNT (14)
+#define fts5YY_REDUCE_MIN (-16)
+#define fts5YY_REDUCE_MAX (54)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17,
- /* 10 */ 67, 12, 12, 12, 20, 27, 35,
+ /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13,
+ /* 10 */ 13, 22, 54, 13, 51,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104,
- /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104,
- /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104,
- /* 30 */ 104, 97, 104,
+ /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96,
+ /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97,
+ /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72,
};
/********** End of lemon-generated parsing tables *****************************/
/* The next table maps tokens (terminal symbols) into fallback tokens.
** If a construct like the following:
@@ -183589,50 +182923,49 @@
#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
"$", "OR", "AND", "NOT",
- "TERM", "COLON", "MINUS", "LCP",
- "RCP", "STRING", "LP", "RP",
+ "TERM", "COLON", "LP", "RP",
+ "MINUS", "LCP", "RCP", "STRING",
"COMMA", "PLUS", "STAR", "error",
"input", "expr", "cnearset", "exprlist",
- "colset", "colsetlist", "nearset", "nearphrases",
+ "nearset", "colset", "colsetlist", "nearphrases",
"phrase", "neardist_opt", "star_opt",
};
#endif /* NDEBUG */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const fts5yyRuleName[] = {
/* 0 */ "input ::= expr",
- /* 1 */ "colset ::= MINUS LCP colsetlist RCP",
- /* 2 */ "colset ::= LCP colsetlist RCP",
- /* 3 */ "colset ::= STRING",
- /* 4 */ "colset ::= MINUS STRING",
- /* 5 */ "colsetlist ::= colsetlist STRING",
- /* 6 */ "colsetlist ::= STRING",
- /* 7 */ "expr ::= expr AND expr",
- /* 8 */ "expr ::= expr OR expr",
- /* 9 */ "expr ::= expr NOT expr",
- /* 10 */ "expr ::= colset COLON LP expr RP",
- /* 11 */ "expr ::= LP expr RP",
- /* 12 */ "expr ::= exprlist",
- /* 13 */ "exprlist ::= cnearset",
- /* 14 */ "exprlist ::= exprlist cnearset",
- /* 15 */ "cnearset ::= nearset",
- /* 16 */ "cnearset ::= colset COLON nearset",
- /* 17 */ "nearset ::= phrase",
- /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 19 */ "nearphrases ::= phrase",
- /* 20 */ "nearphrases ::= nearphrases phrase",
- /* 21 */ "neardist_opt ::=",
- /* 22 */ "neardist_opt ::= COMMA STRING",
- /* 23 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 24 */ "phrase ::= STRING star_opt",
- /* 25 */ "star_opt ::= STAR",
- /* 26 */ "star_opt ::=",
+ /* 1 */ "expr ::= expr AND expr",
+ /* 2 */ "expr ::= expr OR expr",
+ /* 3 */ "expr ::= expr NOT expr",
+ /* 4 */ "expr ::= LP expr RP",
+ /* 5 */ "expr ::= exprlist",
+ /* 6 */ "exprlist ::= cnearset",
+ /* 7 */ "exprlist ::= exprlist cnearset",
+ /* 8 */ "cnearset ::= nearset",
+ /* 9 */ "cnearset ::= colset COLON nearset",
+ /* 10 */ "colset ::= MINUS LCP colsetlist RCP",
+ /* 11 */ "colset ::= LCP colsetlist RCP",
+ /* 12 */ "colset ::= STRING",
+ /* 13 */ "colset ::= MINUS STRING",
+ /* 14 */ "colsetlist ::= colsetlist STRING",
+ /* 15 */ "colsetlist ::= STRING",
+ /* 16 */ "nearset ::= phrase",
+ /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 18 */ "nearphrases ::= phrase",
+ /* 19 */ "nearphrases ::= nearphrases phrase",
+ /* 20 */ "neardist_opt ::=",
+ /* 21 */ "neardist_opt ::= COMMA STRING",
+ /* 22 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 23 */ "phrase ::= STRING star_opt",
+ /* 24 */ "star_opt ::= STAR",
+ /* 25 */ "star_opt ::=",
};
#endif /* NDEBUG */
#if fts5YYSTACKDEPTH<=0
@@ -183758,21 +183091,21 @@
case 19: /* exprlist */
{
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
}
break;
- case 20: /* colset */
- case 21: /* colsetlist */
-{
- sqlite3_free((fts5yypminor->fts5yy11));
-}
- break;
- case 22: /* nearset */
+ case 20: /* nearset */
case 23: /* nearphrases */
{
sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
}
+ break;
+ case 21: /* colset */
+ case 22: /* colsetlist */
+{
+ sqlite3_free((fts5yypminor->fts5yy11));
+}
break;
case 24: /* phrase */
{
sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
}
@@ -184027,28 +183360,27 @@
static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} fts5yyRuleInfo[] = {
{ 16, 1 },
- { 20, 4 },
- { 20, 3 },
- { 20, 1 },
- { 20, 2 },
- { 21, 2 },
- { 21, 1 },
+ { 17, 3 },
{ 17, 3 },
{ 17, 3 },
- { 17, 3 },
- { 17, 5 },
{ 17, 3 },
{ 17, 1 },
{ 19, 1 },
{ 19, 2 },
{ 18, 1 },
{ 18, 3 },
+ { 21, 4 },
+ { 21, 3 },
+ { 21, 1 },
+ { 21, 2 },
+ { 22, 2 },
{ 22, 1 },
- { 22, 5 },
+ { 20, 1 },
+ { 20, 5 },
{ 23, 1 },
{ 23, 2 },
{ 25, 0 },
{ 25, 2 },
{ 24, 4 },
@@ -184119,139 +183451,132 @@
/********** Begin reduce actions **********************************************/
fts5YYMINORTYPE fts5yylhsminor;
case 0: /* input ::= expr */
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
break;
- case 1: /* colset ::= MINUS LCP colsetlist RCP */
-{
- fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 2: /* colset ::= LCP colsetlist RCP */
-{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
- break;
- case 3: /* colset ::= STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 4: /* colset ::= MINUS STRING */
-{
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 5: /* colsetlist ::= colsetlist STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
- fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 6: /* colsetlist ::= STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 7: /* expr ::= expr AND expr */
+ case 1: /* expr ::= expr AND expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 8: /* expr ::= expr OR expr */
+ case 2: /* expr ::= expr OR expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 9: /* expr ::= expr NOT expr */
+ case 3: /* expr ::= expr NOT expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 10: /* expr ::= colset COLON LP expr RP */
-{
- sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
- fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
-}
- fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 11: /* expr ::= LP expr RP */
+ case 4: /* expr ::= LP expr RP */
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
break;
- case 12: /* expr ::= exprlist */
- case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
+ case 5: /* expr ::= exprlist */
+ case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 14: /* exprlist ::= exprlist cnearset */
+ case 7: /* exprlist ::= exprlist cnearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
}
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 15: /* cnearset ::= nearset */
+ case 8: /* cnearset ::= nearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 16: /* cnearset ::= colset COLON nearset */
+ case 9: /* cnearset ::= colset COLON nearset */
{
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11);
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
- sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 17: /* nearset ::= phrase */
+ case 10: /* colset ::= MINUS LCP colsetlist RCP */
+{
+ fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+}
+ break;
+ case 11: /* colset ::= LCP colsetlist RCP */
+{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
+ break;
+ case 12: /* colset ::= STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 13: /* colset ::= MINUS STRING */
+{
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+}
+ break;
+ case 14: /* colsetlist ::= colsetlist STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
+ fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 15: /* colsetlist ::= STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 16: /* nearset ::= phrase */
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
}
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 19: /* nearphrases ::= phrase */
+ case 18: /* nearphrases ::= phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 20: /* nearphrases ::= nearphrases phrase */
+ case 19: /* nearphrases ::= nearphrases phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 21: /* neardist_opt ::= */
+ case 20: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
- case 22: /* neardist_opt ::= COMMA STRING */
+ case 21: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
- case 23: /* phrase ::= phrase PLUS STRING star_opt */
+ case 22: /* phrase ::= phrase PLUS STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 24: /* phrase ::= STRING star_opt */
+ case 23: /* phrase ::= STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 25: /* star_opt ::= STAR */
+ case 24: /* star_opt ::= STAR */
{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
- case 26: /* star_opt ::= */
+ case 25: /* star_opt ::= */
{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
break;
/********** End reduce actions ************************************************/
@@ -185289,15 +184614,13 @@
Fts5Buffer *pBuf,
u32 nData,
const u8 *pData
){
assert_nc( *pRc || nData>=0 );
- if( nData ){
- if( fts5BufferGrow(pRc, pBuf, nData) ) return;
- memcpy(&pBuf->p[pBuf->n], pData, nData);
- pBuf->n += nData;
- }
+ if( fts5BufferGrow(pRc, pBuf, nData) ) return;
+ memcpy(&pBuf->p[pBuf->n], pData, nData);
+ pBuf->n += nData;
}
/*
** Append the nul-terminated string zStr to the buffer pBuf. This function
** ensures that the byte following the buffer data is set to 0x00, even
@@ -185470,12 +184793,12 @@
static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
void *pRet = 0;
if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc(nByte);
- if( pRet==0 ){
- if( nByte>0 ) *pRc = SQLITE_NOMEM;
+ if( pRet==0 && nByte>0 ){
+ *pRc = SQLITE_NOMEM;
}else{
memset(pRet, 0, nByte);
}
}
return pRet;
@@ -186792,11 +186115,10 @@
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
static void fts5ParseFree(void *p){ sqlite3_free(p); }
static int sqlite3Fts5ExprNew(
Fts5Config *pConfig, /* FTS5 Configuration */
- int iCol,
const char *zExpr, /* Expression text */
Fts5Expr **ppNew,
char **pzErr
){
Fts5Parse sParse;
@@ -186817,22 +186139,10 @@
t = fts5ExprGetToken(&sParse, &z, &token);
sqlite3Fts5Parser(pEngine, t, token, &sParse);
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
- /* If the LHS of the MATCH expression was a user column, apply the
- ** implicit column-filter. */
- if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
- int n = sizeof(Fts5Colset);
- Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
- if( pColset ){
- pColset->nCol = 1;
- pColset->aiCol[0] = iCol;
- sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
- }
- }
-
assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
if( sParse.rc==SQLITE_OK ){
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
if( pNew==0 ){
sParse.rc = SQLITE_NOMEM;
@@ -188478,114 +187788,29 @@
}
return pRet;
}
-/*
-** If argument pOrig is NULL, or if (*pRc) is set to anything other than
-** SQLITE_OK when this function is called, NULL is returned.
-**
-** Otherwise, a copy of (*pOrig) is made into memory obtained from
-** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
-** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
-*/
-static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
- Fts5Colset *pRet;
- if( pOrig ){
- int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
- pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
- if( pRet ){
- memcpy(pRet, pOrig, nByte);
- }
- }else{
- pRet = 0;
- }
- return pRet;
-}
-
-/*
-** Remove from colset pColset any columns that are not also in colset pMerge.
-*/
-static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
- int iIn = 0; /* Next input in pColset */
- int iMerge = 0; /* Next input in pMerge */
- int iOut = 0; /* Next output slot in pColset */
-
- while( iInnCol && iMergenCol ){
- int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
- if( iDiff==0 ){
- pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
- iMerge++;
- iIn++;
- }else if( iDiff>0 ){
- iMerge++;
- }else{
- iIn++;
- }
- }
- pColset->nCol = iOut;
-}
-
-/*
-** Recursively apply colset pColset to expression node pNode and all of
-** its decendents. If (*ppFree) is not NULL, it contains a spare copy
-** of pColset. This function may use the spare copy and set (*ppFree) to
-** zero, or it may create copies of pColset using fts5CloneColset().
-*/
-static void fts5ParseSetColset(
- Fts5Parse *pParse,
- Fts5ExprNode *pNode,
- Fts5Colset *pColset,
- Fts5Colset **ppFree
-){
- if( pParse->rc==SQLITE_OK ){
- assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
- || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
- || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
- );
- if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
- Fts5ExprNearset *pNear = pNode->pNear;
- if( pNear->pColset ){
- fts5MergeColset(pNear->pColset, pColset);
- if( pNear->pColset->nCol==0 ){
- pNode->eType = FTS5_EOF;
- pNode->xNext = 0;
- }
- }else if( *ppFree ){
- pNear->pColset = pColset;
- *ppFree = 0;
- }else{
- pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
- }
- }else{
- int i;
- assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
- for(i=0; inChild; i++){
- fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
- }
- }
- }
-}
-
-/*
-** Apply colset pColset to expression node pExpr and all of its descendents.
-*/
static void sqlite3Fts5ParseSetColset(
Fts5Parse *pParse,
- Fts5ExprNode *pExpr,
+ Fts5ExprNearset *pNear,
Fts5Colset *pColset
){
- Fts5Colset *pFree = pColset;
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
pParse->rc = SQLITE_ERROR;
pParse->zErr = sqlite3_mprintf(
"fts5: column queries are not supported (detail=none)"
);
+ sqlite3_free(pColset);
+ return;
+ }
+
+ if( pNear ){
+ pNear->pColset = pColset;
}else{
- fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
+ sqlite3_free(pColset);
}
- sqlite3_free(pFree);
}
static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
switch( pNode->eType ){
case FTS5_STRING: {
@@ -189035,11 +188260,11 @@
zExpr = (const char*)sqlite3_value_text(apVal[0]);
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
+ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
}
if( rc==SQLITE_OK ){
char *zText;
if( pExpr->pRoot->xNext==0 ){
zText = sqlite3_mprintf("");
@@ -189432,14 +188657,13 @@
Fts5HashEntry **aSlot; /* Array of hash slots */
};
/*
** Each entry in the hash table is represented by an object of the
-** following type. Each object, its key (a nul-terminated string) and
-** its current data are stored in a single memory allocation. The
-** key immediately follows the object in memory. The position list
-** data immediately follows the key data in memory.
+** following type. Each object, its key (zKey[]) and its current data
+** are stored in a single memory allocation. The position list data
+** immediately follows the key data in memory.
**
** The data that follows the key is in a similar, but not identical format
** to the doclist data stored in the database. It is:
**
** * Rowid, as a varint
@@ -189459,24 +188683,24 @@
Fts5HashEntry *pScanNext; /* Next entry in sorted order */
int nAlloc; /* Total size of allocation */
int iSzPoslist; /* Offset of space for 4-byte poslist size */
int nData; /* Total bytes of data (incl. structure) */
- int nKey; /* Length of key in bytes */
+ int nKey; /* Length of zKey[] in bytes */
u8 bDel; /* Set delete-flag @ iSzPoslist */
u8 bContent; /* Set content-flag (detail=none mode) */
i16 iCol; /* Column of last value written */
int iPos; /* Position of last value written */
i64 iRowid; /* Rowid of last value written */
+ char zKey[8]; /* Nul-terminated entry key */
};
/*
-** Eqivalent to:
-**
-** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
+** Size of Fts5HashEntry without the zKey[] array.
*/
-#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
+#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8)
+
/*
** Allocate a new hash table.
*/
@@ -189570,11 +188794,11 @@
for(i=0; inSlot; i++){
while( apOld[i] ){
int iHash;
Fts5HashEntry *p = apOld[i];
apOld[i] = p->pHashNext;
- iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), strlen(fts5EntryKey(p)));
+ iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
p->pHashNext = apNew[iHash];
apNew[iHash] = p;
}
}
@@ -189641,24 +188865,22 @@
bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
/* Attempt to locate an existing hash entry */
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- char *zKey = fts5EntryKey(p);
- if( zKey[0]==bByte
+ if( p->zKey[0]==bByte
&& p->nKey==nToken
- && memcmp(&zKey[1], pToken, nToken)==0
+ && memcmp(&p->zKey[1], pToken, nToken)==0
){
break;
}
}
/* If an existing hash entry cannot be found, create a new one. */
if( p==0 ){
/* Figure out how much space to allocate */
- char *zKey;
- int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
+ int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
if( nByte<128 ) nByte = 128;
/* Grow the Fts5Hash.aSlot[] array if necessary. */
if( (pHash->nEntry*2)>=pHash->nSlot ){
int rc = fts5HashResize(pHash);
@@ -189667,19 +188889,18 @@
}
/* Allocate new Fts5HashEntry and add it to the hash table. */
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
if( !p ) return SQLITE_NOMEM;
- memset(p, 0, sizeof(Fts5HashEntry));
+ memset(p, 0, FTS5_HASHENTRYSIZE);
p->nAlloc = nByte;
- zKey = fts5EntryKey(p);
- zKey[0] = bByte;
- memcpy(&zKey[1], pToken, nToken);
- assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
+ p->zKey[0] = bByte;
+ memcpy(&p->zKey[1], pToken, nToken);
+ assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
p->nKey = nToken;
- zKey[nToken+1] = '\0';
- p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
+ p->zKey[nToken+1] = '\0';
+ p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
p->pHashNext = pHash->aSlot[iHash];
pHash->aSlot[iHash] = p;
pHash->nEntry++;
/* Add the first rowid field to the hash-entry */
@@ -189793,15 +189014,13 @@
}else if( p2==0 ){
*ppOut = p1;
p1 = 0;
}else{
int i = 0;
- char *zKey1 = fts5EntryKey(p1);
- char *zKey2 = fts5EntryKey(p2);
- while( zKey1[i]==zKey2[i] ) i++;
+ while( p1->zKey[i]==p2->zKey[i] ) i++;
- if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
+ if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){
/* p2 is smaller */
*ppOut = p2;
ppOut = &p2->pScanNext;
p2 = p2->pScanNext;
}else{
@@ -189840,11 +189059,11 @@
memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
for(iSlot=0; iSlotnSlot; iSlot++){
Fts5HashEntry *pIter;
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
- if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
+ if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){
Fts5HashEntry *pEntry = pIter;
pEntry->pScanNext = 0;
for(i=0; ap[i]; i++){
pEntry = fts5HashEntryMerge(pEntry, ap[i]);
ap[i] = 0;
@@ -189873,22 +189092,20 @@
const char *pTerm, int nTerm, /* Query term */
const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
int *pnDoclist /* OUT: Size of doclist in bytes */
){
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
- char *zKey;
Fts5HashEntry *p;
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- zKey = fts5EntryKey(p);
- if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
+ if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break;
}
if( p ){
fts5HashAddPoslistSize(pHash, p);
- *ppDoclist = (const u8*)&zKey[nTerm+1];
- *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
+ *ppDoclist = (const u8*)&p->zKey[nTerm+1];
+ *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
}else{
*ppDoclist = 0;
*pnDoclist = 0;
}
@@ -189917,16 +189134,15 @@
const u8 **ppDoclist, /* OUT: pointer to doclist */
int *pnDoclist /* OUT: size of doclist in bytes */
){
Fts5HashEntry *p;
if( (p = pHash->pScan) ){
- char *zKey = fts5EntryKey(p);
- int nTerm = (int)strlen(zKey);
+ int nTerm = (int)strlen(p->zKey);
fts5HashAddPoslistSize(pHash, p);
- *pzTerm = zKey;
- *ppDoclist = (const u8*)&zKey[nTerm+1];
- *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
+ *pzTerm = p->zKey;
+ *ppDoclist = (const u8*)&p->zKey[nTerm+1];
+ *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
}else{
*pzTerm = 0;
*ppDoclist = 0;
*pnDoclist = 0;
}
@@ -190560,10 +189776,11 @@
sqlite3_blob *pReader = p->pReader;
p->pReader = 0;
sqlite3_blob_close(pReader);
}
}
+
/*
** Retrieve a record from the %_data table.
**
** If an error occurs, NULL is returned and an error left in the
@@ -192811,12 +192028,11 @@
Fts5Iter *pIter,
int *pbNewTerm /* OUT: True if *might* be new term */
){
assert( pIter->bSkipEmpty );
if( p->rc==SQLITE_OK ){
- *pbNewTerm = 0;
- do{
+ do {
int iFirst = pIter->aFirst[1].iFirst;
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
int bNewTerm = 0;
assert( p->rc==SQLITE_OK );
@@ -192825,10 +192041,12 @@
|| fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
){
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
fts5MultiIterSetEof(pIter);
*pbNewTerm = 1;
+ }else{
+ *pbNewTerm = 0;
}
fts5AssertMultiIterSetup(p, pIter);
}while( fts5MultiIterIsEmpty(p, pIter) );
}
@@ -193090,27 +192308,27 @@
}
return p - (*pa);
}
-static void fts5IndexExtractColset(
- int *pRc,
+static int fts5IndexExtractColset (
Fts5Colset *pColset, /* Colset to filter on */
const u8 *pPos, int nPos, /* Position list */
Fts5Buffer *pBuf /* Output buffer */
){
- if( *pRc==SQLITE_OK ){
- int i;
- fts5BufferZero(pBuf);
- for(i=0; inCol; i++){
- const u8 *pSub = pPos;
- int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
- if( nSub ){
- fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
- }
+ int rc = SQLITE_OK;
+ int i;
+
+ fts5BufferZero(pBuf);
+ for(i=0; inCol; i++){
+ const u8 *pSub = pPos;
+ int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
+ if( nSub ){
+ fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
}
}
+ return rc;
}
/*
** xSetOutputs callback used by detail=none tables.
*/
@@ -193230,13 +192448,12 @@
const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
if( pColset->nCol==1 ){
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
pIter->base.pData = a;
}else{
- int *pRc = &pIter->pIndex->rc;
fts5BufferZero(&pIter->poslist);
- fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
+ fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
pIter->base.pData = pIter->poslist.p;
pIter->base.nData = pIter->poslist.n;
}
}else{
/* The data is distributed over two or more pages. Copy it into the
@@ -193776,10 +192993,13 @@
static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 };
Fts5PageWriter *pPage = &pWriter->writer;
i64 iRowid;
+
+static int nCall = 0;
+nCall++;
assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
/* Set the szLeaf header field. */
assert( 0==fts5GetU16(&pPage->buf.p[2]) );
@@ -194125,11 +193345,10 @@
Fts5StructureSegment *pSeg; /* Output segment */
Fts5Buffer term;
int bOldest; /* True if the output segment is the oldest */
int eDetail = p->pConfig->eDetail;
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
- int bTermWritten = 0; /* True if current term already output */
assert( iLvlnLevel );
assert( pLvl->nMerge<=pLvl->nSeg );
memset(&writer, 0, sizeof(Fts5SegWriter));
@@ -194179,26 +193398,22 @@
Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
int nPos; /* position-list size field value */
int nTerm;
const u8 *pTerm;
+ /* Check for key annihilation. */
+ if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
+
pTerm = fts5MultiIterTerm(pIter, &nTerm);
if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
if( pnRem && writer.nLeafWritten>nRem ){
break;
}
- fts5BufferSet(&p->rc, &term, nTerm, pTerm);
- bTermWritten =0;
- }
-
- /* Check for key annihilation. */
- if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
-
- if( p->rc==SQLITE_OK && bTermWritten==0 ){
+
/* This is a new term. Append a term to the output segment. */
fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
- bTermWritten = 1;
+ fts5BufferSet(&p->rc, &term, nTerm, pTerm);
}
/* Append the rowid to the output */
/* WRITEPOSLISTSIZE */
fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));
@@ -195026,11 +194241,11 @@
pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = doclist.n;
- if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
+ memcpy(pData->p, doclist.p, doclist.n);
fts5MultiIterNew2(p, pData, bDesc, ppIter);
}
fts5BufferFree(&doclist);
}
@@ -195065,14 +194280,14 @@
}
/*
** Commit data to disk.
*/
-static int sqlite3Fts5IndexSync(Fts5Index *p){
+static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
- fts5CloseReader(p);
+ if( bCommit ) fts5CloseReader(p);
return fts5IndexReturn(p);
}
/*
** Discard any data stored in the in-memory hash tables. Do not write it
@@ -195265,11 +194480,11 @@
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
int iIdx = 0; /* Index to search */
- if( nToken ) memcpy(&buf.p[1], pToken, nToken);
+ memcpy(&buf.p[1], pToken, nToken);
/* Figure out which index to search and set iIdx accordingly. If this
** is a prefix query for which there is no prefix index, set iIdx to
** greater than pConfig->nPrefix to indicate that the query will be
** satisfied by scanning multiple terms in the main index.
@@ -195314,11 +194529,11 @@
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
}
if( p->rc ){
- sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
+ sqlite3Fts5IterClose(&pRet->base);
pRet = 0;
fts5CloseReader(p);
}
*ppIter = &pRet->base;
@@ -196932,11 +196147,10 @@
** Costs are not modified by the ORDER BY clause.
*/
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts5Table *pTab = (Fts5Table*)pVTab;
Fts5Config *pConfig = pTab->pConfig;
- const int nCol = pConfig->nCol;
int idxFlags = 0; /* Parameter passed through to xFilter() */
int bHasMatch;
int iNext;
int i;
@@ -196958,38 +196172,28 @@
FTS5_BI_ROWID_GE, 0, 0, -1},
};
int aColMap[3];
aColMap[0] = -1;
- aColMap[1] = nCol;
- aColMap[2] = nCol+1;
+ aColMap[1] = pConfig->nCol;
+ aColMap[2] = pConfig->nCol+1;
/* Set idxFlags flags for all WHERE clause terms that will be used. */
for(i=0; inConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
- int iCol = p->iColumn;
-
- if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
- || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
- ){
- /* A MATCH operator or equivalent */
- if( p->usable ){
- idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
- aConstraint[0].iConsIndex = i;
- }else{
- /* As there exists an unusable MATCH constraint this is an
- ** unusable plan. Set a prohibitively high cost. */
- pInfo->estimatedCost = 1e50;
- return SQLITE_OK;
- }
- }else{
- int j;
- for(j=1; jiCol] && p->op & pC->op && p->usable ){
+ int j;
+ for(j=0; jiColumn==aColMap[pC->iCol] && p->op & pC->op ){
+ if( p->usable ){
pC->iConsIndex = i;
idxFlags |= pC->fts5op;
+ }else if( j==0 ){
+ /* As there exists an unusable MATCH constraint this is an
+ ** unusable plan. Set a prohibitively high cost. */
+ pInfo->estimatedCost = 1e50;
+ return SQLITE_OK;
}
}
}
}
@@ -197560,11 +196764,10 @@
sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */
sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
- int iCol; /* Column on LHS of MATCH operator */
char **pzErrmsg = pConfig->pzErrmsg;
UNUSED_PARAM(zUnused);
UNUSED_PARAM(nVal);
@@ -197591,12 +196794,10 @@
if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
- iCol = (idxNum>>16);
- assert( iCol>=0 && iCol<=pConfig->nCol );
assert( iVal==nVal );
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
/* Set the cursor upper and lower rowid limits. Only some strategies
@@ -197639,11 +196840,11 @@
** indicates that the MATCH expression is not a full text query,
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
}else{
char **pzErr = &pTab->base.zErrMsg;
- rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
+ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr);
if( rc==SQLITE_OK ){
if( bOrderByRank ){
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
}else{
@@ -198019,11 +197220,11 @@
int rc;
Fts5Table *pTab = (Fts5Table*)pVtab;
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
fts5TripCursors(pTab);
- rc = sqlite3Fts5StorageSync(pTab->pStorage);
+ rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
pTab->pConfig->pzErrmsg = 0;
return rc;
}
/*
@@ -198830,11 +198031,11 @@
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage);
+ return sqlite3Fts5StorageSync(pTab->pStorage, 0);
}
/*
** The xRelease() method.
**
@@ -198843,11 +198044,11 @@
static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage);
+ return sqlite3Fts5StorageSync(pTab->pStorage, 0);
}
/*
** The xRollbackTo() method.
**
@@ -199054,11 +198255,11 @@
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2017-05-25 16:50:27 edb4e819b0c058c7d74d27ebd14cc5ceb2bad6a6144a486a970182b7afe3f8b9", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
static const sqlite3_module fts5Mod = {
/* iVersion */ 2,
@@ -199390,11 +198591,11 @@
}
}
static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
Fts5Config *pConfig = pStorage->pConfig;
- int rc = sqlite3Fts5StorageSync(pStorage);
+ int rc = sqlite3Fts5StorageSync(pStorage, 1);
fts5StorageRenameOne(pConfig, &rc, "data", zName);
fts5StorageRenameOne(pConfig, &rc, "idx", zName);
fts5StorageRenameOne(pConfig, &rc, "config", zName);
if( pConfig->bColumnsize ){
@@ -200253,19 +199454,19 @@
}
/*
** Flush any data currently held in-memory to disk.
*/
-static int sqlite3Fts5StorageSync(Fts5Storage *p){
+static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
int rc = SQLITE_OK;
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
if( p->bTotalsValid ){
rc = fts5StorageSaveTotals(p);
- p->bTotalsValid = 0;
+ if( bCommit ) p->bTotalsValid = 0;
}
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexSync(p->pIndex);
+ rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
}
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
return rc;
}
Index: src/sqlite3.h
==================================================================
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -119,13 +119,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.19.2"
-#define SQLITE_VERSION_NUMBER 3019002
-#define SQLITE_SOURCE_ID "2017-05-25 16:50:27 edb4e819b0c058c7d74d27ebd14cc5ceb2bad6a6144a486a970182b7afe3f8b9"
+#define SQLITE_VERSION "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -855,11 +855,11 @@
** of 25 milliseconds before the first retry and with the delay increasing
** by an additional 25 milliseconds with each subsequent retry. This
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer is the new retry count and the second
+** integers where the first integer i the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
** interrogated. The zDbName parameter is ignored.
**
@@ -2209,10 +2209,13 @@
** that are started after the running statement count reaches zero are
** not effected by the sqlite3_interrupt().
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
+**
+** If the database connection closes while [sqlite3_interrupt()]
+** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2671,11 +2674,10 @@
SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
-** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
@@ -2699,26 +2701,20 @@
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are either NULL pointers or zero-terminated strings
-** that contain additional details about the action to be authorized.
-** Applications must always be prepared to encounter a NULL pointer in any
-** of the third through the sixth parameters of the authorization callback.
+** to the callback are zero-terminated strings that contain additional
+** details about the action to be authorized.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
-** ^When a table is referenced by a [SELECT] but no column values are
-** extracted from that table (for example in a query like
-** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
-** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
**
** An authorizer is used when [sqlite3_prepare | preparing]
@@ -3707,11 +3703,11 @@
** Unprotected sqlite3_value objects may only be used with
** [sqlite3_result_value()] and [sqlite3_bind_value()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct sqlite3_value sqlite3_value;
+typedef struct Mem sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
@@ -4761,15 +4757,14 @@
** metadata associated with the pattern string.
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
-** value to the application-defined function. ^N is zero for the left-most
-** function argument. ^If there is no metadata
-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata() function with the Nth argument
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function. ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
@@ -4796,14 +4791,10 @@
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
-** The value of the N parameter to these interfaces should be non-negative.
-** Future enhancements may make use of negative N values to define new
-** kinds of function caching behavior.
-**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
@@ -9394,11 +9385,11 @@
**
** As well as the regular sqlite3changegroup_add() and
** sqlite3changegroup_output() functions, also available are the streaming
** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
*/
-SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
+int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
@@ -9471,11 +9462,11 @@
** function returns SQLITE_NOMEM. In all cases, if an error occurs the
** final contents of the changegroup is undefined.
**
** If no error occurs, SQLITE_OK is returned.
*/
-SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
@@ -9497,20 +9488,20 @@
** is returned and the output variables are set to the size of and a
** pointer to the output buffer, respectively. In this case it is the
** responsibility of the caller to eventually free the buffer using a
** call to sqlite3_free().
*/
-SQLITE_API int sqlite3changegroup_output(
+int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
);
/*
** CAPI3REF: Delete A Changegroup Object
*/
-SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
**
** Apply a changeset to a database. This function attempts to update the
@@ -9895,15 +9886,15 @@
SQLITE_API int sqlite3session_patchset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
+int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
Index: src/stat.c
==================================================================
--- src/stat.c
+++ src/stat.c
@@ -178,15 +178,15 @@
@ %h(p) %h(db_get("parent-project-name","")) |
}
/* @ Server ID: | %h(db_get("server-code","")) |
*/
@ Fossil Version: |
@ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
- @ (%h(RELEASE_VERSION)) (details)
+ @ (%h(RELEASE_VERSION)) (details)
@ |
@ SQLite Version: | %.19s(sqlite3_sourceid())
@ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))
- @ (details) |
+ @ (details)
if( g.eHashPolicy!=HPOLICY_AUTO ){
@ Schema Version: | %h(g.zAuxSchema),
@ %s(hpolicy_name()) |
}else{
@ Schema Version: | %h(g.zAuxSchema) |
@@ -341,11 +341,10 @@
** Show ways in which this repository has been accessed
*/
void urllist_page(void){
Stmt q;
int cnt;
- char *zRemote;
login_check_credentials();
if( !g.perm.Admin ){ login_needed(0); return; }
style_header("URLs and Checkouts");
style_adunit_config(ADUNIT_RIGHT_OK);
@@ -379,22 +378,10 @@
db_finalize(&q);
if( cnt==0 ){
@ (none) |
}
@
- zRemote = db_text(0, "SELECT value FROM config WHERE name='last-sync-url'");
- if( zRemote ){
- @ Last Sync URL
- if( sqlite3_strlike("http%", zRemote, 0)==0 ){
- UrlData x;
- url_parse_local(zRemote, URL_OMIT_USER, &x);
- @ %h(zRemote)
- }else{
- @
%h(zRemote)
- }
- @
- }
style_footer();
}
/*
** WEBPAGE: repo_schema
Index: src/tag.c
==================================================================
--- src/tag.c
+++ src/tag.c
@@ -587,11 +587,11 @@
}
/*
** COMMAND: reparent*
**
-** Usage: %fossil reparent [OPTIONS] CHECK-IN PARENT ...
+** Usage: %fossil reparent [OPTIONS] CHECK-IN PARENT ....
**
** Create a "parent" tag that causes CHECK-IN to be interpreted as a
** child of PARENT. If multiple PARENTs are listed, then the first is
** the primary parent and others are merge ancestors.
**
@@ -619,11 +619,11 @@
if( find_option("dryrun","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc<4 ){
- usage("[OPTIONS] CHECK-IN PARENT ...");
+ usage("reparent [OPTIONS] PARENT ...");
}
rid = name_to_typed_rid(g.argv[2], "ci");
blob_init(&value, 0, 0);
for(i=3; i> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
+ return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+ int iHi = count(aEntry) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aEntry[iTest] ){
iRes = iTest;
@@ -203,11 +201,11 @@
'e', 'i', 'o', 'u', 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
int iRes = 0;
- int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
+ int iHi = count(aDia) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aDia[iTest] ){
iRes = iTest;
@@ -350,11 +348,11 @@
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
const struct TableEntry *p;
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+ int iHi = count(aEntry) - 1;
int iLo = 0;
int iRes = -1;
assert( c>aEntry[0].iCode );
while( iHi>=iLo ){
Index: src/url.c
==================================================================
--- src/url.c
+++ src/url.c
@@ -38,11 +38,10 @@
#define URL_PROMPT_PW 0x001 /* Prompt for password if needed */
#define URL_REMEMBER 0x002 /* Remember the url for later reuse */
#define URL_ASK_REMEMBER_PW 0x004 /* Ask whether to remember prompted pw */
#define URL_REMEMBER_PW 0x008 /* Should remember pw */
#define URL_PROMPTED 0x010 /* Prompted for PW already */
-#define URL_OMIT_USER 0x020 /* Omit the user name from URL */
/*
** The URL related data used with this subsystem.
*/
struct UrlData {
@@ -154,15 +153,11 @@
dehttpize(pUrlData->passwd);
}
if( pUrlData->isSsh ){
urlFlags &= ~URL_ASK_REMEMBER_PW;
}
- if( urlFlags & URL_OMIT_USER ){
- zLogin = mprintf("");
- }else{
- zLogin = mprintf("%t@", pUrlData->user);
- }
+ zLogin = mprintf("%t@", pUrlData->user);
for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
pUrlData->name = mprintf("%.*s", j-i-1, &zUrl[i+1]);
i = j;
}else{
int inSquare = 0;
Index: src/winhttp.c
==================================================================
--- src/winhttp.c
+++ src/winhttp.c
@@ -306,11 +306,10 @@
SOCKADDR_IN addr;
int idCnt = 0;
int iPort = mnPort;
Blob options;
wchar_t zTmpPath[MAX_PATH];
- const char *zSkin;
#if USE_SEE
const char *zSavedKey = 0;
size_t savedKeySize = 0;
#endif
@@ -331,14 +330,10 @@
blob_appendf(&options, " --th-trace");
}
if( flags & HTTP_SERVER_REPOLIST ){
blob_appendf(&options, " --repolist");
}
- zSkin = skin_in_use();
- if( zSkin ){
- blob_appendf(&options, " --skin %s", zSkin);
- }
#if USE_SEE
zSavedKey = db_get_saved_encryption_key();
savedKeySize = db_get_saved_encryption_key_size();
if( zSavedKey!=0 && savedKeySize>0 ){
blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
Index: test/commit-warning.test
==================================================================
--- test/commit-warning.test
+++ test/commit-warning.test
@@ -16,11 +16,11 @@
############################################################################
#
# The focus of this file is to test pre-commit warnings.
#
-test_setup
+test_setup
# binary
write_file binary "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
# text with CRLF lines
@@ -60,13 +60,13 @@
set a15 $a14$a14
set a16 $a15$a15
write_file line-64K "$a16\n"
# UTF-8 extends 7-bit ASCII using bytes 80 and above to encode
-# larger character codes. Unicode uses U+0 through U+10FFFF only,
+# larger character codes. Unicode uses U+0 through U+10FFFF only,
# with U+D800 through U+DFFF reserved for surrogate pairs.
-# UTF-8 is valid if it is the shortest possible coding, encodes a
+# UTF-8 is valid if it is the shortest possible coding, encodes a
# valid Unicode code point. But it's complicated.
write_file utf-mod-c0-80 "11 bit NUL:\xC0\x80 is sometimes ok\n"
write_file utf-bad-e0-80-80 "16 bit NUL:\xE0\x80\x80 is bad\n"
write_file utf-bad-f0-80-80-80 "21 bit NUL:\xF0\x80\x80\x80 is bad\n"
write_file utf-bad-f8-80-80-80-80 "26 bit NUL:\xF8\x80\x80\x80\x80 is bad\n"
@@ -99,15 +99,15 @@
write_file utf-16be-bombe-hello "$bomBE$hello16BE"
write_file utf-16le-bombe-hello "$bomBE$hello16LE"
write_file utf-16be-bomle-hello "$bomLE$hello16BE"
set le16 [read_file [file join $testdir utf16le.txt]]
set be16 [read_file [file join $testdir utf16be.txt]]
-write_file utf-16le.txt $le16
+write_file utf-16le.txt $le16
write_file utf-16be.txt $be16
-write_file utf-nobom-16le.txt [string range $le16 2 end]
+write_file utf-nobom-16le.txt [string range $le16 2 end]
write_file utf-nobom-16be.txt [string range $be16 2 end]
-#write_file [file join $::env(TEMP) utf-nobom-16le.txt] [string range $le16 2 end]
+#write_file [file join $::env(TEMP) utf-nobom-16le.txt] [string range $le16 2 end]
#write_file [file join $::env(TEMP) utf-nobom-16be.txt] [string range $be16 2 end]
# make all the test files known to fossil, then test
fossil addremove
fossil test-commit-warning --no-settings -v
@@ -157,11 +157,11 @@
###############################################################################
# TODO: Change to a collection of test-case crafted files
# rather than depend on this list of files that will
# be fragile as development progresses.
-#
+#
# Unless the real goal of this test is to document a collection
# of source files that MUST NEVER BE TEXT.
#
run_in_checkout {
fossil test-commit-warning --no-settings
@@ -296,10 +296,10 @@
1\twww/fossil3.gif\tbinary data
1\twww/fossil_logo_small.gif\tbinary data
1\twww/fossil_logo_small2.gif\tbinary data
1\twww/fossil_logo_small3.gif\tbinary data
1\twww/xkcd-git.gif\tbinary data
-1}]]}
+1}]]}
###############################################################################
test_cleanup
Index: test/merge5.test
==================================================================
--- test/merge5.test
+++ test/merge5.test
@@ -18,11 +18,11 @@
# Tests of the "merge" command
#
puts "Skipping Merge5 tests"
protOut {
-fossil sqlite3 --no-repository reacts badly to SQL dumped from
+fossil sqlite3 --no-repository reacts badly to SQL dumped from
repositories created from fossil older than version 2.0.
}
test merge5-sqlite3-issue false knownBug
test_cleanup_then_return
Index: test/tester.tcl
==================================================================
--- test/tester.tcl
+++ test/tester.tcl
@@ -338,11 +338,11 @@
set y [read_file $b]
regsub -all { +\n} $y \n y
return [expr {$x==$y}]
}
-# Return true if two strings refer to the
+# Return true if two strings refer to the
# same uuid. That is, the shorter is a prefix
# of the longer.
#
proc same_uuid {a b} {
set na [string length $a]
Index: test/th1.test
==================================================================
--- test/th1.test
+++ test/th1.test
@@ -1579,11 +1579,11 @@
file delete $th1FileName
###############################################################################
# Tests for the TH1 unversioned command require at least one
-# unversioned file in the repository. All tests run in a freshly
+# unversioned file in the repository. All tests run in a freshly
# created checkout of a freshly created repo, so we can just
# create a file or two for the purpose.
write_file ten.txt "0123456789"
fossil unversioned add ten.txt
fossil unversioned list
Index: win/Makefile.mingw
==================================================================
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -980,11 +980,11 @@
SQLITE3_SHELL_SRC.0 = shell.c
SQLITE3_SHELL_SRC.1 = shell-see.c
SQLITE3_SHELL_SRC. = shell.c
SQLITE3_SHELL_SRC = $(SRCDIR)/$(SQLITE3_SHELL_SRC.$(USE_SEE))
SEE_FLAGS.0 =
-SEE_FLAGS.1 = -DSQLITE_HAS_CODEC -DSQLITE_SHELL_DBKEY_PROC=fossil_key
+SEE_FLAGS.1 = -DSQLITE_HAS_CODEC
SEE_FLAGS. =
SEE_FLAGS = $(SEE_FLAGS.$(USE_SEE))
EXTRAOBJ = \
@@ -2250,11 +2250,11 @@
$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
$(OBJDIR)/shell.o: $(SQLITE3_SHELL_SRC) $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw
- $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) -c $(SQLITE3_SHELL_SRC) -o $@
+ $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SQLITE3_SHELL_SRC) -o $@
$(OBJDIR)/th.o: $(SRCDIR)/th.c
$(XTCC) -c $(SRCDIR)/th.c -o $@
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
Index: win/Makefile.mingw.mistachkin
==================================================================
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -980,11 +980,11 @@
SQLITE3_SHELL_SRC.0 = shell.c
SQLITE3_SHELL_SRC.1 = shell-see.c
SQLITE3_SHELL_SRC. = shell.c
SQLITE3_SHELL_SRC = $(SRCDIR)/$(SQLITE3_SHELL_SRC.$(USE_SEE))
SEE_FLAGS.0 =
-SEE_FLAGS.1 = -DSQLITE_HAS_CODEC -DSQLITE_SHELL_DBKEY_PROC=fossil_key
+SEE_FLAGS.1 = -DSQLITE_HAS_CODEC
SEE_FLAGS. =
SEE_FLAGS = $(SEE_FLAGS.$(USE_SEE))
EXTRAOBJ = \
@@ -2250,11 +2250,11 @@
$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $@
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
$(OBJDIR)/shell.o: $(SQLITE3_SHELL_SRC) $(SRCDIR)/sqlite3.h $(SRCDIR)/../win/Makefile.mingw.mistachkin
- $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) -c $(SQLITE3_SHELL_SRC) -o $@
+ $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SQLITE3_SHELL_SRC) -o $@
$(OBJDIR)/th.o: $(SRCDIR)/th.c
$(XTCC) -c $(SRCDIR)/th.c -o $@
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
Index: win/Makefile.msc
==================================================================
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -867,21 +867,23 @@
codecheck1$E: $(SRCDIR)\codecheck1.c
$(BCC) $**
!if $(USE_SEE)!=0
-SEE_FLAGS = /DSQLITE_HAS_CODEC=1 /DSQLITE_SHELL_DBKEY_PROC=fossil_key
SQLITE3_SHELL_SRC = $(SRCDIR)\shell-see.c
-SQLITE3_SRC = $(SRCDIR)\sqlite3-see.c
!else
-SEE_FLAGS =
SQLITE3_SHELL_SRC = $(SRCDIR)\shell.c
-SQLITE3_SRC = $(SRCDIR)\sqlite3.c
!endif
$(OX)\shell$O : $(SQLITE3_SHELL_SRC) $B\win\Makefile.msc
- $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) -c $(SQLITE3_SHELL_SRC)
+ $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SQLITE3_SHELL_SRC)
+
+!if $(USE_SEE)!=0
+SQLITE3_SRC = $(SRCDIR)\sqlite3-see.c
+!else
+SQLITE3_SRC = $(SRCDIR)\sqlite3.c
+!endif
$(OX)\sqlite3$O : $(SQLITE3_SRC) $B\win\Makefile.msc
$(TCC) /Fo$@ -c $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) $(SQLITE3_SRC)
$(OX)\th$O : $(SRCDIR)\th.c
Index: www/aboutdownload.wiki
==================================================================
--- www/aboutdownload.wiki
+++ www/aboutdownload.wiki
@@ -11,19 +11,19 @@
for a list of all unversioned files. Javascript within the
download.html page then figures out which unversioned files are
build products and paints appropriate icons on the displayed
download page.
-When a new version is generated, the developers use the
+When a new version is generated, the developers us the
[/help?cmd=uv|fossil uv edit] command to make minor changes
to the "[/uv/download.html?mimetype=text/plain|download.html]"
file so that it knows about the
new version number. Then the developers run
-the [/help?cmd=uv|fossil uv add] command for each
+the [/help?cmd=uv|fossil uv add] command for each
build product. Finally, the
[/help?cmd=uv|fossil uv sync] command is run to push all
-the content up to servers. All
+the content up to servers. All
[./selfhost.wiki|three self-hosting repositories] for Fossil
are updated automatically.
2.0 Details
@@ -82,11 +82,11 @@
Only users with the [/setup_ulist_notes|"y" permission] are allowed
to push unversioned content up to the servers. Having the ability
to push check-ins (the [/setup_ulist_notes|"i" permission]) is not
sufficient.
-On the Fossil project there are 67 people (as of 2017-03-24) who have
-check-in privileges. But only 3 core developers
-can push unversioned content and thus
+On the Fossil project there are 67 people (as of 2017-03-24) who have
+check-in privileges. But only 3 core developers
+have the ability push unversioned content and thus
change the build products on the download page. Minimizing the number
of people who can change the build products helps to ensure that
rogue binaries do not slip onto the download page unnoticed.
Index: www/changes.wiki
==================================================================
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,19 +1,7 @@
Change Log
-
-Changes for Version 2.3 (2017-06-??, preferably just after the Unicode 10 release)
-
- * Update the built-in SQLite to version 3.19.2.
- * Update internal Unicode character tables, used in regular expression
- handling, from version 9.0 to 10.0.
- * Show the last-sync-URL on the [/help?cmd=/urllist|/urllist] page.
- * Fix "database locked" warnings caused by "PRAGMA optimize".
- * Fix a potential XSS vulnerability on the
- [/help?cmd=/help|/help] webpage.
- * Documentation updates
-
Changes for Version 2.2 (2017-04-11)
* GIT comment tags are now handled by Fossil during import/export.
* Show the content of README files on directory listings.
Index: www/env-opts.md
==================================================================
--- www/env-opts.md
+++ www/env-opts.md
@@ -141,16 +141,10 @@
`FOSSIL_HOME`: Location of the `~/.fossil` file. The first environment
variable found in the environment from the list `FOSSIL_HOME`,
`LOCALAPPDATA` (Windows), `APPDATA` (Windows), `HOMEDRIVE` and
`HOMEPATH` (Windows, used together), and `HOME` is used as the
location of the `~/.fossil` file.
-
-
-`FOSSIL_USE_SEE_TEXTKEY`: If set, treat the encryption key string for
-SEE as text to be hashed into the actaul encryption key. This has no
-effect if Fossil was not compiled with SEE support enabled.
-
`FOSSIL_USER`: Name of the default user account if the checkout, local
or global `default-user` setting is not present. The first environment
variable found in the environment from the list `FOSSIL_USER`, `USER`,
`LOGNAME`, and `USERNAME` is the user name. If none of those are set,
DELETED www/globs.md
Index: www/globs.md
==================================================================
--- www/globs.md
+++ /dev/null
@@ -1,540 +0,0 @@
-# File Name Glob Patterns
-
-
-A [glob pattern][glob] is a text expression that matches one or more
-file names using wild cards familiar to most users of a command line.
-For example, `*` is a glob that matches any name at all and
-`Readme.txt` is a glob that matches exactly one file.
-
-Note that although both are notations for describing patterns in text,
-glob patterns are not the same thing as a [regular expression or
-regexp][regexp].
-
-[glob]: https://en.wikipedia.org/wiki/Glob_(programming) (Wikipedia)
-[regexp]: https://en.wikipedia.org/wiki/Regular_expression
-
-
-A number of fossil setting values hold one or more file glob patterns
-that will identify files needing special treatment. Glob patterns are
-also accepted in options to certain commands as well as query
-parameters to certain pages.
-
-In many cases more than one glob may be specified in a setting,
-option, or query parameter by listing multiple globs separated by a
-comma or white space.
-
-Of course, many fossil commands also accept lists of files to act on,
-and those also may be specified with globs. Although those glob
-patterns are similar to what is described here, they are not defined
-by fossil, but rather by the conventions of the operating system in
-use.
-
-
-## Syntax
-
-A list of glob patterns is simply one or more glob patterns separated
-by white space or commas. If a glob must contain white spaces or
-commas, it can be quoted with either single or double quotation marks.
-A list is said to match if any one (or more) globs in the list
-matches.
-
-A glob pattern is a collection of characters compared to a target
-text, usually a file name. The whole glob is said to match if it
-successfully consumes and matches the entire target text. Glob
-patterns are made up of ordinary characters and special characters.
-
-Ordinary characters consume a single character of the target and must
-match it exactly.
-
-Special characters (and special character sequences) consume zero or
-more characters from the target and describe what matches. The special
-characters (and sequences) are:
-
- * `*` Matches any sequence of zero or more characters;
- * `?` Matches exactly one character;
- * `[...]` Matches one character from the enclosed list of characters; and
- * `[^...]` Matches one character not in the enclosed list.
-
-Special character sequences have some additional features:
-
- * A range of characters may be specified with `-`, so `[a-d]` matches
- exactly the same characters as `[abcd]`. Ranges reflect Unicode
- code points without any locale-specific collation sequence.
- * Include `-` in a list by placing it last, just before the `]`.
- * Include `]` in a list by making the first character after the `[` or
- `[^`. At any other place, `]` ends the list.
- * Include `^` in a list by placing anywhere except first after the
- `[`.
- * Beware that ranges in lists may include more than you expect:
- `[A-z]` Matches `A` and `Z`, but also matches `a` and some less
- obvious characters such as `[`, `\`, and `]` with code point
- values between `Z` and `a`.
- * Beware that a range must be specified from low value to high
- value: `[z-a]` does not match any character at all, preventing the
- entire glob from matching.
- * Note that unlike typical Unix shell globs, wildcards (`*`, `?`,
- and character lists) are allowed to match `/` directory
- separators as well as the initial `.` in the name of a hidden
- file or directory.
-
-Some examples of character lists:
-
- * `[a-d]` Matches any one of `a`, `b`, `c`, or `d` but not `ä`;
- * `[^a-d]` Matches exactly one character other than `a`, `b`, `c`,
- or `d`;
- * `[0-9a-fA-F]` Matches exactly one hexadecimal digit;
- * `[a-]` Matches either `a` or `-`;
- * `[][]` Matches either `]` or `[`;
- * `[^]]` Matches exactly one character other than `]`;
- * `[]^]` Matches either `]` or `^`; and
- * `[^-]` Matches exactly one character other than `-`.
-
-White space means the specific ASCII characters TAB, LF, VT, FF, CR,
-and SPACE. Note that this does not include any of the many additional
-spacing characters available in Unicode, and specifically does not
-include U+00A0 NO-BREAK SPACE.
-
-Because both LF and CR are white space and leading and trailing spaces
-are stripped from each glob in a list, a list of globs may be broken
-into lines between globs when the list is stored in a file (as for a
-versioned setting).
-
-Similarly 'single quotes' and "double quotes" are the ASCII straight
-quote characters, not any of the other quotation marks provided in
-Unicode and specifically not the "curly" quotes preferred by
-typesetters and word processors.
-
-
-## File Names to Match
-
-Before it is compared to a glob pattern, each file name is transformed
-to a canonical form. The glob must match the entire canonical file
-name to be considered a match.
-
-The canonical name of a file has all directory separators changed to
-`/`, redundant slashes are removed, all `.` path components are
-removed, and all `..` path components are resolved. (There are
-additional details we are ignoring here, but they cover rare edge
-cases and also follow the principle of least surprise.)
-
-The goal is to have a name that is the simplest possible for each
-particular file, and that will be the same on Windows, Unix, and any
-other platform where fossil is run.
-
-Beware, however, that all glob matching is case sensitive. This will
-not be a surprise on Unix where all file names are also case
-sensitive. However, most Windows file systems are case preserving and
-case insensitive. That is, on Windows, the names `ReadMe` and `README`
-are names of the same file; on Unix they are different files.
-
-Some example cases:
-
- * The glob `README` matches only a file named `README` in the root of
- the tree. It does not match a file named `src/README` because it
- does not include any characters that consume (and match) the
- `src/` part.
- * The glob `*/README` does match `src/README`. Unlike Unix file
- globs, it also matches `src/library/README`. However it does not
- match the file `README` in the root of the tree.
- * The glob `*README` does match `src/README` as well as the file
- `README` in the root of the tree as well as `foo/bar/README` or
- any other file named `README` in the tree. However, it also
- matches `A-DIFFERENT-README` and `src/DO-NOT-README`, or any other
- file whose name ends with `README`.
- * The glob `src/README` does match the file named `src\README` on
- Windows because all directory separators are rewritten as `/` in
- the canonical name before the glob is matched. This makes it much
- easier to write globs that work on both Unix and Windows.
- * The glob `*.[ch]` matches every C source or header file in the
- tree at the root or at any depth. Again, this is (deliberately)
- different from Unix file globs and Windows wild cards.
-
-
-## Where Globs are Used
-
-### Settings that are Globs
-
-These settings are all lists of glob patterns:
-
- * `binary-glob`
- * `clean-glob`
- * `crlf-glob`
- * `crnl-glob`
- * `encoding-glob`
- * `ignore-glob`
- * `keep-glob`
-
-All may be [versioned, local, or global](settings.wiki). Use `fossil
-settings` to manage local and global settings, or a file in the
-repository's `.fossil-settings/` folder at the root of the tree named
-for each for versioned setting.
-
-Using versioned settings for these not only has the advantage that
-they are tracked in the repository just like the rest of your project,
-but you can more easily keep longer lists of more complicated glob
-patterns than would be practical in either local or global settings.
-
-The `ignore-glob` is an example of one setting that frequently grows
-to be an elaborate list of files that should be ignored by most
-commands. This is especially true when one (or more) IDEs are used in
-a project because each IDE has its own ideas of how and where to cache
-information that speeds up its browsing and building tasks but which
-need not be preserved in your project's history.
-
-
-### Commands that Refer to Globs
-
-Many of the commands that respect the settings containing globs have
-options to override some or all of the settings. These options are
-usually named to correspond to the setting they override, such as
-`--ignore` to override the `ignore-glob` setting. These commands are:
-
- * [`add`][]
- * [`addremove`][]
- * [`changes`][]
- * [`clean`][]
- * [`extras`][]
- * [`merge`][]
- * [`settings`][]
- * [`status`][]
- * [`unset`][]
-
-The commands [`tarball`][] and [`zip`][] produce compressed archives of a
-specific checkin. They may be further restricted by options that
-specify glob patterns that name files to include or exclude rather
-than archiving the entire checkin.
-
-The commands [`http`][], [`cgi`][], [`server`][], and [`ui`][] that
-implement or support with web servers provide a mechanism to name some
-files to serve with static content where a list of glob patterns
-specifies what content may be served.
-
-[`add`]: /help?cmd=add
-[`addremove`]: /help?cmd=addremove
-[`changes`]: /help?cmd=changes
-[`clean`]: /help?cmd=clean
-[`extras`]: /help?cmd=extras
-[`merge`]: /help?cmd=merge
-[`settings`]: /help?cmd=settings
-[`status`]: /help?cmd=status
-[`unset`]: /help?cmd=unset
-
-[`tarball`]: /help?cmd=tarball
-[`zip`]: /help?cmd=zip
-
-[`http`]: /help?cmd=http
-[`cgi`]: /help?cmd=cgi
-[`server`]: /help?cmd=server
-[`ui`]: /help?cmd=ui
-
-
-### Web Pages that Refer to Globs
-
-The [`/timeline`][] page supports the query parameter `chng=GLOBLIST` that
-names a list of glob patterns defining which files to focus the
-timeline on. It also has the query parameters `t=TAG` and `r=TAG` that
-names a tag to focus on, which can be configured with `ms=STYLE` to
-use a glob pattern to match tag names instead of the default exact
-match or a couple of other comparison styles.
-
-The pages [`/tarball`][] and [`/zip`][] generate compressed archives
-of a specific checkin. They may be further restricted by query
-parameters that specify glob patterns that name files to include or
-exclude rather than taking the entire checkin.
-
-[`/timeline`]: /help?cmd=/timeline
-[`/tarball`]: /help?cmd=/tarball
-[`/zip`]: /help?cmd=/zip
-
-
-## Platform Quirks
-
-Fossil glob patterns are based on the glob pattern feature of POSIX
-shells. Fossil glob patterns also have a quoting mechanism, discussed
-above. Because other parts of your operating system may interpret glob
-patterns and quotes separately from Fossil, it is often difficult to
-give glob patterns correctly to Fossil on the command line. Quotes and
-special characters in glob patterns are likely to be interpreted when
-given as part of a `fossil` command, causing unexpected behavior.
-
-These problems do not affect [versioned settings files](settings.wiki)
-or Admin → Settings in Fossil UI. Consequently, it is better to
-set long-term `*-glob` settings via these methods than to use `fossil
-settings` commands.
-
-That advice does not help you when you are giving one-off glob patterns
-in `fossil` commands. The remainder of this section gives remedies and
-workarounds for these problems.
-
-
-## POSIX Systems
-
-If you are using Fossil on a system with a POSIX-compatible shell
-— Linux, macOS, the BSDs, Unix, Cygwin, WSL etc. — the shell
-may expand the glob patterns before passing the result to the `fossil`
-executable.
-
-Sometimes this is exactly what you want. Consider this command for
-example:
-
- $ fossil add RE*
-
-If you give that command in a directory containing `README.txt` and
-`RELEASE-NOTES.txt`, the shell will expand the command to:
-
- $ fossil add README.txt RELEASE-NOTES.txt
-
-…which is compatible with the `fossil add` command's argument list,
-which allows multiple files.
-
-Now consider what happens instead if you say:
-
- $ fossil add --ignore RE* src/*.c
-
-This *does not* do what you want because the shell will expand both `RE*`
-and `src/*.c`, causing one of the two files matching the `RE*` glob
-pattern to be ignored and the other to be added to the repository. You
-need to say this in that case:
-
- $ fossil add --ignore 'RE*' src/*.c
-
-The single quotes force a POSIX shell to pass the `RE*` glob pattern
-through to Fossil untouched, which will do its own glob pattern
-matching. There are other methods of quoting a glob pattern or escaping
-its special characters; see your shell's manual.
-
-Beware that Fossil's `--ignore` option does not override explicit file
-mentions:
-
- $ fossil add --ignore 'REALLY SECRET STUFF.txt' RE*
-
-You might think that would add everything beginning with `RE` *except*
-for `REALLY SECRET STUFF.txt`, but when a file is both given
-explicitly to Fossil and also matches an ignore rule, Fossil asks what
-you want to do with it in the default case; and it does not even ask
-if you gave the `-f` or `--force` option along with `--ignore`.
-
-The spaces in the ignored file name above bring us to another point:
-such file names must be quoted in Fossil glob patterns, lest Fossil
-interpret it as multiple glob patterns, but the shell interprets
-quotation marks itself.
-
-One way to fix both this and the previous problem is:
-
- $ fossil add --ignore "'REALLY SECRET STUFF.txt'" READ*
-
-The nested quotation marks cause the inner set to be passed through to
-Fossil, and the more specific glob pattern at the end — that is,
-`READ*` vs `RE*` — avoids a conflict between explicitly-listed
-files and `--ignore` rules in the `fossil add` command.
-
-Another solution would be to use shell escaping instead of nested
-quoting:
-
- $ fossil add --ignore "\"REALLY SECRET STUFF.txt\"" READ*
-
-It bears repeating that the two glob patterns here are not interpreted
-the same way when running this command from a *subdirectory* of the top
-checkout directory as when running it at the top of the checkout tree.
-If these files were in a subdirectory of the checkout tree called `doc`
-and that was your current working directory, the command would have to
-be:
-
- $ fossil add --ignore "'doc/REALLY SECRET STUFF.txt'" READ*
-
-instead. The Fossil glob pattern still needs the `doc/` prefix because
-Fossil always interprets glob patterns from the base of the checkout
-directory, not from the current working directory as POSIX shells do.
-
-When in doubt, use `fossil status` after running commands like the
-above to make sure the right set of files were scheduled for insertion
-into the repository before checking the changes in. You never want to
-accidentally check something like a password, an API key, or the
-private half of a public cryptographic key into Fossil repository that
-can be read by people who should not have such secrets.
-
-
-## Windows
-
-Neither standard Windows command shell — `cmd.exe` or PowerShell
-— expands glob patterns the way POSIX shells do. Windows command
-shells rely on the command itself to do the glob pattern expansion. The
-way this works depends on several factors:
-
- * the version of Windows you are using
- * which OS upgrades have been applied to it
- * the compiler that built your Fossil executable
- * whether you are running the command interactively
- * whether the command is built against a runtime system that does this
- at all
- * whether the Fossil command is being run from a file named `*.BAT` vs
- being named `*.CMD`
-
-These factors also affect how a program like `fossil.exe` interprets
-quotation marks on its command line.
-
-The fifth item above does not apply to `fossil.exe` when built with
-typical tool chains, but we will see an example below where the exception
-applies in a way that affects how Fossil interprets the glob pattern.
-
-The most common problem is figuring out how to get a glob pattern passed
-on the command line into `fossil.exe` without it being expanded by the C
-runtime library that your particular Fossil executable is linked to,
-which tries to act like the POSIX systems described above. Windows is
-not strongly governed by POSIX, so it has not historically hewed closely
-to its strictures.
-
-(This section does not cover the [Microsoft POSIX
-subsystem](https://en.wikipedia.org/wiki/Microsoft_POSIX_subsystem),
-Windows' obsolete [Services for Unix
-3.*x*](https://en.wikipedia.org/wiki/Windows_Services_for_UNIX) feature,
-or the [Windows Subsystem for
-Linux](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux). (The
-latter is sometimes incorrectly called "Bash on Windows" or "Ubuntu on
-Windows.") See the POSIX Systems section above for those cases.)
-
-For example, consider how you would set `crlf-glob` to `*` in order to
-disable Fossil's "looks like a binary file" checks. The naïve
-approach will not work:
-
- C:\...> fossil setting crlf-glob *
-
-The C runtime library will expand that to the list of all files in the
-current directory, which will probably cause a Fossil error because
-Fossil expects either nothing or option flags after the setting's new
-value.
-
-Let's try again:
-
- C:\...> fossil setting crlf-glob '*'
-
-That may or may not work. Either `'*'` or `*` needs to be passed through
-to Fossil untouched for this to do what you expect, which may or may not
-happen, depending on the factors listed above.
-
-An approach that *will* work reliably is:
-
- C:\...> echo * | fossil setting crlf-glob --args -
-
-This works because the built-in command `echo` does not expand its
-arguments, and the `--args -` option makes it read further command
-arguments from Fossil's standard input, which is connected to the output
-of `echo` by the pipe. (`-` is a common Unix convention meaning
-"standard input.")
-
-Another (usually) correct approach is:
-
- C:\...> fossil setting crlf-glob *,
-
-This works because the trailing comma prevents the command shell from
-matching any files, unless you happen to have files named with a
-trailing comma in the current directory. If the pattern matches no
-files, it is passed into Fossil's `main()` function as-is by the C
-runtime system. Since Fossil uses commas to separate multiple glob
-patterns, this means "all files at the root of the Fossil checkout
-directory and nothing else."
-
-
-## Converting `.gitignore` to `ignore-glob`
-
-Many other version control systems handle the specific case of
-ignoring certain files differently from fossil: they have you create
-individual "ignore" files in each folder, which specify things ignored
-in that folder and below. Usually some form of glob patterns are used
-in those files, but the details differ from fossil.
-
-In many simple cases, you can just store a top level "ignore" file in
-`.fossil-settings/ignore-glob`. But as usual, there will be lots of
-edge cases.
-
-[Git has a rich collection of ignore files][gitignore] which
-accumulate rules that affect the current command. There are global
-files, per-user files, per workspace unmanaged files, and fully
-version controlled files. Some of the files used have no set name, but
-are called out in configuration files.
-
-[gitignore]: https://git-scm.com/docs/gitignore
-
-In contrast, fossil has a global setting and a local setting, but the local setting
-overrides the global rather than extending it. Similarly, a fossil
-command's `--ignore` option replaces the `ignore-glob` setting rather
-than extending it.
-
-With that in mind, translating a `.gitignore` file into
-`.fossil-settings/ignore-glob` may be possible in many cases. Here are
-some of features of `.gitignore` and comments on how they relate to
-fossil:
-
- * "A blank line matches no files..." is the same in fossil.
- * "A line starting with # serves as a comment...." not in fossil.
- * "Trailing spaces are ignored unless they are quoted..." is similar
- in fossil. All whitespace before and after a glob is trimmed in
- fossil unless quoted with single or double quotes. Git uses
- backslash quoting instead, which fossil does not.
- * "An optional prefix "!" which negates the pattern..." not in
- fossil.
- * Git's globs are relative to the location of the `.gitignore` file;
- fossil's globs are relative to the root of the workspace.
- * Git's globs and fossil's globs treat directory separators
- differently. Git includes a notation for zero or more directories
- that is not needed in fossil.
-
-### Example
-
-In a project with source and documentation:
-
- work
- +-- doc
- +-- src
-
-The file `doc/.gitignore` might contain:
-
- # Finished documents by pandoc via LaTeX
- *.pdf
- # Intermediate files
- *.tex
- *.toc
- *.log
- *.out
- *.tmp
-
-Entries in `.fossil-settings/ignore-glob` with similar effect, also
-limited to the `doc` folder:
-
- doc/*.pdf
- doc/*.tex, doc/*.toc, doc/*.log, doc/*.out, doc/*.tmp
-
-
-
-
-
-## Implementation and References
-
-Most of the implementation of glob pattern handling in fossil is found
-`glob.c`, `file.c`, and each individual command and web page that uses
-a glob pattern. Find commands and pages in the fossil sources by
-looking for comments like `COMMAND: add` or `WEBPAGE: timeline` in
-front of the function that implements the command or page in files
-`src/*.c`. (Fossil's build system creates the tables used to dispatch
-commands at build time by searching the sources for those comments.) A
-few starting points:
-
- * [`src/glob.c`][glob.c] implements glob pattern list loading,
- parsing, and matching.
- * [`src/file.c`][file.c] implements various kinds of canonical
- names of a file.
-
-
-[glob.c]: https://www.fossil-scm.org/index.html/file/src/glob.c
-[file.c]: https://www.fossil-scm.org/index.html/file/src/file.c
-
-The actual pattern matching is implemented in SQL, so the
-documentation for `GLOB` and the other string matching operators in
-[SQLite] (https://sqlite.org/lang_expr.html#like) is useful. Of
-course, the SQLite source code and test harnesses also make
-entertaining reading:
-
- * `src/func.c` [lines 570-768]
- (https://www.sqlite.org/src/artifact?name=9d52522cc8ae7f5c&ln=570-768)
- * `test/expr.test` [lines 586-673]
- (https://www.sqlite.org/src/artifact?name=66a2c9ac34f74f03&ln=586-673)
Index: www/mkindex.tcl
==================================================================
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -36,11 +36,10 @@
fileformat.wiki {Fossil File Format}
fiveminutes.wiki {Up and Running in 5 Minutes as a Single User}
foss-cklist.wiki {Checklist For Successful Open-Source Projects}
fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
fossil-v-git.wiki {Fossil Versus Git}
- globs.md {File Name Glob Patterns}
hacker-howto.wiki {Hacker How-To}
hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
/help {Lists of Commands and Webpages}
hints.wiki {Fossil Tips And Usage Hints}
index.wiki {Home Page}
Index: www/permutedindex.html
==================================================================
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -85,11 +85,10 @@
Examples — Webpage
Export To And From Git — Import And
Express 2010 IDE — Integrating Fossil in the Microsoft
Features To Fossil — Adding New
File Format — Fossil
-File Name Glob Patterns
Files — Unversioned
Forking, Merging, and Tagging — Branching,
Format — Fossil Delta
Format — Fossil File
Formatting Rules — Markdown
@@ -109,11 +108,10 @@
Frequently Asked Questions
General — Quotes: What People Are Saying About Fossil, Git, and DVCSes in
Git — Fossil Versus
Git — Import And Export To And From
Git, and DVCSes in General — Quotes: What People Are Saying About Fossil,
-Glob Patterns — File Name
Global Options — Environment Variables and
Graph — Theming: Customizing the Timeline
Guide — Fossil Quick Start
Guidelines — Source Code Style
Hacker How-To
@@ -142,11 +140,10 @@
Map — Site
Markdown Formatting Rules
Merging, and Tagging — Branching, Forking,
Microsoft Express 2010 IDE — Integrating Fossil in the
Minutes as a Single User — Up and Running in 5
-Name Glob Patterns — File
Names — Check-in And Version
New Features To Fossil — Adding
New Fossil Repository — How To Create A
Open-Source Projects — Checklist For Successful
Operation — Principles Of
@@ -154,11 +151,10 @@
Overview Of The Design And Implementation Of Fossil — A Technical
Page — Home
Page Works — How The Download
Pages — Theming: Customizing The Appearance of Web
Password Management And Authentication
-Patterns — File Name Glob
People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What
Performance Statistics
Policy: Choosing Between SHA1 and SHA3-256 — Hash
Pre-Release Testing Checklist
Principles Of Operation