diff --git a/Makefile.in b/Makefile.in index fb159fe..c1fdd2a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -32,7 +32,7 @@ TCC = @CC@ @CPPFLAGS@ @CFLAGS@ -I. -I${TOP}/src -I${TOP}/ext/rtree # Define this for the autoconf-based build, so that the code knows it can # include the generated config.h # -TCC += -D_HAVE_SQLITE_CONFIG_H +TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and @@ -531,6 +531,12 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl +tclsqlite3.c: sqlite3.c + echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c + cat sqlite3.c >>tclsqlite3.c + echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c + cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c + sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl diff --git a/VERSION b/VERSION index c77a7de..f06fb9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.9 +3.7.10 diff --git a/config.h.in b/config.h.in index 11f2280..5e087dc 100644 --- a/config.h.in +++ b/config.h.in @@ -33,6 +33,9 @@ /* Define to 1 if you have the `localtime_s' function. */ #undef HAVE_LOCALTIME_S +/* Define to 1 if you have the `malloc_usable_size' function. */ +#undef HAVE_MALLOC_USABLE_SIZE + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H diff --git a/configure b/configure index 79cd72d..8a34f2b 100755 --- a/configure +++ b/configure @@ -1,22 +1,18 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for sqlite 3.7.9. -# +# Generated by GNU Autoconf 2.62 for sqlite 3.7.10. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. -# -# +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which @@ -24,15 +20,23 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; esac + fi + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + as_nl=' ' export as_nl @@ -40,13 +44,7 @@ export as_nl as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else @@ -57,7 +55,7 @@ else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; - case $arg in #( + case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; @@ -80,6 +78,13 @@ if test "${PATH_SEPARATOR+set}" != set; then } fi +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + # IFS # We need space, tab and new line, in precisely that order. Quoting is @@ -89,15 +94,15 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( +case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done IFS=$as_save_IFS ;; @@ -109,16 +114,12 @@ if test "x$as_myself" = x; then fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 + { (exit 1); exit 1; } fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' @@ -130,248 +131,7 @@ export LC_ALL LANGUAGE=C export LANGUAGE -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - +# Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr @@ -385,12 +145,8 @@ else as_basename=false fi -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi +# Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ @@ -410,19 +166,295 @@ $as_echo X/"$0" | } s/.*/./; q'` -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits +# CDPATH. +$as_unset CDPATH - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= @@ -439,7 +471,8 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the @@ -449,18 +482,29 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits exit } + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( +case `echo -n x` in -n*) - case `echo 'xy\c'` in + case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; + *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then @@ -490,7 +534,7 @@ rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' + as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false @@ -509,10 +553,10 @@ else if test -d "$1"; then test -d "$1/."; else - case $1 in #( + case $1 in -*)set "./$1";; esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' @@ -527,6 +571,7 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} @@ -675,11 +720,10 @@ fi -test -n "$DJDIR" || exec 7<&0 &1 +exec 7<&0 &1 # Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -694,14 +738,14 @@ cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.7.9' -PACKAGE_STRING='sqlite 3.7.9' +PACKAGE_VERSION='3.7.10' +PACKAGE_STRING='sqlite 3.7.10' PACKAGE_BUGREPORT='' -PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ @@ -739,122 +783,121 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='LTLIBOBJS -LIBOBJS -BUILD_CFLAGS -USE_GCOV -OPT_FEATURE_FLAGS -USE_AMALGAMATION -TARGET_DEBUG -TARGET_HAVE_READLINE -TARGET_READLINE_INC -TARGET_READLINE_LIBS -HAVE_TCL -TCL_STUB_LIB_SPEC -TCL_STUB_LIB_FLAG -TCL_STUB_LIB_FILE -TCL_LIB_SPEC -TCL_LIB_FLAG -TCL_LIB_FILE -TCL_INCLUDE_SPEC -TCL_LIBS -TCL_SRC_DIR -TCL_BIN_DIR -TCL_VERSION -TARGET_EXEEXT -SQLITE_OS_OS2 -SQLITE_OS_WIN -SQLITE_OS_UNIX -BUILD_EXEEXT -TEMP_STORE -ALLOWRELEASE -XTHREADCONNECT -SQLITE_THREADSAFE -BUILD_CC -VERSION_NUMBER -RELEASE -VERSION -program_prefix -TCLLIBDIR -TCLSH_CMD -AWK -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -lt_ECHO -RANLIB -STRIP -AR -OBJDUMP -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBTOOL -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME +ac_subst_vars='SHELL PATH_SEPARATOR -SHELL' +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +LIBTOOL +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +SED +GREP +EGREP +FGREP +LD +DUMPBIN +ac_ct_DUMPBIN +NM +LN_S +OBJDUMP +AR +STRIP +RANLIB +lt_ECHO +DSYMUTIL +NMEDIT +LIPO +OTOOL +OTOOL64 +CPP +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +AWK +TCLSH_CMD +TCLLIBDIR +program_prefix +VERSION +RELEASE +VERSION_NUMBER +BUILD_CC +SQLITE_THREADSAFE +XTHREADCONNECT +ALLOWRELEASE +TEMP_STORE +BUILD_EXEEXT +SQLITE_OS_UNIX +SQLITE_OS_WIN +SQLITE_OS_OS2 +TARGET_EXEEXT +TCL_VERSION +TCL_BIN_DIR +TCL_SRC_DIR +TCL_LIBS +TCL_INCLUDE_SPEC +TCL_LIB_FILE +TCL_LIB_FLAG +TCL_LIB_SPEC +TCL_STUB_LIB_FILE +TCL_STUB_LIB_FLAG +TCL_STUB_LIB_SPEC +HAVE_TCL +TARGET_READLINE_LIBS +TARGET_READLINE_INC +TARGET_HAVE_READLINE +TARGET_DEBUG +USE_AMALGAMATION +OPT_FEATURE_FLAGS +USE_GCOV +BUILD_CFLAGS +LIBOBJS +LTLIBOBJS' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -952,9 +995,8 @@ do fi case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -999,7 +1041,8 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1025,7 +1068,8 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1229,7 +1273,8 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1245,7 +1290,8 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1275,17 +1321,17 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1302,14 +1348,16 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + fatal) { $as_echo "$as_me: error: Unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1331,7 +1379,8 @@ do [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' @@ -1345,8 +1394,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1361,9 +1410,11 @@ test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" + { $as_echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } # Find the source files, if location was not specified. @@ -1402,11 +1453,13 @@ else fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1432,7 +1485,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.7.9 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1446,7 +1499,7 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1497,7 +1550,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.7.9:";; + short | recursive ) echo "Configuration of sqlite 3.7.10:";; esac cat <<\_ACEOF @@ -1543,7 +1596,7 @@ Some influential environment variables: LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor TCLLIBDIR Where to install tcl plugin @@ -1551,7 +1604,6 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to the package provider. _ACEOF ac_status=$? fi @@ -1614,427 +1666,22 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.7.9 -generated by GNU Autoconf 2.67 +sqlite configure 3.7.10 +generated by GNU Autoconf 2.62 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_func - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_type - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.7.9, which was -generated by GNU Autoconf 2.67. Invocation command line was +It was created by sqlite $as_me 3.7.10, which was +generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -2070,8 +1717,8 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done + $as_echo "PATH: $as_dir" +done IFS=$as_save_IFS } >&5 @@ -2108,9 +1755,9 @@ do ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) - as_fn_append ac_configure_args1 " '$ac_arg'" + ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else @@ -2126,13 +1773,13 @@ do -* ) ac_must_keep_next=true ;; esac fi - as_fn_append ac_configure_args " '$ac_arg'" + ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there @@ -2144,9 +1791,11 @@ trap 'exit_status=$? { echo - $as_echo "## ---------------- ## + cat <<\_ASBOX +## ---------------- ## ## Cache variables. ## -## ---------------- ##" +## ---------------- ## +_ASBOX echo # The following way of writing the cache mishandles newlines in values, ( @@ -2155,13 +1804,13 @@ trap 'exit_status=$? case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +$as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; + *) $as_unset $ac_var ;; esac ;; esac done @@ -2180,9 +1829,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - $as_echo "## ----------------- ## + cat <<\_ASBOX +## ----------------- ## ## Output variables. ## -## ----------------- ##" +## ----------------- ## +_ASBOX echo for ac_var in $ac_subst_vars do @@ -2195,9 +1846,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + cat <<\_ASBOX +## ------------------- ## ## File substitutions. ## -## ------------------- ##" +## ------------------- ## +_ASBOX echo for ac_var in $ac_subst_files do @@ -2211,9 +1864,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; fi if test -s confdefs.h; then - $as_echo "## ----------- ## + cat <<\_ASBOX +## ----------- ## ## confdefs.h. ## -## ----------- ##" +## ----------- ## +_ASBOX echo cat confdefs.h echo @@ -2227,39 +1882,37 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; exit $exit_status ' 0 for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h -$as_echo "/* confdefs.h */" > confdefs.h - # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF @@ -2268,12 +1921,7 @@ _ACEOF ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2284,23 +1932,19 @@ fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 + if test -r "$ac_site_file"; then + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } + . "$ac_site_file" fi done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; @@ -2308,7 +1952,7 @@ $as_echo "$as_me: loading cache $cache_file" >&6;} esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi @@ -2323,11 +1967,11 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; @@ -2337,17 +1981,17 @@ $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac @@ -2359,20 +2003,41 @@ $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## + + + + + + + + + + + + + + + + + + + + + + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -2384,10 +2049,15 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -as_fn_error $? "configure script is out of date: +{ { $as_echo "$as_me:$LINENO: error: configure script is out of date: configure \$PACKAGE_VERSION = $PACKAGE_VERSION top level VERSION file = $sqlite_version_sanity_check -please regen with autoconf" "$LINENO" 5 +please regen with autoconf" >&5 +$as_echo "$as_me: error: configure script is out of date: + configure \$PACKAGE_VERSION = $PACKAGE_VERSION + top level VERSION file = $sqlite_version_sanity_check +please regen with autoconf" >&2;} + { (exit 1); exit 1; }; } fi # The following RCS revision string applies to configure.in @@ -2398,7 +2068,7 @@ fi # case `pwd` in *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 + { $as_echo "$as_me:$LINENO: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac @@ -2438,7 +2108,9 @@ for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do fi done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, @@ -2452,27 +2124,35 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +{ $as_echo "$as_me:$LINENO: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if test "${ac_cv_build+set}" = set; then $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +$as_echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -2488,24 +2168,28 @@ IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +{ $as_echo "$as_me:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if test "${ac_cv_host+set}" = set; then $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +$as_echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -2529,9 +2213,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2542,24 +2226,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 + { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2569,9 +2253,9 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -2582,24 +2266,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2608,8 +2292,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -2622,9 +2310,9 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2635,24 +2323,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 + { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2662,9 +2350,9 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2676,18 +2364,18 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then @@ -2706,10 +2394,10 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 + { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2721,9 +2409,9 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2734,24 +2422,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 + { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2765,9 +2453,9 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -2778,24 +2466,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -2808,8 +2496,12 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -2819,37 +2511,55 @@ fi fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" +{ (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -2865,8 +2575,8 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } +{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: @@ -2882,17 +2592,17 @@ do done rm -f $ac_rmfiles -if { { ac_try="$ac_link_default" +if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, @@ -2909,7 +2619,7 @@ do # certainly right. break;; *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi @@ -2928,41 +2638,80 @@ test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 + +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } + ac_exeext=$ac_cv_exeext +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" +if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -2977,83 +2726,30 @@ for ac_file in conftest.exe conftest conftest.*; do esac done else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } + { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 + +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3065,17 +2761,17 @@ main () } _ACEOF rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in @@ -3088,23 +2784,29 @@ else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi + rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3118,16 +2820,37 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else - ac_compiler_gnu=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes @@ -3136,16 +2859,20 @@ else fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if test "${ac_cv_prog_cc_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3156,11 +2883,35 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3171,12 +2922,36 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : else - ac_c_werror_flag=$ac_save_c_werror_flag + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3187,17 +2962,42 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS @@ -3214,14 +3014,18 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -3278,9 +3082,32 @@ for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done @@ -3291,19 +3118,17 @@ fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 + { $as_echo "$as_me:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac -if test "x$ac_cv_prog_cc_c89" != xno; then : -fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3311,9 +3136,9 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +{ $as_echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if test "${ac_cv_path_SED+set}" = set; then $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -3321,7 +3146,7 @@ else ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} + $as_unset ac_script || ac_script= if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST @@ -3330,7 +3155,7 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do + for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue @@ -3350,7 +3175,7 @@ case `"$ac_path_SED" --version 2>&1` in $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val + ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" @@ -3365,17 +3190,19 @@ esac $ac_path_SED_found && break 3 done done - done +done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: no acceptable sed could be found in \$PATH" >&5 +$as_echo "$as_me: error: no acceptable sed could be found in \$PATH" >&2;} + { (exit 1); exit 1; }; } fi else ac_cv_path_SED=$SED fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed @@ -3393,9 +3220,9 @@ Xsed="$SED -e 1s/^X//" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if test "${ac_cv_path_GREP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -3406,7 +3233,7 @@ for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do + for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue @@ -3426,7 +3253,7 @@ case `"$ac_path_GREP" --version 2>&1` in $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val + ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" @@ -3441,24 +3268,26 @@ esac $ac_path_GREP_found && break 3 done done - done +done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if test "${ac_cv_path_EGREP+set}" = set; then $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -3472,7 +3301,7 @@ for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do + for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue @@ -3492,7 +3321,7 @@ case `"$ac_path_EGREP" --version 2>&1` in $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val + ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" @@ -3507,10 +3336,12 @@ esac $ac_path_EGREP_found && break 3 done done - done +done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP @@ -3518,14 +3349,14 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +{ $as_echo "$as_me:$LINENO: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if test "${ac_cv_path_FGREP+set}" = set; then $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -3539,7 +3370,7 @@ for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do + for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue @@ -3559,7 +3390,7 @@ case `"$ac_path_FGREP" --version 2>&1` in $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val + ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" @@ -3574,10 +3405,12 @@ esac $ac_path_FGREP_found && break 3 done done - done +done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } fi else ac_cv_path_FGREP=$FGREP @@ -3585,7 +3418,7 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" @@ -3611,7 +3444,7 @@ test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : +if test "${with_gnu_ld+set}" = set; then withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no @@ -3620,7 +3453,7 @@ fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 + { $as_echo "$as_me:$LINENO: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) @@ -3650,13 +3483,13 @@ $as_echo_n "checking for ld used by $CC... " >&6; } ;; esac elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 + { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 + { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi -if test "${lt_cv_path_LD+set}" = set; then : +if test "${lt_cv_path_LD+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$LD"; then @@ -3687,16 +3520,18 @@ fi LD="$lt_cv_path_LD" if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 + { $as_echo "$as_me:$LINENO: result: $LD" >&5 $as_echo "$LD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +$as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if test "${lt_cv_prog_gnu_ld+set}" = set; then : +if test "${lt_cv_prog_gnu_ld+set}" = set; then $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. @@ -3709,7 +3544,7 @@ case `$LD -v 2>&1 &5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld @@ -3721,9 +3556,9 @@ with_gnu_ld=$lt_cv_prog_gnu_ld -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +{ $as_echo "$as_me:$LINENO: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if test "${lt_cv_path_NM+set}" = set; then : +if test "${lt_cv_path_NM+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -3770,7 +3605,7 @@ else : ${lt_cv_path_NM=no} fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" @@ -3781,9 +3616,9 @@ else do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if test "${ac_cv_prog_DUMPBIN+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -3794,24 +3629,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 + { $as_echo "$as_me:$LINENO: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -3825,9 +3660,9 @@ if test -z "$DUMPBIN"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then @@ -3838,24 +3673,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -3868,8 +3703,12 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN @@ -3888,44 +3727,44 @@ test -z "$NM" && NM=nm -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +{ $as_echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } -if test "${lt_cv_nm_interface+set}" = set; then : +if test "${lt_cv_nm_interface+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3898: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3737: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3901: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3740: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3904: output\"" >&5) + (eval echo "\"\$as_me:3743: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +{ $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 + { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +{ $as_echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } -if test "${lt_cv_sys_max_cmd_len+set}" = set; then : +if test "${lt_cv_sys_max_cmd_len+set}" = set; then $as_echo_n "(cached) " >&6 else i=0 @@ -4043,10 +3882,10 @@ else fi if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 + { $as_echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 + { $as_echo "$as_me:$LINENO: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len @@ -4060,7 +3899,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len : ${MV="mv -f"} : ${RM="rm -f"} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +{ $as_echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no @@ -4070,17 +3909,17 @@ xsi_shell=no && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +{ $as_echo "$as_me:$LINENO: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +{ $as_echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } @@ -4115,14 +3954,14 @@ esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +{ $as_echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } -if test "${lt_cv_ld_reload_flag+set}" = set; then : +if test "${lt_cv_ld_reload_flag+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in @@ -4151,9 +3990,9 @@ esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if test "${ac_cv_prog_OBJDUMP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -4164,24 +4003,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 + { $as_echo "$as_me:$LINENO: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4191,9 +4030,9 @@ if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -4204,24 +4043,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4230,8 +4069,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP @@ -4250,9 +4093,9 @@ test -z "$OBJDUMP" && OBJDUMP=objdump -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +{ $as_echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } -if test "${lt_cv_deplibs_check_method+set}" = set; then : +if test "${lt_cv_deplibs_check_method+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' @@ -4446,7 +4289,7 @@ tpf*) esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method @@ -4466,9 +4309,9 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if test "${ac_cv_prog_AR+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -4479,24 +4322,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 + { $as_echo "$as_me:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4506,9 +4349,9 @@ if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -4519,24 +4362,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4545,8 +4388,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR @@ -4571,9 +4418,9 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if test "${ac_cv_prog_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -4584,24 +4431,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 + { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4611,9 +4458,9 @@ if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -4624,24 +4471,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4650,8 +4497,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP @@ -4670,9 +4521,9 @@ test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then : +if test "${ac_cv_prog_RANLIB+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then @@ -4683,24 +4534,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 + { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4710,9 +4561,9 @@ if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then @@ -4723,24 +4574,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -4749,8 +4600,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB @@ -4827,9 +4682,9 @@ compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +{ $as_echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then $as_echo_n "(cached) " >&6 else @@ -4945,18 +4800,18 @@ void nm_test_func(void){} int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -5009,11 +4864,11 @@ _LT_EOF lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" @@ -5047,10 +4902,10 @@ if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 + { $as_echo "$as_me:$LINENO: result: failed" >&5 $as_echo "failed" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 + { $as_echo "$as_me:$LINENO: result: ok" >&5 $as_echo "ok" >&6; } fi @@ -5077,7 +4932,7 @@ fi # Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : +if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi @@ -5089,11 +4944,11 @@ case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" @@ -5107,12 +4962,12 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5110 "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + echo '#line 4965 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) @@ -5146,11 +5001,11 @@ x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in @@ -5199,9 +5054,9 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 + { $as_echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if test "${lt_cv_cc_needs_belf+set}" = set; then : +if test "${lt_cv_cc_needs_belf+set}" = set; then $as_echo_n "(cached) " >&6 else ac_ext=c @@ -5210,7 +5065,11 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5221,13 +5080,38 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then lt_cv_cc_needs_belf=yes else - lt_cv_cc_needs_belf=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_cc_needs_belf=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -5235,7 +5119,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf @@ -5245,11 +5129,11 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in @@ -5275,9 +5159,9 @@ need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then @@ -5288,24 +5172,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 + { $as_echo "$as_me:$LINENO: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5315,9 +5199,9 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then @@ -5328,24 +5212,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5354,8 +5238,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL @@ -5367,9 +5255,9 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NMEDIT+set}" = set; then : +if test "${ac_cv_prog_NMEDIT+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then @@ -5380,24 +5268,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 + { $as_echo "$as_me:$LINENO: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5407,9 +5295,9 @@ if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then @@ -5420,24 +5308,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5446,8 +5334,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT @@ -5459,9 +5351,9 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_LIPO+set}" = set; then : +if test "${ac_cv_prog_LIPO+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then @@ -5472,24 +5364,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 + { $as_echo "$as_me:$LINENO: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5499,9 +5391,9 @@ if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then @@ -5512,24 +5404,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5538,8 +5430,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO @@ -5551,9 +5447,9 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL+set}" = set; then : +if test "${ac_cv_prog_OTOOL+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then @@ -5564,24 +5460,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 + { $as_echo "$as_me:$LINENO: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5591,9 +5487,9 @@ if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then @@ -5604,24 +5500,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5630,8 +5526,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL @@ -5643,9 +5543,9 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL64+set}" = set; then : +if test "${ac_cv_prog_OTOOL64+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then @@ -5656,24 +5556,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 + { $as_echo "$as_me:$LINENO: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5683,9 +5583,9 @@ if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then @@ -5696,24 +5596,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 + { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -5722,8 +5622,12 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 @@ -5758,9 +5662,9 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 + { $as_echo "$as_me:$LINENO: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } -if test "${lt_cv_apple_cc_single_mod+set}" = set; then : +if test "${lt_cv_apple_cc_single_mod+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no @@ -5785,18 +5689,22 @@ else rm -f conftest.* fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 + { $as_echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5807,17 +5715,42 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then lt_cv_ld_exported_symbols_list=yes else - lt_cv_ld_exported_symbols_list=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_ld_exported_symbols_list=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } case $host_os in rhapsody* | darwin1.[012]) @@ -5859,14 +5792,14 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if test "${ac_cv_prog_CPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -5881,7 +5814,11 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include @@ -5890,34 +5827,78 @@ do #endif Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext + +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext + +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then break fi @@ -5929,7 +5910,7 @@ fi else ac_cv_prog_CPP=$CPP fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes @@ -5940,7 +5921,11 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include @@ -5949,40 +5934,85 @@ do #endif Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext + +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext + +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } + { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi ac_ext=c @@ -5992,12 +6022,16 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -6012,23 +6046,48 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else - ac_cv_header_stdc=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - + $EGREP "memchr" >/dev/null 2>&1; then + : else ac_cv_header_stdc=no fi @@ -6038,14 +6097,18 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - + $EGREP "free" >/dev/null 2>&1; then + : else ac_cv_header_stdc=no fi @@ -6055,10 +6118,14 @@ fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -6085,33 +6152,117 @@ main () return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : else - ac_cv_header_stdc=no + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then -$as_echo "#define STDC_HEADERS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if test `eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -6121,13 +6272,61 @@ fi done + for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = x""yes; then : +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if test `eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -6147,7 +6346,7 @@ done # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : +if test "${enable_shared+set}" = set; then enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; @@ -6178,7 +6377,7 @@ fi # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : +if test "${enable_static+set}" = set; then enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; @@ -6210,7 +6409,7 @@ fi # Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : +if test "${with_pic+set}" = set; then withval=$with_pic; pic_mode="$withval" else pic_mode=default @@ -6226,7 +6425,7 @@ test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : +if test "${enable_fast_install+set}" = set; then enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; @@ -6307,9 +6506,9 @@ if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +{ $as_echo "$as_me:$LINENO: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } -if test "${lt_cv_objdir+set}" = set; then : +if test "${lt_cv_objdir+set}" = set; then $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null @@ -6322,7 +6521,7 @@ else fi rmdir .libs 2>/dev/null fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir @@ -6415,9 +6614,9 @@ test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 + { $as_echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -6468,10 +6667,10 @@ fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 + { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -6481,9 +6680,9 @@ fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 + { $as_echo "$as_me:$LINENO: checking for file" >&5 $as_echo_n "checking for file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -6534,10 +6733,10 @@ fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 + { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -6614,9 +6813,9 @@ lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + { $as_echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no @@ -6632,11 +6831,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6635: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6834: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6639: \$? = $ac_status" >&5 + echo "$as_me:6838: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6649,7 +6848,7 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then @@ -6669,7 +6868,7 @@ fi lt_prog_compiler_pic= lt_prog_compiler_static= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +{ $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then @@ -6941,7 +7140,7 @@ case $host_os in lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 $as_echo "$lt_prog_compiler_pic" >&6; } @@ -6953,9 +7152,9 @@ $as_echo "$lt_prog_compiler_pic" >&6; } # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 + { $as_echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no @@ -6971,11 +7170,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6974: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7173: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6978: \$? = $ac_status" >&5 + echo "$as_me:7177: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6988,7 +7187,7 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then @@ -7012,9 +7211,9 @@ fi # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +{ $as_echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if test "${lt_cv_prog_compiler_static_works+set}" = set; then : +if test "${lt_cv_prog_compiler_static_works+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no @@ -7040,7 +7239,7 @@ else LDFLAGS="$save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then @@ -7055,9 +7254,9 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if test "${lt_cv_prog_compiler_c_o+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -7076,11 +7275,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7079: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7278: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7083: \$? = $ac_status" >&5 + echo "$as_me:7282: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7102,7 +7301,7 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } @@ -7110,9 +7309,9 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if test "${lt_cv_prog_compiler_c_o+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -7131,11 +7330,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7134: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7333: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7138: \$? = $ac_status" >&5 + echo "$as_me:7337: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7157,7 +7356,7 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } @@ -7166,7 +7365,7 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 + { $as_echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* @@ -7174,10 +7373,10 @@ $as_echo_n "checking if we can lock with hard links... " >&6; } touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 + { $as_echo "$as_me:$LINENO: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 + { $as_echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi @@ -7190,7 +7389,7 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 + { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= @@ -7632,7 +7831,11 @@ _LT_EOF allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -7643,7 +7846,27 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -7657,9 +7880,16 @@ aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpat if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -7672,7 +7902,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi else # Determine the default libpath from the value encoded in an # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -7683,7 +7917,27 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -7697,9 +7951,16 @@ aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpat if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -7911,16 +8172,42 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + cat >conftest.$ac_ext <<_ACEOF int foo(void) {} _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' @@ -8176,7 +8463,7 @@ rm -f core conftest.err conftest.$ac_objext \ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +{ $as_echo "$as_me:$LINENO: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no @@ -8213,16 +8500,16 @@ x|xyes) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + { $as_echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext @@ -8236,11 +8523,11 @@ $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } then archive_cmds_need_lc=no else @@ -8251,7 +8538,7 @@ $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } cat conftest.err 1>&5 fi $RM conftest* - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 + { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 $as_echo "$archive_cmds_need_lc" >&6; } ;; esac @@ -8415,7 +8702,7 @@ esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 + { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then @@ -8850,7 +9137,11 @@ linux* | k*bsd*-gnu) save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -8861,13 +9152,41 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir @@ -9079,7 +9398,7 @@ uts4*) dynamic_linker=no ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +{ $as_echo "$as_me:$LINENO: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no @@ -9181,7 +9500,7 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + { $as_echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || @@ -9206,7 +9525,7 @@ else # directories. hardcode_action=unsupported fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +{ $as_echo "$as_me:$LINENO: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || @@ -9251,14 +9570,18 @@ else darwin*) # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 + { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -9276,18 +9599,43 @@ return dlopen (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_dl_dlopen=yes else - ac_cv_lib_dl_dlopen=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else @@ -9300,18 +9648,106 @@ fi ;; *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = x""yes; then : + { $as_echo "$as_me:$LINENO: checking for shl_load" >&5 +$as_echo_n "checking for shl_load... " >&6; } +if test "${ac_cv_func_shl_load+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shl_load || defined __stub___shl_load +choke me +#endif + +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func_shl_load=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shl_load=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +$as_echo "$ac_cv_func_shl_load" >&6; } +if test $ac_cv_func_shl_load = yes; then lt_cv_dlopen="shl_load" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 + { $as_echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } -if test "${ac_cv_lib_dld_shl_load+set}" = set; then : +if test "${ac_cv_lib_dld_shl_load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -9329,32 +9765,145 @@ return shl_load (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_dld_shl_load=yes else - ac_cv_lib_dld_shl_load=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : +if test $ac_cv_lib_dld_shl_load = yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = x""yes; then : + { $as_echo "$as_me:$LINENO: checking for dlopen" >&5 +$as_echo_n "checking for dlopen... " >&6; } +if test "${ac_cv_func_dlopen+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_dlopen || defined __stub___dlopen +choke me +#endif + +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func_dlopen=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_dlopen=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +$as_echo "$ac_cv_func_dlopen" >&6; } +if test $ac_cv_func_dlopen = yes; then lt_cv_dlopen="dlopen" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 + { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -9372,28 +9921,57 @@ return dlopen (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_dl_dlopen=yes else - ac_cv_lib_dl_dlopen=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 + { $as_echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } -if test "${ac_cv_lib_svld_dlopen+set}" = set; then : +if test "${ac_cv_lib_svld_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -9411,28 +9989,57 @@ return dlopen (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_svld_dlopen=yes else - ac_cv_lib_svld_dlopen=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : +if test $ac_cv_lib_svld_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 + { $as_echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } -if test "${ac_cv_lib_dld_dld_link+set}" = set; then : +if test "${ac_cv_lib_dld_dld_link+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -9450,18 +10057,43 @@ return dld_link (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_dld_dld_link=yes else - ac_cv_lib_dld_dld_link=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : +if test $ac_cv_lib_dld_dld_link = yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi @@ -9500,9 +10132,9 @@ fi save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 + { $as_echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self+set}" = set; then : +if test "${lt_cv_dlopen_self+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -9511,7 +10143,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9514 "configure" +#line 10146 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9570,11 +10202,11 @@ int main () return status; } _LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -9591,14 +10223,14 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 + { $as_echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self_static+set}" = set; then : +if test "${lt_cv_dlopen_self_static+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -9607,7 +10239,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9610 "configure" +#line 10242 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9666,11 +10298,11 @@ int main () return status; } _LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -9687,7 +10319,7 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi @@ -9726,12 +10358,12 @@ fi striplib= old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +{ $as_echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough @@ -9740,15 +10372,15 @@ else if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } ;; esac @@ -9766,12 +10398,12 @@ fi # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 + { $as_echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 + { $as_echo "$as_me:$LINENO: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 + { $as_echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no @@ -9792,14 +10424,14 @@ $as_echo_n "checking whether to build shared libraries... " >&6; } fi ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 + { $as_echo "$as_me:$LINENO: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 + { $as_echo "$as_me:$LINENO: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 + { $as_echo "$as_me:$LINENO: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } @@ -9848,10 +10480,10 @@ CC="$lt_save_CC" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : +if test "${ac_cv_path_install+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9859,11 +10491,11 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. @@ -9900,7 +10532,7 @@ case $as_dir/ in #(( ;; esac - done +done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir @@ -9916,7 +10548,7 @@ fi INSTALL=$ac_install_sh fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. @@ -9931,9 +10563,9 @@ for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if test "${ac_cv_prog_AWK+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -9944,24 +10576,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 + { $as_echo "$as_me:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -9974,15 +10606,15 @@ done # Enable large file support (if special flags are necessary) # # Check whether --enable-largefile was given. -if test "${enable_largefile+set}" = set; then : +if test "${enable_largefile+set}" = set; then enableval=$enable_largefile; fi if test "$enable_largefile" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 + { $as_echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } -if test "${ac_cv_sys_largefile_CC+set}" = set; then : +if test "${ac_cv_sys_largefile_CC+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no @@ -9991,7 +10623,11 @@ else while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. @@ -10010,14 +10646,60 @@ main () return 0; } _ACEOF - if ac_fn_c_try_compile "$LINENO"; then : + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" - if ac_fn_c_try_compile "$LINENO"; then : + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_sys_largefile_CC=' -n32'; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext break done @@ -10025,19 +10707,23 @@ rm -f core conftest.err conftest.$ac_objext rm -f conftest.$ac_ext fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 + { $as_echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if test "${ac_cv_sys_file_offset_bits+set}" = set; then : +if test "${ac_cv_sys_file_offset_bits+set}" = set; then $as_echo_n "(cached) " >&6 else while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. @@ -10056,11 +10742,38 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=no; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include @@ -10080,15 +10793,38 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=64; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; @@ -10100,13 +10836,17 @@ _ACEOF esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 + { $as_echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } -if test "${ac_cv_sys_large_files+set}" = set; then : +if test "${ac_cv_sys_large_files+set}" = set; then $as_echo_n "(cached) " >&6 else while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. @@ -10125,11 +10865,38 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=no; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGE_FILES 1 #include @@ -10149,15 +10916,38 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=1; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; @@ -10174,8 +10964,101 @@ fi ######### # Check for needed/wanted data types -ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" -if test "x$ac_cv_type_int8_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for int8_t" >&5 +$as_echo_n "checking for int8_t... " >&6; } +if test "${ac_cv_type_int8_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_int8_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (int8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((int8_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int8_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_int8_t" >&5 +$as_echo "$ac_cv_type_int8_t" >&6; } +if test $ac_cv_type_int8_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INT8_T 1 @@ -10183,8 +11066,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" -if test "x$ac_cv_type_int16_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for int16_t" >&5 +$as_echo_n "checking for int16_t... " >&6; } +if test "${ac_cv_type_int16_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_int16_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (int16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((int16_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int16_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5 +$as_echo "$ac_cv_type_int16_t" >&6; } +if test $ac_cv_type_int16_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INT16_T 1 @@ -10192,8 +11168,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" -if test "x$ac_cv_type_int32_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for int32_t" >&5 +$as_echo_n "checking for int32_t... " >&6; } +if test "${ac_cv_type_int32_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_int32_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (int32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((int32_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int32_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5 +$as_echo "$ac_cv_type_int32_t" >&6; } +if test $ac_cv_type_int32_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INT32_T 1 @@ -10201,8 +11270,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" -if test "x$ac_cv_type_int64_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for int64_t" >&5 +$as_echo_n "checking for int64_t... " >&6; } +if test "${ac_cv_type_int64_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_int64_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (int64_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((int64_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int64_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_int64_t" >&5 +$as_echo "$ac_cv_type_int64_t" >&6; } +if test $ac_cv_type_int64_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INT64_T 1 @@ -10210,8 +11372,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" -if test "x$ac_cv_type_intptr_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for intptr_t" >&5 +$as_echo_n "checking for intptr_t... " >&6; } +if test "${ac_cv_type_intptr_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_intptr_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (intptr_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((intptr_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_intptr_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 +$as_echo "$ac_cv_type_intptr_t" >&6; } +if test $ac_cv_type_intptr_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INTPTR_T 1 @@ -10219,8 +11474,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" -if test "x$ac_cv_type_uint8_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for uint8_t" >&5 +$as_echo_n "checking for uint8_t... " >&6; } +if test "${ac_cv_type_uint8_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_uint8_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (uint8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((uint8_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint8_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5 +$as_echo "$ac_cv_type_uint8_t" >&6; } +if test $ac_cv_type_uint8_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINT8_T 1 @@ -10228,8 +11576,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" -if test "x$ac_cv_type_uint16_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for uint16_t" >&5 +$as_echo_n "checking for uint16_t... " >&6; } +if test "${ac_cv_type_uint16_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_uint16_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (uint16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((uint16_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint16_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5 +$as_echo "$ac_cv_type_uint16_t" >&6; } +if test $ac_cv_type_uint16_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINT16_T 1 @@ -10237,8 +11678,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" -if test "x$ac_cv_type_uint32_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for uint32_t" >&5 +$as_echo_n "checking for uint32_t... " >&6; } +if test "${ac_cv_type_uint32_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_uint32_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (uint32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((uint32_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint32_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +$as_echo "$ac_cv_type_uint32_t" >&6; } +if test $ac_cv_type_uint32_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINT32_T 1 @@ -10246,8 +11780,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" -if test "x$ac_cv_type_uint64_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for uint64_t" >&5 +$as_echo_n "checking for uint64_t... " >&6; } +if test "${ac_cv_type_uint64_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_uint64_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (uint64_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((uint64_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint64_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +$as_echo "$ac_cv_type_uint64_t" >&6; } +if test $ac_cv_type_uint64_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINT64_T 1 @@ -10255,8 +11882,101 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = x""yes; then : +{ $as_echo "$as_me:$LINENO: checking for uintptr_t" >&5 +$as_echo_n "checking for uintptr_t... " >&6; } +if test "${ac_cv_type_uintptr_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_uintptr_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (uintptr_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((uintptr_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uintptr_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 +$as_echo "$ac_cv_type_uintptr_t" >&6; } +if test $ac_cv_type_uintptr_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINTPTR_T 1 @@ -10268,11 +11988,146 @@ fi ######### # Check for needed/wanted headers + + + + for ac_header in sys/types.h stdlib.h stdint.h inttypes.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 +$as_echo_n "checking $ac_header usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 +$as_echo_n "checking $ac_header presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + +fi +if test `eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -10285,11 +12140,105 @@ done ######### # Figure out whether or not we have these functions # -for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + + + + + + + +for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if test `eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10312,9 +12261,9 @@ for ac_prog in tclsh8.5 tclsh do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_TCLSH_CMD+set}" = set; then : +if test "${ac_cv_prog_TCLSH_CMD+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$TCLSH_CMD"; then @@ -10325,24 +12274,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_TCLSH_CMD="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi TCLSH_CMD=$ac_cv_prog_TCLSH_CMD if test -n "$TCLSH_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_CMD" >&5 + { $as_echo "$as_me:$LINENO: result: $TCLSH_CMD" >&5 $as_echo "$TCLSH_CMD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -10380,17 +12329,17 @@ fi VERSION=`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Version set to $VERSION" >&5 +{ $as_echo "$as_me:$LINENO: Version set to $VERSION" >&5 $as_echo "$as_me: Version set to $VERSION" >&6;} RELEASE=`cat $srcdir/VERSION` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Release set to $RELEASE" >&5 +{ $as_echo "$as_me:$LINENO: Release set to $RELEASE" >&5 $as_echo "$as_me: Release set to $RELEASE" >&6;} VERSION_NUMBER=`cat $srcdir/VERSION \ | sed 's/[^0-9]/ /g' \ | awk '{printf "%d%03d%03d",$1,$2,$3}'` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Version number set to $VERSION_NUMBER" >&5 +{ $as_echo "$as_me:$LINENO: Version number set to $VERSION_NUMBER" >&5 $as_echo "$as_me: Version number set to $VERSION_NUMBER" >&6;} @@ -10403,7 +12352,7 @@ $as_echo "$as_me: Version number set to $VERSION_NUMBER" >&6;} # # Check whether --with-hints was given. -if test "${with_hints+set}" = set; then : +if test "${with_hints+set}" = set; then withval=$with_hints; hints=$withval fi @@ -10428,7 +12377,7 @@ if test "$hints" = ""; then fi fi if test "$hints" != ""; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: reading hints from $hints" >&5 + { $as_echo "$as_me:$LINENO: result: reading hints from $hints" >&5 $as_echo "reading hints from $hints" >&6; } . $hints fi @@ -10446,9 +12395,9 @@ else do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BUILD_CC+set}" = set; then : +if test "${ac_cv_prog_BUILD_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$BUILD_CC"; then @@ -10459,24 +12408,24 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do + for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done +done IFS=$as_save_IFS fi fi BUILD_CC=$ac_cv_prog_BUILD_CC if test -n "$BUILD_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_CC" >&5 + { $as_echo "$as_me:$LINENO: result: $BUILD_CC" >&5 $as_echo "$BUILD_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi @@ -10495,33 +12444,37 @@ fi # Do we want to support multithreaded use of sqlite # # Check whether --enable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then : +if test "${enable_threadsafe+set}" = set; then enableval=$enable_threadsafe; else enable_threadsafe=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5 +{ $as_echo "$as_me:$LINENO: checking whether to support threadsafe operation" >&5 $as_echo_n "checking whether to support threadsafe operation... " >&6; } if test "$enable_threadsafe" = "no"; then SQLITE_THREADSAFE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else SQLITE_THREADSAFE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } fi if test "$SQLITE_THREADSAFE" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 + { $as_echo "$as_me:$LINENO: checking for library containing pthread_create" >&5 $as_echo_n "checking for library containing pthread_create... " >&6; } -if test "${ac_cv_search_pthread_create+set}" = set; then : +if test "${ac_cv_search_pthread_create+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -10546,27 +12499,54 @@ for ac_lib in '' pthread; do ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_search_pthread_create=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_pthread_create+set}" = set; then : + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_pthread_create+set}" = set; then break fi done -if test "${ac_cv_search_pthread_create+set}" = set; then : - +if test "${ac_cv_search_pthread_create+set}" = set; then + : else ac_cv_search_pthread_create=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_pthread_create" >&5 $as_echo "$ac_cv_search_pthread_create" >&6; } ac_res=$ac_cv_search_pthread_create -if test "$ac_res" != no; then : +if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi @@ -10579,21 +12559,21 @@ fi # due to bugs in the threading implementations. This is thus off by default. # # Check whether --enable-cross-thread-connections was given. -if test "${enable_cross_thread_connections+set}" = set; then : +if test "${enable_cross_thread_connections+set}" = set; then enableval=$enable_cross_thread_connections; else enable_xthreadconnect=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to allow connections to be shared across threads" >&5 +{ $as_echo "$as_me:$LINENO: checking whether to allow connections to be shared across threads" >&5 $as_echo_n "checking whether to allow connections to be shared across threads... " >&6; } if test "$enable_xthreadconnect" = "no"; then XTHREADCONNECT='' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else XTHREADCONNECT='-DSQLITE_ALLOW_XTHREAD_CONNECT=1' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } fi @@ -10602,21 +12582,21 @@ fi # Do we want to support release # # Check whether --enable-releasemode was given. -if test "${enable_releasemode+set}" = set; then : +if test "${enable_releasemode+set}" = set; then enableval=$enable_releasemode; else enable_releasemode=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support shared library linked as release mode or not" >&5 +{ $as_echo "$as_me:$LINENO: checking whether to support shared library linked as release mode or not" >&5 $as_echo_n "checking whether to support shared library linked as release mode or not... " >&6; } if test "$enable_releasemode" = "no"; then ALLOWRELEASE="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } else ALLOWRELEASE="-release `cat $srcdir/VERSION`" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } fi @@ -10625,38 +12605,38 @@ fi # Do we want temporary databases in memory # # Check whether --enable-tempstore was given. -if test "${enable_tempstore+set}" = set; then : +if test "${enable_tempstore+set}" = set; then enableval=$enable_tempstore; else enable_tempstore=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an in-ram database for temporary tables" >&5 +{ $as_echo "$as_me:$LINENO: checking whether to use an in-ram database for temporary tables" >&5 $as_echo_n "checking whether to use an in-ram database for temporary tables... " >&6; } case "$enable_tempstore" in never ) TEMP_STORE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: never" >&5 + { $as_echo "$as_me:$LINENO: result: never" >&5 $as_echo "never" >&6; } ;; no ) TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } ;; yes ) TEMP_STORE=2 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } ;; always ) TEMP_STORE=3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: always" >&5 + { $as_echo "$as_me:$LINENO: result: always" >&5 $as_echo "always" >&6; } ;; * ) TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } ;; esac @@ -10668,17 +12648,53 @@ esac # the CYGWIN environment. So check for that special case and handle # things accordingly. # -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if executables have the .exe suffix" >&5 +{ $as_echo "$as_me:$LINENO: checking if executables have the .exe suffix" >&5 $as_echo_n "checking if executables have the .exe suffix... " >&6; } if test "$config_BUILD_EXEEXT" = ".exe"; then CYGWIN=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 + { $as_echo "$as_me:$LINENO: result: unknown" >&5 $as_echo "unknown" >&6; } fi if test "$CYGWIN" != "yes"; then + { $as_echo "$as_me:$LINENO: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +$as_echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + case $host_os in *cygwin* ) CYGWIN=yes;; @@ -10730,7 +12746,7 @@ fi # minor changes to accomodate systems that do not have TCL installed. # # Check whether --enable-tcl was given. -if test "${enable_tcl+set}" = set; then : +if test "${enable_tcl+set}" = set; then enableval=$enable_tcl; use_tcl=$enableval else use_tcl=yes @@ -10739,13 +12755,13 @@ fi if test "${use_tcl}" = "yes" ; then # Check whether --with-tcl was given. -if test "${with_tcl+set}" = set; then : +if test "${with_tcl+set}" = set; then withval=$with_tcl; with_tclconfig=${withval} fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 + { $as_echo "$as_me:$LINENO: checking for Tcl configuration" >&5 $as_echo_n "checking for Tcl configuration... " >&6; } - if test "${ac_cv_c_tclconfig+set}" = set; then : + if test "${ac_cv_c_tclconfig+set}" = set; then $as_echo_n "(cached) " >&6 else @@ -10754,7 +12770,9 @@ else if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else - as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 +$as_echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} + { (exit 1); exit 1; }; } fi fi @@ -10827,25 +12845,25 @@ fi if test x"${ac_cv_c_tclconfig}" = x ; then use_tcl=no - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5 + { $as_echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5 $as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5 + { $as_echo "$as_me:$LINENO: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5 $as_echo "$as_me: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5 + { $as_echo "$as_me:$LINENO: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5 $as_echo "$as_me: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&2;} else TCL_BIN_DIR=${ac_cv_c_tclconfig} - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 + { $as_echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 $as_echo "found $TCL_BIN_DIR/tclConfig.sh" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 + { $as_echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 $as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; } if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 + { $as_echo "$as_me:$LINENO: result: loading" >&5 $as_echo "loading" >&6; } . $TCL_BIN_DIR/tclConfig.sh else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5 + { $as_echo "$as_me:$LINENO: result: file not found" >&5 $as_echo "file not found" >&6; } fi @@ -10906,7 +12924,7 @@ TARGET_READLINE_LIBS="" TARGET_READLINE_INC="" TARGET_HAVE_READLINE=0 # Check whether --enable-readline was given. -if test "${enable_readline+set}" = set; then : +if test "${enable_readline+set}" = set; then enableval=$enable_readline; with_readline=$enableval else with_readline=auto @@ -10918,7 +12936,7 @@ if test x"$with_readline" != xno; then # Check whether --with-readline-lib was given. -if test "${with_readline_lib+set}" = set; then : +if test "${with_readline_lib+set}" = set; then withval=$with_readline_lib; with_readline_lib=$withval else with_readline_lib="auto" @@ -10927,13 +12945,17 @@ fi if test "x$with_readline_lib" = xauto; then save_LIBS="$LIBS" LIBS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 + { $as_echo "$as_me:$LINENO: checking for library containing tgetent" >&5 $as_echo_n "checking for library containing tgetent... " >&6; } -if test "${ac_cv_search_tgetent+set}" = set; then : +if test "${ac_cv_search_tgetent+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -10958,41 +12980,72 @@ for ac_lib in '' readline ncurses curses termcap; do ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_search_tgetent=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_tgetent+set}" = set; then : + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_tgetent+set}" = set; then break fi done -if test "${ac_cv_search_tgetent+set}" = set; then : - +if test "${ac_cv_search_tgetent+set}" = set; then + : else ac_cv_search_tgetent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tgetent" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_tgetent" >&5 $as_echo "$ac_cv_search_tgetent" >&6; } ac_res=$ac_cv_search_tgetent -if test "$ac_res" != no; then : +if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" term_LIBS="$LIBS" else term_LIBS="" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 + { $as_echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } -if test "${ac_cv_lib_readline_readline+set}" = set; then : +if test "${ac_cv_lib_readline_readline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -11010,18 +13063,43 @@ return readline (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_readline_readline=yes else - ac_cv_lib_readline_readline=no + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_readline_readline=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = x""yes; then : +if test $ac_cv_lib_readline_readline = yes; then TARGET_READLINE_LIBS="-lreadline" else found="no" @@ -11035,15 +13113,141 @@ fi # Check whether --with-readline-inc was given. -if test "${with_readline_inc+set}" = set; then : +if test "${with_readline_inc+set}" = set; then withval=$with_readline_inc; with_readline_inc=$withval else with_readline_inc="auto" fi if test "x$with_readline_inc" = xauto; then - ac_fn_c_check_header_mongrel "$LINENO" "readline.h" "ac_cv_header_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_h" = x""yes; then : + if test "${ac_cv_header_readline_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for readline.h" >&5 +$as_echo_n "checking for readline.h... " >&6; } +if test "${ac_cv_header_readline_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5 +$as_echo "$ac_cv_header_readline_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking readline.h usability" >&5 +$as_echo_n "checking readline.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking readline.h presence" >&5 +$as_echo_n "checking readline.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: readline.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: readline.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: readline.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: readline.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: readline.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: readline.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: readline.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: readline.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: readline.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for readline.h" >&5 +$as_echo_n "checking for readline.h... " >&6; } +if test "${ac_cv_header_readline_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_readline_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5 +$as_echo "$ac_cv_header_readline_h" >&6; } + +fi +if test $ac_cv_header_readline_h = yes; then found="yes" else @@ -11052,23 +13256,27 @@ else for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do for subdir in include include/readline; do as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/readline.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/readline.h" >&5 +{ $as_echo "$as_me:$LINENO: checking for $dir/$subdir/readline.h" >&5 $as_echo_n "checking for $dir/$subdir/readline.h... " >&6; } -if eval "test \"\${$as_ac_File+set}\"" = set; then : +if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +$as_echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } if test -r "$dir/$subdir/readline.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +ac_res=`eval 'as_val=${'$as_ac_File'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : +if test `eval 'as_val=${'$as_ac_File'} + $as_echo "$as_val"'` = yes; then found=yes fi @@ -11105,13 +13313,17 @@ fi # Figure out what C libraries are required to compile programs # that use "fdatasync()" function. # -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5 +{ $as_echo "$as_me:$LINENO: checking for library containing fdatasync" >&5 $as_echo_n "checking for library containing fdatasync... " >&6; } -if test "${ac_cv_search_fdatasync+set}" = set; then : +if test "${ac_cv_search_fdatasync+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -11136,27 +13348,54 @@ for ac_lib in '' rt; do ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_search_fdatasync=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_fdatasync+set}" = set; then : + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_fdatasync+set}" = set; then break fi done -if test "${ac_cv_search_fdatasync+set}" = set; then : - +if test "${ac_cv_search_fdatasync+set}" = set; then + : else ac_cv_search_fdatasync=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_fdatasync" >&5 $as_echo "$ac_cv_search_fdatasync" >&6; } ac_res=$ac_cv_search_fdatasync -if test "$ac_res" != no; then : +if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi @@ -11165,7 +13404,7 @@ fi ######### # check for debug enabled # Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : +if test "${enable_debug+set}" = set; then enableval=$enable_debug; use_debug=$enableval else use_debug=no @@ -11181,7 +13420,7 @@ fi ######### # See whether we should use the amalgamation to build # Check whether --enable-amalgamation was given. -if test "${enable_amalgamation+set}" = set; then : +if test "${enable_amalgamation+set}" = set; then enableval=$enable_amalgamation; use_amalgamation=$enableval else use_amalgamation=yes @@ -11195,7 +13434,7 @@ fi ######### # See whether we should allow loadable extensions # Check whether --enable-load-extension was given. -if test "${enable_load_extension+set}" = set; then : +if test "${enable_load_extension+set}" = set; then enableval=$enable_load_extension; use_loadextension=$enableval else use_loadextension=no @@ -11203,13 +13442,17 @@ fi if test "${use_loadextension}" = "yes" ; then OPT_FEATURE_FLAGS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 + { $as_echo "$as_me:$LINENO: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } -if test "${ac_cv_search_dlopen+set}" = set; then : +if test "${ac_cv_search_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -11234,27 +13477,54 @@ for ac_lib in '' dl; do ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_search_dlopen=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_dlopen+set}" = set; then : + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_dlopen+set}" = set; then break fi done -if test "${ac_cv_search_dlopen+set}" = set; then : - +if test "${ac_cv_search_dlopen+set}" = set; then + : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen -if test "$ac_res" != no; then : +if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi @@ -11317,7 +13587,7 @@ BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS ######### # See whether we should use GCOV # Check whether --enable-gcov was given. -if test "${enable_gcov+set}" = set; then : +if test "${enable_gcov+set}" = set; then enableval=$enable_gcov; use_gcov=$enableval else use_gcov=no @@ -11369,13 +13639,13 @@ _ACEOF case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +$as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; + *) $as_unset $ac_var ;; esac ;; esac done @@ -11383,8 +13653,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" @@ -11407,11 +13677,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi @@ -11425,15 +13695,14 @@ DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= -U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs @@ -11445,10 +13714,9 @@ LTLIBOBJS=$ac_ltlibobjs ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. @@ -11458,18 +13726,17 @@ cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 debug=false ac_cs_recheck=false ac_cs_silent=false - SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which @@ -11477,15 +13744,23 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; esac + fi + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + as_nl=' ' export as_nl @@ -11493,13 +13768,7 @@ export as_nl as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else @@ -11510,7 +13779,7 @@ else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; - case $arg in #( + case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; @@ -11533,6 +13802,13 @@ if test "${PATH_SEPARATOR+set}" != set; then } fi +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + # IFS # We need space, tab and new line, in precisely that order. Quoting is @@ -11542,15 +13818,15 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( +case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done IFS=$as_save_IFS ;; @@ -11562,16 +13838,12 @@ if test "x$as_myself" = x; then fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 + { (exit 1); exit 1; } fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' @@ -11583,89 +13855,7 @@ export LC_ALL LANGUAGE=C export LANGUAGE -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - +# Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr @@ -11679,12 +13869,8 @@ else as_basename=false fi -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi +# Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ @@ -11704,25 +13890,76 @@ $as_echo X/"$0" | } s/.*/./; q'` -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( +case `echo -n x` in -n*) - case `echo 'xy\c'` in + case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; + *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then @@ -11751,56 +13988,8 @@ fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' + as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false @@ -11819,10 +14008,10 @@ else if test -d "$1"; then test -d "$1/."; else - case $1 in #( + case $1 in -*)set "./$1";; esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' @@ -11837,19 +14026,13 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to +# Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.7.9, which was -generated by GNU Autoconf 2.67. Invocation command line was +This file was extended by sqlite $as_me 3.7.10, which was +generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -11862,15 +14045,6 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q` _ACEOF -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" @@ -11881,22 +14055,19 @@ _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. +\`$as_me' instantiates files from templates according to the +current configuration. -Usage: $0 [OPTION]... [TAG]... +Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages + -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] + --file=FILE[:TEMPLATE] instantiate the configuration file FILE - --header=FILE[:TEMPLATE] + --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: @@ -11908,17 +14079,16 @@ $config_headers Configuration commands: $config_commands -Report bugs to the package provider." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.7.9 -configured by $0, generated by GNU Autoconf 2.67, - with options \\"\$ac_cs_config\\" +sqlite config.status 3.7.10 +configured by $0, generated by GNU Autoconf 2.62, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -11935,16 +14105,11 @@ ac_need_defaults=: while test $# != 0 do case $1 in - --*=?*) + --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; *) ac_option=$1 ac_optarg=$2 @@ -11958,29 +14123,27 @@ do ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; esac - as_fn_append CONFIG_FILES " '$ac_optarg'" + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" + CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; + { $as_echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ @@ -11988,10 +14151,11 @@ Try \`$0 --help' for more information.";; ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; + -*) { $as_echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; - *) as_fn_append ac_config_targets " $1" + *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac @@ -12301,7 +14465,9 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; esac done @@ -12328,7 +14494,7 @@ $debug || trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 - trap 'as_fn_exit 1' 1 2 13 15 + trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. @@ -12339,7 +14505,11 @@ $debug || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +} || +{ + $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -12347,13 +14517,7 @@ $debug || if test -n "$CONFIG_FILES"; then -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi +ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' @@ -12370,18 +14534,23 @@ _ACEOF echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -12403,7 +14572,7 @@ s/'"$ac_delim"'$// t delim :nl h -s/\(.\{148\}\)..*/\1/ +s/\(.\{148\}\).*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p @@ -12417,7 +14586,7 @@ s/.\{148\}// t nl :delim h -s/\(.\{148\}\)..*/\1/ +s/\(.\{148\}\).*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p @@ -12470,28 +14639,22 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } _ACEOF -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// s/^[^=]*=[ ]*$// }' fi @@ -12519,7 +14682,9 @@ for ac_last_try in false false :; do if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} + { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -12585,9 +14750,9 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 } split(mac1, mac2, "(") #) macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". + prefix = substr(line, 1, index(line, defundef) - 1) print prefix "define", macro P[macro] D[macro] next } else { @@ -12595,7 +14760,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" + print "/*", line, "*/" next } } @@ -12604,7 +14769,9 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 +$as_echo "$as_me: error: could not setup config headers machinery" >&2;} + { (exit 1); exit 1; }; } fi # test -n "$CONFIG_HEADERS" @@ -12617,7 +14784,9 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +$as_echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -12645,10 +14814,12 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" + ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't @@ -12659,7 +14830,7 @@ do `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. @@ -12672,7 +14843,9 @@ $as_echo "$as_me: creating $ac_file" >&6;} case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; esac ;; esac @@ -12700,7 +14873,47 @@ $as_echo X"$ac_file" | q } s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in @@ -12752,6 +14965,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= + ac_sed_dataroot=' /datarootdir/ { p @@ -12761,11 +14975,12 @@ ac_sed_dataroot=' /@docdir@/p /@infodir@/p /@localedir@/p -/@mandir@/p' +/@mandir@/p +' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 @@ -12775,7 +14990,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; + s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF @@ -12803,22 +15018,26 @@ s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} +which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; :H) # @@ -12829,23 +15048,29 @@ which seems to be undefined. Please make sure it is defined" >&2;} $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 + { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 + || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 +$as_echo "$as_me: error: could not create -" >&2;} + { (exit 1); exit 1; }; } fi ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 + :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac @@ -13492,12 +15717,15 @@ _LT_EOF done # for ac_tag -as_fn_exit 0 +{ (exit 0); exit 0; } _ACEOF +chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } # configure is writing to config.log, and then calls config.status. @@ -13518,10 +15746,10 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 + $ac_cs_success || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: Unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2;} fi diff --git a/configure.ac b/configure.ac index 46afeb7..a772e03 100644 --- a/configure.ac +++ b/configure.ac @@ -127,7 +127,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h]) ######### # Figure out whether or not we have these functions # -AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime]) +AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size]) ######### # By default, we use the amalgamation (this may be changed below...) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 12013f2..88a4148 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -712,6 +712,7 @@ static void fts3Appendf( char *z; va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); if( z && *pz ){ char *z2 = sqlite3_mprintf("%s%s", *pz, z); sqlite3_free(z); diff --git a/ext/fts3/fts3_porter.c b/ext/fts3/fts3_porter.c index 148c570..84aa132 100644 --- a/ext/fts3/fts3_porter.c +++ b/ext/fts3/fts3_porter.c @@ -40,7 +40,7 @@ typedef struct porter_tokenizer { } porter_tokenizer; /* -** Class derived from sqlit3_tokenizer_cursor +** Class derived from sqlite3_tokenizer_cursor */ typedef struct porter_tokenizer_cursor { sqlite3_tokenizer_cursor base; diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 2904a9a..0ee7ea8 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1386,7 +1386,6 @@ int sqlite3Fts3SegReaderNew( int nRoot, /* Size of buffer containing root node */ Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ ){ - int rc = SQLITE_OK; /* Return code */ Fts3SegReader *pReader; /* Newly allocated SegReader object */ int nExtra = 0; /* Bytes to allocate segment root node */ @@ -1414,13 +1413,8 @@ int sqlite3Fts3SegReaderNew( }else{ pReader->iCurrentBlock = iStartLeaf-1; } - - if( rc==SQLITE_OK ){ - *ppReader = pReader; - }else{ - sqlite3Fts3SegReaderFree(pReader); - } - return rc; + *ppReader = pReader; + return SQLITE_OK; } /* @@ -1470,6 +1464,7 @@ int sqlite3Fts3SegReaderPending( Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ ){ Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ + Fts3HashElem *pE; /* Iterator variable */ Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ int nElem = 0; /* Size of array at aElem */ int rc = SQLITE_OK; /* Return Code */ @@ -1478,7 +1473,6 @@ int sqlite3Fts3SegReaderPending( pHash = &p->aIndex[iIndex].hPending; if( bPrefix ){ int nAlloc = 0; /* Size of allocated array at aElem */ - Fts3HashElem *pE = 0; /* Iterator variable */ for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ char *zKey = (char *)fts3HashKey(pE); @@ -1512,8 +1506,13 @@ int sqlite3Fts3SegReaderPending( }else{ /* The query is a simple term lookup that matches at most one term in - ** the index. All that is required is a straight hash-lookup. */ - Fts3HashElem *pE = fts3HashFindElem(pHash, zTerm, nTerm); + ** the index. All that is required is a straight hash-lookup. + ** + ** Because the stack address of pE may be accessed via the aElem pointer + ** below, the "Fts3HashElem *pE" must be declared so that it is valid + ** within this entire function, not just this "else{...}" block. + */ + pE = fts3HashFindElem(pHash, zTerm, nTerm); if( pE ){ aElem = &pE; nElem = 1; diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 884482e..4c36f26 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1193,7 +1193,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ int nBlob; /* Check that value is actually a blob. */ - if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR; + if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; /* Check that the blob is roughly the right size. */ nBlob = sqlite3_value_bytes(pValue); diff --git a/manifest b/manifest index 307b0c3..d3c4376 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Version\s3.7.9 -D 2011-11-01T00:52:41.132 +C Version\s3.7.10 +D 2012-01-16T13:28:40.069 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 +F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171 +F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248 @@ -21,10 +21,10 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 -F config.h.in 405a958bdb3af382a809dccb08a44694923ddd61 +F config.h.in 31cc8c4943f56e60c4aa4fba929c9d4c70e418b4 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 806c06aef5895860da49600ce098dbe4d5a8435c x -F configure.ac 298a759c086e72c013da459c2aec02a104f4224f +F configure 5c1cf496e63a233d2abcccf7a3570ba84d5dce01 x +F configure.ac 75323bdac56fb0e69f6a3fc5b23f24359550b9d9 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e @@ -63,7 +63,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 246ef2d0cef67517d156d39c9247cd6c432f0d79 +F ext/fts3/fts3.c bd570b99f1f65b17d587361a421d7f2f28082aa0 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h def7a900f98c5ab5fa4772e922bfa219d5097f05 F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691 @@ -71,21 +71,21 @@ F ext/fts3/fts3_expr.c f5df26bddf46a5916b2a5f80c4027996e92b7b15 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec F ext/fts3/fts3_icu.c 6c8f395cdf9e1e3afa7fadb7e523dbbf381c6dfa -F ext/fts3/fts3_porter.c 8d946908f4812c005d3d33fcbe78418b1f4eb70c +F ext/fts3/fts3_porter.c b7e5276f9f0a5fc7018b6fa55ce0f31f269ef881 F ext/fts3/fts3_snippet.c 1f9ee6a8e0e242649645968dcec4deb253d86c2a F ext/fts3/fts3_term.c a5457992723455a58804cb75c8cbd8978db5c2ef F ext/fts3/fts3_test.c 24fa13f330db011500acb95590da9eee24951894 F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3 F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68 -F ext/fts3/fts3_write.c c097228bff4d33c6b8a270c9717b9f8339068776 +F ext/fts3/fts3_write.c fdf0c99830360146ec7128150271c8c014a8fef7 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 692e9192d148f318b3dca9f744600346a175eedd +F ext/rtree/rtree.c b92ab2e91e35c4964644647322813419c65fe1ce F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 28e1b8da4da98093ce3210187434dd760a8d89d8 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -119,82 +119,82 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 5a1db16a651ce6310c8b046b2cbb736e030e14b9 +F src/analyze.c f32ff304da413851eefa562b04e61ff6cb88248b F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 4368158da74d4711888e03264105c5c527d76caf +F src/backup.c e9538bad2d4a4fcd4308f1aed7cb18a0fbc968f9 F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 32199e2d939233ade25340eaba450f818b37c079 +F src/btree.c a65816cc000bdd421772986e64c88c9035331332 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce -F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 +F src/btreeInt.h 6c9960645c431c9456ca56498f43a2b3bf1fa8c2 +F src/build.c 8e2a4dedad860fed982270ef43968505f35ec57f F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8 -F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8 +F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 +F src/expr.c 537591e95eac74af783e4eb033954fb218cf398e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 -F src/global.c e230227de13601714b29f9363028514aada5ae2f +F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ca18783512323f74aaf4ee74b46ffd75ec80d031 +F src/insert.c d7c69718acbb92e10e4b121da7bed13903342962 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 -F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c df06f5229b8046f85dde253dfd7fe35ae9e4902e -F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 +F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d +F src/main.c e60abee4a7ca3da31b67745ccf02b8d29f138614 +F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 +F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6 -F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f +F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc F src/mutex.h 2a79e0c10c26412546b501ee0f3d92b42decf63e -F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151 +F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553 F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f -F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 +F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 -F src/os.c 5d9b02782ed36345348d6fe21d7762ed3a9cfd2a -F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 +F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c +F src/os.h a2219c3b05ce31230bb000fdc4f1a542b33ee649 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c ddda0b1c5ae536669634d7bff31b3f8f4d654866 -F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 -F src/pager.c ad62daa0c21e27ae332b3ceb4f579a2a97046ddc -F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d -F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce -F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 -F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197 -F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7 -F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 -F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 +F src/os_unix.c 657672fab2580a84116c140b36ee3d6b6fc75b4e +F src/os_win.c 5ac061ae1326a71500cee578ed0fd9113b4f6a37 +F src/pager.c 4d58c983d9f4d34bc2d48e4280361ccaeecd03c5 +F src/pager.h 5cd760857707529b403837d813d86b68938d6183 +F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba +F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 +F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f +F src/pcache1.c 281822d22265245b19f908cb3f5df725f7e11b06 +F src/pragma.c fb979b7b5103ad0db1b72bcf349c83f5dec62574 +F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e +F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 +F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 -F src/shell.c f0ab793261ab045a0b8c47fa2707e8a894d2898f -F src/sqlite.h.in ff950aef7b378963c67add42dda5d446a0b7330e +F src/select.c a1d075db66a0ea42807353501b62997969e5be79 +F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d +F src/sqlite.h.in 53516617d2945a411d028674d7fa20dd394b9ec0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h c74457cd2c4bd77683bac76e698bf2ec2d3e13f9 +F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c 0f41b7c67719207a5de24b009e172c4dcf189827 -F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 -F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 +F src/tclsqlite.c 2aeb69958965dad0842d5ea1456f1a958ef296e6 +F src/test1.c 1b1e514e85ffe7152b02cba38bd0a1ce8cd56113 +F src/test2.c 711555927f1f7e8db9aab86b512bc6934a774abe +F src/test3.c 91d3f1a09cfae3533ef17d8b484a160f3d1f1a21 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 F src/test5.c e1a19845625144caf038031234a12185e40d315c -F src/test6.c 3191b4ab964a144230ff9ef96c093520375c7b2a +F src/test6.c cf6ab27a59e1ab64b011bb251ba600131e803e59 F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843 F src/test8.c 99f70341d6ec480313775127f4cd14b4a47db557 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -202,57 +202,58 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c bc8826296a7b3a86eeaba1ac2af5551d1c20c35b +F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc -F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 +F src/test_func.c 6232d722a4ddb193035aa13a03796bf57d6c12fd F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254 F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a -F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c +F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 -F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff +F src/test_journal.c a6a6baf343f79b942331f13378d045e7e270ae64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 3fc368022c46fe44ec22c5e1ed727223a54a6a1d +F src/test_multiplex.c afab2c9d292677ab31e0dd4b3dde2420fb655c5f F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec -F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 -F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 -F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 +F src/test_osinst.c 6abf0a37ce831120c4ef1b913afdd813e7ac1a73 +F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 +F src/test_quota.c b4a6519417d87870e7ef5838dbf3cae164dcc28d +F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_stat.c 69de4361c7a69fc1136d31ab7144408cd00805c7 +F src/test_stat.c 80271ad7d776a79babe0e025bb3a1bfcd3a3cfb1 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 -F src/test_vfs.c b0baec983bd6f872715a4b44c8f39104fec333af -F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d +F src/test_vfs.c 07157a0bbfe161cb5e32cad2079abd26cd611c4b +F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 -F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 -F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d +F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 +F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 +F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c df83983bd57057df4951516880066b42b7055269 +F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c 326994a64a9a08853122200dc9f62cb96b8f0831 -F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 -F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 -F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c a950e34449a508d48d90475acc287943a4094f3a +F src/vdbe.c 64e3fc0bb56c54ceac3cc1d1e65257bfda21550e +F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb +F src/vdbeInt.h ef9b8584b23b033894a0804dc6b90196c6779fb9 +F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 +F src/vdbeaux.c eb13a6917ed7455b5b49236fe5cfb3d3c3e4c57b F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb -F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 +F src/vdbemem.c 4f7d25d5ea2e2040254095b8f6de07f8dbbadf80 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 -F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 +F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 9658df8d404b82e6b2d40fd05944463214e2d935 -F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a +F src/wal.c 5f7bcc0610af759953defd769eacebfd98a22bc8 +F src/wal.h eaa00b9a403ddda2b56d01b7afc19ef600f9363f F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 7c85f4c93058e27100d404f0777aaeb0d1b296ae +F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -274,7 +275,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c -F test/attach.test 0e6f8de2589f11a5f474ef57fe5af2877e61c0e8 +F test/attach.test 0d112b7713611fdf0340260192749737135fda5f F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c @@ -289,13 +290,14 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/backcompat.test 71eeb75ea567c060774c4e8db4b0e703f21c7677 F test/backup.test 6970614b002b056ae5bab5b76559905e02b6f0b2 -F test/backup2.test b4966934b2dc10a9a6546114566ea69b34a5185e +F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0 F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 F test/bigfile.test a8ec8073a20207456dab01a29ad9cde42b0dd103 +F test/bigfile2.test f8e83eca9abef60692a34255a2ebcb96aff897fc F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0 @@ -315,7 +317,7 @@ F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360 F test/capi3.test 7200dff6acb17b9a4b6f9918f554eaae04968ddd F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test ccf0acf045dbacd09f6229aa4efed670aaba76a9 -F test/capi3d.test cd36571f014f34bdc4421967f6453cbb597d5d16 +F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test db2b29d557544347d28e25b8406f5d5ecc3d1bc3 @@ -347,6 +349,7 @@ F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647 F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb F test/corruptD.test 99b1999dbfa7cc04aaeac9d695a2445d4e7c7458 F test/corruptE.test 1b9eb20a8711251ce57b44a257e241085b39b52d +F test/corruptF.test 984b1706c9c0e4248141b056c21124612628d12e F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/crash.test 519dc29f6fea151f015a23236e555239353946eb F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 @@ -361,7 +364,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff -F test/dbstatus.test 9eb484ba837c6f3f9bbcaecc29e6060a8c3ba6d2 +F test/dbstatus.test 3e978f8bdb2362a36a4be63c36a59f542c4cc2a3 F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 @@ -373,21 +376,21 @@ F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test df5b11ad606439129c88720a86787bc9ca181f31 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test 4771686a586b6ae414f927c389b2c101cc05c028 -F test/e_delete.test e2ae0d3fce5efd70fef99025e932afffc5616fab -F test/e_droptrigger.test ddd4b28ed8a3d81bd5153fa0ab7559529a2ca03a -F test/e_dropview.test b347bab30fc8de67b131594b3cd6f3d3bdaa753d -F test/e_expr.test d93ccded2409c66637dc1649a02f169e041b63d8 +F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84 +F test/e_delete.test ec168cd4b08d681e6d5847f462203755ad647532 +F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235 +F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e +F test/e_expr.test 4e4399006b3d1ab333721b8e386cabb9fb6d5a89 F test/e_fkey.test 38039b840ab19331000b0f0eb1d82baa7208a67a F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 -F test/e_insert.test 76d4bb5da9b28014d515d91ffe29a79a1e99f2bc -F test/e_reindex.test a064f0878b8f848fbca38f1f61f82f15a3000c64 +F test/e_insert.test 234242b71855af8e8a9b1e141c3533f6d43d8645 +F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test 8d7fac7a268eaeb80b9a7ba7964505b9d30f5458 +F test/e_select.test 6f488c22851c1c280ed74e16a9a1430706a3a8cb F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 -F test/e_update.test b926341a65955d69a6375c9eb4fd82e7089bc83a +F test/e_update.test dba988a4d079156549a40854074ba4890b0a4577 F test/e_uri.test 6f35b491f80dac005c8144f38b2dfb4d96483596 -F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf +F test/e_vacuum.test 5296e25ef871965bac010b9da083dd7e4734526e F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 @@ -513,7 +516,7 @@ F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7 F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597 F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 -F test/incrvacuum2.test 62fbeb85459fe4e501684d8fb5b6e98a23e3b0c0 +F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b F test/incrvacuum_ioerr.test 22f208d01c528403240e05beecc41dc98ed01637 F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 @@ -525,7 +528,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test 63ea672b0fc6d3a9a0ccee774a771510b1e684c4 +F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 @@ -543,7 +546,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d -F test/journal2.test 29937bdbb253bbfd92057610120bdc0aa7e84a0a +F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1 F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -570,7 +573,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test bc745155ff4252d4f35ec8316625b0dfe2abc659 F test/malloc3.test de8eca0c3e748878845fdca3663ec4b642073caf F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test 30dc30b57fa22552eba0d8c95210d96c3d958a39 +F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -592,7 +595,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 16ce163ac1ace3d71bf0eaa6a821ed153addd91f +F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 @@ -605,7 +608,9 @@ F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 -F test/multiplex.test 9df8bf738b3b97c718fceb3fadb30900ba494418 +F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 +F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a +F test/multiplex3.test 15903c343f1eaa4b00998b7ceacfc4987e4ccfe9 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -616,7 +621,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 -F test/pager1.test 1b630b3248c7d28862fe9e190cfe52234b502504 +F test/pager1.test 9e9f5f1c6d4df4831dbff213b1262ef94bf72118 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 @@ -626,14 +631,16 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 -F test/permutations.test 522823b47238cb1754198f80817fe9f9158ede55 -F test/pragma.test 1ea0c85be853135bb7468e6eed48ee12b04794d4 +F test/permutations.test fa6f0e5f13fe0b1d3f7a7613179b7f7b20028184 +F test/pragma.test 7fa35e53085812dac94c2bfcbb02c2a4ad35df5e F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quota.test 1c59a396e8f7b5d8466fa74b59f2aeb778d74f7a +F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 +F test/quota.test af47d25c166aa7b33ef25f21bb7f2afb29d82c77 +F test/quota2.test 1b8df088e604f2df573f96e726b5e518cb0cddaa F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -666,7 +673,7 @@ F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test 74c0fb2c6eecb0219cbed0cbe3df136f8fbf9343 F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 -F test/selectB.test 0d072c5846071b569766e6cd7f923f646a8b2bfa +F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48 @@ -678,6 +685,7 @@ F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 +F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53 @@ -697,17 +705,17 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a -F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 +F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 966addf703faee6a5d509abe6d8885e393e552fd +F test/syscall.test 265cda616f56a297406728ee1e74c9b4a93aa6dd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 -F test/tclsqlite.test 5ebcbb0dccc3fbc1edc3bba84c38e2c2d574c5aa +F test/tclsqlite.test 1597d353308531527583481d14d9da52ea8ed0af F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl 0b2999b578964297663de4870babbbee29225622 +F test/tester.tcl 001051eaf28c1040800f588a64c63e0bd0e1f36b F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -727,6 +735,7 @@ F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9 F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac F test/tkt-38cb5df375.test 9e9b19857dba0896a8efdaf334d405ba423492f2 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 +F test/tkt-3a77c9714e.test 1675c22a5be71d7fa026e5db5daeeb4dd64f7824 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 @@ -735,6 +744,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7 +F test/tkt-7bbfb7d442.test 8e7658f77d1ccea9d88dc9e255d3ed7fb68f8bdf F test/tkt-80ba201079.test a09684db1a0bd55b8838f606adccee456a51ddbf F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c @@ -863,7 +873,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 -F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e +F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46 F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/uri.test 0d289d32396bdbc491e9dc845f1a52e13f861e0b @@ -893,24 +903,25 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test e11da8d5ea8a38a247339455098357e9adf63d76 -F test/wal2.test ad6412596815f553cd30f271d291ab003092bc7e -F test/wal3.test 18da4e65c30c43c646ad40e145e9a074e4062fc9 +F test/wal.test edefe316b4125d7f68004ea53c5e73c398d436cc +F test/wal2.test f11883dd3cb7f647c5d2acfd7b5c6d4ba5770cc9 +F test/wal3.test 6504bbf348b2d6dfade64a064f1050fd617e8706 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c -F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b +F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbig.test 0ab8a430ef420a3114f7092e0f30fc9585ffa155 F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde -F test/walcrash.test 4fcb661faf71db91214156d52d43ee327f52bde1 +F test/walcrash.test 4457436593be8c136f9148487c7dccd5e9013af2 F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142 -F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 +F test/walcrash3.test 595e44c6197f0d0aa509fc135be2fd0209d11a2c +F test/walfault.test 97394d8de82a99f7abf1c12ed229640607fd0ad2 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/walpersist.test fd40d33765b2693f721c90c66d97f99757559006 +F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a @@ -927,9 +938,11 @@ F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test bed66dcfc69a54a99661c0c9906189cb5e58f4e2 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 +F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 +F test/zerodamage.test 0de750389990b1078bab203c712dc3fefd1d8b82 F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -937,7 +950,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 949328f67cac94969d3112b105b8457edf27f44e +F tool/lemon.c 445f18999b700d83b83a5d9be00c596546c21052 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -974,8 +987,8 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6635cd9a7714b681dd8aa96e90be462a40d10178 -R b059ff356abfc5b4524a9b548916f43e -T +sym-version-3.7.9 * +P 9da1cd0a06aca4eb3fb21fa4d321b9e3e07444b4 +R 81a3b6b323708ac95becda2f7731a3a4 +T +sym-version-3.7.10 * U drh -Z a9ecbb5c487c786a176874d979505217 +Z 1c2c75389d69d7c8466f72bd2161ada0 diff --git a/manifest.uuid b/manifest.uuid index cf01f92..15673d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7c6050ef060877ebe77b41d959e9df13f8c9b5e +ebd01a8deffb5024a5d7494eef800d2366d97204 diff --git a/sqlcipher.xcodeproj/project.pbxproj b/sqlcipher.xcodeproj/project.pbxproj index 6fa58b8..df35b13 100644 --- a/sqlcipher.xcodeproj/project.pbxproj +++ b/sqlcipher.xcodeproj/project.pbxproj @@ -195,6 +195,12 @@ ); INSTALL_PATH = /usr/local/lib; OTHER_CFLAGS = ( + "-DSQLITE_HAS_CODEC", + "-DNDEBUG", + "-DSQLITE_TEMP_STORE=2", + "-DSQLITE_THREADSAFE", + ); + "OTHER_CFLAGS[arch=armv6]" = ( "-mno-thumb", "-DSQLITE_HAS_CODEC", "-DNDEBUG", @@ -219,6 +225,13 @@ ); INSTALL_PATH = /usr/local/lib; OTHER_CFLAGS = ( + "-DSQLITE_HAS_CODEC", + "-DNDEBUG", + "-DSQLITE_OS_UNIX=1", + "-DSQLITE_TEMP_STORE=2", + "-DSQLITE_THREADSAFE", + ); + "OTHER_CFLAGS[arch=armv6]" = ( "-mno-thumb", "-DSQLITE_HAS_CODEC", "-DNDEBUG", diff --git a/src/analyze.c b/src/analyze.c index b6a987a..cbfdc85 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -529,6 +529,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); + sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum); sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, (char*)&stat3InitFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2); diff --git a/src/backup.c b/src/backup.c index bdf96bd..aa34018 100644 --- a/src/backup.c +++ b/src/backup.c @@ -678,7 +678,9 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); if( pFd->pMethods ){ i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); - sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc ) goto copy_finished; } /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set @@ -703,12 +705,13 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ assert( b.rc!=SQLITE_OK ); rc = sqlite3_backup_finish(&b); if( rc==SQLITE_OK ){ - pTo->pBt->pageSizeFixed = 0; + pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; }else{ sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } assert( sqlite3BtreeIsInTrans(pTo)==0 ); +copy_finished: sqlite3BtreeLeave(pFrom); sqlite3BtreeLeave(pTo); return rc; diff --git a/src/btree.c b/src/btree.c index d64e172..2532406 100644 --- a/src/btree.c +++ b/src/btree.c @@ -243,7 +243,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ /* If some other connection is holding an exclusive lock, the ** requested lock may not be obtained. */ - if( pBt->pWriter!=p && pBt->isExclusive ){ + if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); return SQLITE_LOCKED_SHAREDCACHE; } @@ -264,7 +264,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); if( eLock==WRITE_LOCK ){ assert( p==pBt->pWriter ); - pBt->isPending = 1; + pBt->btsFlags |= BTS_PENDING; } return SQLITE_LOCKED_SHAREDCACHE; } @@ -352,7 +352,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ ** the setSharedCacheTableLock() procedure) held by Btree object p. ** ** This function assumes that Btree p has an open read or write -** transaction. If it does not, then the BtShared.isPending variable +** transaction. If it does not, then the BTS_PENDING flag ** may be incorrectly cleared. */ static void clearAllSharedCacheTableLocks(Btree *p){ @@ -365,7 +365,7 @@ static void clearAllSharedCacheTableLocks(Btree *p){ while( *ppIter ){ BtLock *pLock = *ppIter; - assert( pBt->isExclusive==0 || pBt->pWriter==pLock->pBtree ); + assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); assert( pLock->pBtree->inTrans>=pLock->eLock ); if( pLock->pBtree==p ){ *ppIter = pLock->pNext; @@ -378,22 +378,21 @@ static void clearAllSharedCacheTableLocks(Btree *p){ } } - assert( pBt->isPending==0 || pBt->pWriter ); + assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); if( pBt->pWriter==p ){ pBt->pWriter = 0; - pBt->isExclusive = 0; - pBt->isPending = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); }else if( pBt->nTransaction==2 ){ /* This function is called when Btree p is concluding its ** transaction. If there currently exists a writer, and p is not ** that writer, then the number of locks held by connections other ** than the writer must be about to drop to zero. In this case - ** set the isPending flag to 0. + ** set the BTS_PENDING flag to 0. ** - ** If there is not currently a writer, then BtShared.isPending must + ** If there is not currently a writer, then BTS_PENDING must ** be zero already. So this next line is harmless in that case. */ - pBt->isPending = 0; + pBt->btsFlags &= ~BTS_PENDING; } } @@ -405,8 +404,7 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){ if( pBt->pWriter==p ){ BtLock *pLock; pBt->pWriter = 0; - pBt->isExclusive = 0; - pBt->isPending = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); pLock->eLock = READ_LOCK; @@ -859,7 +857,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ ** This routine works only for pages that do not contain overflow cells. */ #define findCell(P,I) \ - ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)]))) + ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) #define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) @@ -1264,7 +1262,7 @@ static int freeSpace(MemPage *pPage, int start, int size){ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( size>=0 ); /* Minimum cell size is 4 */ - if( pPage->pBt->secureDelete ){ + if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ /* Overwrite deleted information with zeros when the secure_delete ** option is enabled */ memset(&data[start], 0, size); @@ -1367,6 +1365,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ }else{ return SQLITE_CORRUPT_BKPT; } + pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; } @@ -1409,6 +1408,8 @@ static int btreeInitPage(MemPage *pPage){ pPage->nOverflow = 0; usableSize = pBt->usableSize; pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; + pPage->aDataEnd = &data[usableSize]; + pPage->aCellIdx = &data[cellOffset]; top = get2byteNotZero(&data[hdr+5]); pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ @@ -1500,7 +1501,7 @@ static void zeroPage(MemPage *pPage, int flags){ assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->secureDelete ){ + if( pBt->btsFlags & BTS_SECURE_DELETE ){ memset(&data[hdr], 0, pBt->usableSize - hdr); } data[hdr] = (char)flags; @@ -1512,6 +1513,8 @@ static void zeroPage(MemPage *pPage, int flags){ decodeFlags(pPage, flags); pPage->hdrOffset = hdr; pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aCellIdx = &data[first]; pPage->nOverflow = 0; assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); @@ -1772,7 +1775,12 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); @@ -1846,9 +1854,9 @@ int sqlite3BtreeOpen( pBt->pCursor = 0; pBt->pPage1 = 0; - pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; #ifdef SQLITE_SECURE_DELETE - pBt->secureDelete = 1; + pBt->btsFlags |= BTS_SECURE_DELETE; #endif pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE @@ -1869,7 +1877,7 @@ int sqlite3BtreeOpen( nReserve = 0; }else{ nReserve = zDbHeader[20]; - pBt->pageSizeFixed = 1; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); @@ -2157,7 +2165,7 @@ int sqlite3BtreeSyncDisabled(Btree *p){ ** If parameter nReserve is less than zero, then the number of reserved ** bytes per page is left unchanged. ** -** If the iFix!=0 then the pageSizeFixed flag is set so that the page size +** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size ** and autovacuum mode can no longer be changed. */ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ @@ -2165,7 +2173,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ BtShared *pBt = p->pBt; assert( nReserve>=-1 && nReserve<=255 ); sqlite3BtreeEnter(p); - if( pBt->pageSizeFixed ){ + if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; } @@ -2182,7 +2190,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ } rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); pBt->usableSize = pBt->pageSize - (u16)nReserve; - if( iFix ) pBt->pageSizeFixed = 1; + if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; sqlite3BtreeLeave(p); return rc; } @@ -2222,8 +2230,8 @@ int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ } /* -** Set the secureDelete flag if newFlag is 0 or 1. If newFlag is -1, -** then make no changes. Always return the value of the secureDelete +** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1, +** then make no changes. Always return the value of the BTS_SECURE_DELETE ** setting after the change. */ int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ @@ -2231,9 +2239,10 @@ int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ if( p==0 ) return 0; sqlite3BtreeEnter(p); if( newFlag>=0 ){ - p->pBt->secureDelete = (newFlag!=0) ? 1 : 0; + p->pBt->btsFlags &= ~BTS_SECURE_DELETE; + if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE; } - b = p->pBt->secureDelete; + b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0; sqlite3BtreeLeave(p); return b; } @@ -2254,7 +2263,7 @@ int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ u8 av = (u8)autoVacuum; sqlite3BtreeEnter(p); - if( pBt->pageSizeFixed && (av ?1:0)!=pBt->autoVacuum ){ + if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ rc = SQLITE_READONLY; }else{ pBt->autoVacuum = av ?1:0; @@ -2328,14 +2337,14 @@ static int lockBtree(BtShared *pBt){ #ifdef SQLITE_OMIT_WAL if( page1[18]>1 ){ - pBt->readOnly = 1; + pBt->btsFlags |= BTS_READ_ONLY; } if( page1[19]>1 ){ goto page1_init_failed; } #else if( page1[18]>2 ){ - pBt->readOnly = 1; + pBt->btsFlags |= BTS_READ_ONLY; } if( page1[19]>2 ){ goto page1_init_failed; @@ -2349,7 +2358,7 @@ static int lockBtree(BtShared *pBt){ ** may not be the latest version - there may be a newer one in the log ** file. */ - if( page1[19]==2 && pBt->doNotUseWAL==0 ){ + if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ @@ -2426,6 +2435,11 @@ static int lockBtree(BtShared *pBt){ pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); pBt->maxLeaf = (u16)(pBt->usableSize - 35); pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); pBt->pPage1 = pPage1; pBt->nPage = nPage; @@ -2489,7 +2503,7 @@ static int newDatabase(BtShared *pBt){ data[23] = 32; memset(&data[24], 0, 100-24); zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); - pBt->pageSizeFixed = 1; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; #ifndef SQLITE_OMIT_AUTOVACUUM assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); @@ -2553,7 +2567,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } /* Write transactions are not possible on a read-only database */ - if( pBt->readOnly && wrflag ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ rc = SQLITE_READONLY; goto trans_begun; } @@ -2563,7 +2577,9 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ ** on this shared-btree structure and a second write transaction is ** requested, return SQLITE_LOCKED. */ - if( (wrflag && pBt->inTransaction==TRANS_WRITE) || pBt->isPending ){ + if( (wrflag && pBt->inTransaction==TRANS_WRITE) + || (pBt->btsFlags & BTS_PENDING)!=0 + ){ pBlock = pBt->pWriter->db; }else if( wrflag>1 ){ BtLock *pIter; @@ -2587,7 +2603,8 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); if( SQLITE_OK!=rc ) goto trans_begun; - pBt->initiallyEmpty = (u8)(pBt->nPage==0); + pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; + if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; do { /* Call lockBtree() until either pBt->pPage1 is populated or ** lockBtree() returns something other than SQLITE_OK. lockBtree() @@ -2599,7 +2616,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); if( rc==SQLITE_OK && wrflag ){ - if( pBt->readOnly ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ rc = SQLITE_READONLY; }else{ rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); @@ -2636,7 +2653,8 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ #ifndef SQLITE_OMIT_SHARED_CACHE assert( !pBt->pWriter ); pBt->pWriter = p; - pBt->isExclusive = (u8)(wrflag>1); + pBt->btsFlags &= ~BTS_EXCLUSIVE; + if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; #endif /* If the db-size header field is incorrect (as it may be if an old @@ -3365,7 +3383,7 @@ int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); - assert( pBt->readOnly==0 ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( iStatement>0 ); assert( iStatement>p->db->nSavepoint ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -3400,7 +3418,9 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ sqlite3BtreeEnter(p); rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); if( rc==SQLITE_OK ){ - if( iSavepoint<0 && pBt->initiallyEmpty ) pBt->nPage = 0; + if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ + pBt->nPage = 0; + } rc = newDatabase(pBt); pBt->nPage = get4byte(28 + pBt->pPage1->aData); @@ -3470,7 +3490,7 @@ static int btreeCursor( assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); assert( pBt->pPage1 && pBt->pPage1->aData ); - if( NEVER(wrFlag && pBt->readOnly) ){ + if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){ return SQLITE_READONLY; } if( iTable==1 && btreePagecount(pBt)==0 ){ @@ -3970,7 +3990,7 @@ static int accessPayload( u8 aSave[4]; u8 *aWrite = &pBuf[-4]; memcpy(aSave, aWrite, 4); - rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1)); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else @@ -4174,7 +4194,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ return SQLITE_OK; } -#ifndef NDEBUG +#if 0 /* ** Page pParent is an internal (non-leaf) tree page. This function ** asserts that page number iChild is the left-child if the iIdx'th @@ -4207,11 +4227,21 @@ static void moveToParent(BtCursor *pCur){ assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>0 ); assert( pCur->apPage[pCur->iPage] ); + + /* UPDATE: It is actually possible for the condition tested by the assert + ** below to be untrue if the database file is corrupt. This can occur if + ** one cursor has modified page pParent while a reference to it is held + ** by a second cursor. Which can only happen if a single page is linked + ** into more than one b-tree structure in a corrupt database. */ +#if 0 assertParentIndex( pCur->apPage[pCur->iPage-1], pCur->aiIdx[pCur->iPage-1], pCur->apPage[pCur->iPage]->pgno ); +#endif + testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); + releasePage(pCur->apPage[pCur->iPage]); pCur->iPage--; pCur->info.nSize = 0; @@ -4550,16 +4580,21 @@ int sqlite3BtreeMovetoUnpacked( ** 2 bytes of the cell. */ int nCell = pCell[0]; - if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){ + if( nCell<=pPage->max1bytePayload + /* && (pCell+nCell)aDataEnd */ + ){ /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + /* && (pCell+nCell+2)<=pPage->aDataEnd */ ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* The record flows over onto one or more overflow pages. In @@ -4676,7 +4711,13 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ pPage = pCur->apPage[pCur->iPage]; idx = ++pCur->aiIdx[pCur->iPage]; assert( pPage->isInit ); - assert( idx<=pPage->nCell ); + + /* 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 + ** only happen if the database is corrupt in such a way as to link the + ** page into more than one b-tree structure. */ + testcase( idx>pPage->nCell ); pCur->info.nSize = 0; pCur->validNKey = 0; @@ -5101,7 +5142,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ nFree = get4byte(&pPage1->aData[36]); put4byte(&pPage1->aData[36], nFree+1); - if( pBt->secureDelete ){ + if( pBt->btsFlags & BTS_SECURE_DELETE ){ /* If the secure_delete option is enabled, then ** always fully overwrite deleted information with zeros. */ @@ -5162,7 +5203,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ if( rc==SQLITE_OK ){ put4byte(&pTrunk->aData[4], nLeaf+1); put4byte(&pTrunk->aData[8+nLeaf*4], iPage); - if( pPage && !pBt->secureDelete ){ + if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ sqlite3PagerDontWrite(pPage->pDbPage); } rc = btreeSetHasContent(pBt, iPage); @@ -5454,7 +5495,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); data = pPage->aData; - ptr = &data[pPage->cellOffset + 2*idx]; + ptr = &pPage->aCellIdx[2*idx]; pc = get2byte(ptr); hdr = pPage->hdrOffset; testcase( pc==get2byte(&data[hdr+5]) ); @@ -5468,7 +5509,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ *pRC = rc; return; } - endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; + endPtr = &pPage->aCellIdx[2*pPage->nCell - 2]; assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ while( ptrnCell==0 ); assert( get2byteNotZero(&data[hdr+5])==nUsable ); - pCellptr = &data[pPage->cellOffset + nCell*2]; + pCellptr = &pPage->aCellIdx[nCell*2]; cellbody = nUsable; for(i=nCell-1; i>=0; i--){ u16 sz = aSize[i]; @@ -6003,7 +6044,7 @@ static int balance_nonroot( ** In this case, temporarily copy the cell into the aOvflSpace[] ** buffer. It will be copied out again as soon as the aSpace[] buffer ** is allocated. */ - if( pBt->secureDelete ){ + if( pBt->btsFlags & BTS_SECURE_DELETE ){ int iOff; iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); @@ -6188,8 +6229,14 @@ static int balance_nonroot( /* Either we found one or more cells (cntnew[0])>0) or pPage is ** a virtual root page. A virtual root page is when the real root ** page is page 1 and we are the only child of that page. + ** + ** UPDATE: The assert() below is not necessarily true if the database + ** file is corrupt. The corruption will be detected and reported later + ** in this procedure so there is no need to act upon it now. */ +#if 0 assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); +#endif TRACE(("BALANCE: old: %d %d %d ", apOld[0]->pgno, @@ -6739,7 +6786,8 @@ int sqlite3BtreeInsert( } assert( cursorHoldsMutex(pCur) ); - assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly ); + assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); /* Assert that the caller has been consistent. If this cursor was opened @@ -6868,7 +6916,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); - assert( !pBt->readOnly ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( pCur->wrFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); @@ -6989,7 +7037,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); - assert( !pBt->readOnly ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); #ifdef SQLITE_OMIT_AUTOVACUUM rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); @@ -7363,7 +7411,9 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ /* If auto-vacuum is disabled in this build and this is an auto-vacuum ** database, mark the database as read-only. */ #ifdef SQLITE_OMIT_AUTOVACUUM - if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1; + if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } #endif sqlite3BtreeLeave(p); @@ -8163,7 +8213,8 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ if( !pCsr->wrFlag ){ return SQLITE_READONLY; } - assert( !pCsr->pBt->readOnly && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 + && pCsr->pBt->inTransaction==TRANS_WRITE ); assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); assert( pCsr->apPage[pCsr->iPage]->intKey ); @@ -8203,7 +8254,8 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ /* If setting the version fields to 1, do not automatically open the ** WAL connection, even if the version fields are currently set to 2. */ - pBt->doNotUseWAL = (u8)(iVersion==1); + pBt->btsFlags &= ~BTS_NO_WAL; + if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; rc = sqlite3BtreeBeginTrans(pBtree, 0); if( rc==SQLITE_OK ){ @@ -8220,6 +8272,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ } } - pBt->doNotUseWAL = 0; + pBt->btsFlags &= ~BTS_NO_WAL; return rc; } diff --git a/src/btreeInt.h b/src/btreeInt.h index 55469cf..907c02e 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -277,6 +277,7 @@ struct MemPage { u8 hasData; /* True if this page stores data */ u8 hdrOffset; /* 100 for page 1. 0 otherwise */ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ + u8 max1bytePayload; /* min(maxLocal,127) */ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ @@ -289,6 +290,8 @@ struct MemPage { } aOvfl[5]; BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aCellIdx; /* The cell index area */ DbPage *pDbPage; /* Pager page handle */ Pgno pgno; /* Page number for this page */ }; @@ -368,7 +371,7 @@ struct Btree { /* ** An instance of this object represents a single database file. ** -** A single database file can be in use as the same time by two +** A single database file can be in use at the same time by two ** or more database connections. When two or more connections are ** sharing the same database file, each connection has it own ** private Btree object for the file and each of those Btrees points @@ -405,17 +408,14 @@ struct BtShared { sqlite3 *db; /* Database connection currently using this Btree */ BtCursor *pCursor; /* A list of all open cursors */ MemPage *pPage1; /* First page of the database */ - u8 readOnly; /* True if the underlying file is readonly */ - u8 pageSizeFixed; /* True if the page size can no longer be changed */ - u8 secureDelete; /* True if secure_delete is enabled */ - u8 initiallyEmpty; /* Database is empty at start of transaction */ u8 openFlags; /* Flags to sqlite3BtreeOpen() */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ #endif u8 inTransaction; /* Transaction state */ - u8 doNotUseWAL; /* If true, do not open write-ahead-log file */ + u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ + u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ @@ -433,12 +433,21 @@ struct BtShared { BtShared *pNext; /* Next on a list of sharable BtShared structs */ BtLock *pLock; /* List of locks held on this shared-btree struct */ Btree *pWriter; /* Btree with currently open write transaction */ - u8 isExclusive; /* True if pWriter has an EXCLUSIVE lock on the db */ - u8 isPending; /* If waiting for read-locks to clear */ #endif u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ }; +/* +** Allowed values for BtShared.btsFlags +*/ +#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ +#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ +#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ +#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */ + /* ** An instance of the following structure is used to hold information ** about a cell. The parseCellPtr() function fills in this structure @@ -474,7 +483,7 @@ struct CellInfo { ** The entry is identified by its MemPage and the index in ** MemPage.aCell[] of the entry. ** -** A single database file can shared by two more database connections, +** A single database file can be shared by two more database connections, ** but cursors cannot be shared. Each cursor is associated with a ** particular database connection identified BtCursor.pBtree.db. ** @@ -635,7 +644,7 @@ struct IntegrityCk { }; /* -** Read or write a two- and four-byte big-endian integer values. +** Routines to read or write a two- and four-byte big-endian integer values. */ #define get2byte(x) ((x)[0]<<8 | (x)[1]) #define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) diff --git a/src/build.c b/src/build.c index e23aab6..5798e73 100644 --- a/src/build.c +++ b/src/build.c @@ -2661,19 +2661,23 @@ Index *sqlite3CreateIndex( nName = sqlite3Strlen30(zName); nCol = pList->nExpr; pIndex = sqlite3DbMallocZero(db, - sizeof(Index) + /* Index structure */ - sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */ - sizeof(int)*nCol + /* Index.aiColumn */ - sizeof(char *)*nCol + /* Index.azColl */ - sizeof(u8)*nCol + /* Index.aSortOrder */ - nName + 1 + /* Index.zName */ - nExtra /* Collation sequence names */ + ROUND8(sizeof(Index)) + /* Index structure */ + ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */ + sizeof(char *)*nCol + /* Index.azColl */ + sizeof(int)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol + /* Index.aSortOrder */ + nName + 1 + /* Index.zName */ + nExtra /* Collation sequence names */ ); if( db->mallocFailed ){ goto exit_create_index; } - pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]); - pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]); + zExtra = (char*)pIndex; + pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))]; + pIndex->azColl = (char**) + ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1)); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); diff --git a/src/crypto.c b/src/crypto.c index 5c8b2d6..b91e4e5 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -70,13 +70,20 @@ static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ct sqlite3_mutex_enter(db->mutex); db->nextPagesize = page_sz; - pDb->pBt->pBt->pageSizeFixed = 0; + + /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else + sqliteBtreeSetPageSize will block the change */ + pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz)); rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0); sqlite3_mutex_leave(db->mutex); return rc; } +void codec_set_default_use_hmac(int use) { + sqlcipher_set_default_use_hmac(use); +} + int codec_set_use_hmac(sqlite3* db, int nDb, int use) { struct Db *pDb = &db->aDb[nDb]; @@ -90,8 +97,6 @@ int codec_set_use_hmac(sqlite3* db, int nDb, int use) { rc = sqlcipher_codec_ctx_set_use_hmac(ctx, use); if(rc != SQLITE_OK) return rc; /* since the use of hmac has changed, the page size may also change */ - /* Note: before forcing the page size we need to force pageSizeFixed to 0, else - sqliteBtreeSetPageSize will block the change */ return codec_set_btree_to_codec_pagesize(db, pDb, ctx); } } diff --git a/src/crypto.h b/src/crypto.h index a5a62ec..7a7165b 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -149,6 +149,8 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *); void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **); +void sqlcipher_set_default_use_hmac(int use); + int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use); /* end extensions defined in crypto_impl.c */ diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 336afbd..f0e9dfb 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -79,6 +79,8 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *, cipher_ctx *); /* prototype for pager HMAC function */ int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *); +static int default_use_hmac = DEFAULT_USE_HMAC; + struct codec_ctx { int kdf_salt_sz; int page_sz; @@ -325,7 +327,12 @@ int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int return SQLITE_OK; } +/* set the global default flag for HMAC */ +void sqlcipher_set_default_use_hmac(int use) { + default_use_hmac = use; +} +/* set the codec flag for whether this individual database should be using hmac */ int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) { int reserve = EVP_MAX_IV_LENGTH; /* base reserve size will be IV only */ @@ -432,7 +439,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f /* Use HMAC signatures by default. Note that codec_set_use_hmac will implicity call codec_set_page_size to set the default */ - if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, DEFAULT_USE_HMAC)) != SQLITE_OK) return rc; + if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_use_hmac)) != SQLITE_OK) return rc; if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc; diff --git a/src/delete.c b/src/delete.c index 147a5ca..f666b90 100644 --- a/src/delete.c +++ b/src/delete.c @@ -148,7 +148,6 @@ Expr *sqlite3LimitWhere( */ if( pOrderBy && (pLimit == 0) ) { sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - pParse->parseError = 1; goto limit_where_cleanup_2; } diff --git a/src/expr.c b/src/expr.c index d506173..22643ff 100644 --- a/src/expr.c +++ b/src/expr.c @@ -870,7 +870,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; pItem->done = 0; - pItem->iCol = pOldItem->iCol; + pItem->iOrderByCol = pOldItem->iOrderByCol; pItem->iAlias = pOldItem->iAlias; } return pNew; @@ -940,7 +940,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ return pNew; } Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - Select *pNew; + Select *pNew, *pPrior; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; @@ -951,7 +951,9 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; - pNew->pPrior = sqlite3SelectDup(db, p->pPrior, flags); + pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); pNew->iLimit = 0; @@ -1373,6 +1375,15 @@ static int isCandidateForInOpt(Select *p){ } #endif /* SQLITE_OMIT_SUBQUERY */ +/* +** Code an OP_Once instruction and allocate space for its flag. Return the +** address of the new instruction. +*/ +int sqlite3CodeOnce(Parse *pParse){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); +} + /* ** This function is used by the implementation of the IN (...) operator. ** It's job is to find or create a b-tree structure that may be used @@ -1433,6 +1444,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ int eType = 0; /* Type of RHS table. IN_INDEX_* */ int iTab = pParse->nTab++; /* Cursor of the RHS table */ int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); @@ -1443,7 +1455,6 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ sqlite3 *db = pParse->db; /* Database connection */ - Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ Table *pTab; /* Table . */ Expr *pExpr; /* Expression */ int iCol; /* Index of column */ @@ -1468,10 +1479,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ */ assert(v); if( iCol<0 ){ - int iMem = ++pParse->nMem; int iAddr; - iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); + iAddr = sqlite3CodeOnce(pParse); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; @@ -1497,12 +1507,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ - int iMem = ++pParse->nMem; int iAddr; char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); - iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); + iAddr = sqlite3CodeOnce(pParse); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); @@ -1512,6 +1521,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ sqlite3VdbeJumpHere(v, iAddr); if( prNotFound && !pTab->aCol[iCol].notNull ){ *prNotFound = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); } } } @@ -1527,6 +1537,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ eType = IN_INDEX_EPH; if( prNotFound ){ *prNotFound = rMayHaveNull = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); }else{ testcase( pParse->nQueryLoop>(double)1 ); pParse->nQueryLoop = (double)1; @@ -1599,9 +1610,8 @@ int sqlite3CodeSubselect( ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ - if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ - int mem = ++pParse->nMem; - testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){ + testAddr = sqlite3CodeOnce(pParse); } #ifndef SQLITE_OMIT_EXPLAIN @@ -2939,6 +2949,264 @@ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ return inReg; } +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) +/* +** Generate a human-readable explanation of an expression tree. +*/ +void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ + int op; /* The opcode being coded */ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + if( pExpr==0 ){ + op = TK_NULL; + }else{ + op = pExpr->op; + } + switch( op ){ + case TK_AGG_COLUMN: { + sqlite3ExplainPrintf(pOut, "AGG{%d:%d}", + pExpr->iTable, pExpr->iColumn); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn); + }else{ + sqlite3ExplainPrintf(pOut, "{%d:%d}", + pExpr->iTable, pExpr->iColumn); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue); + }else{ + sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3ExplainPrintf(pOut,"NULL"); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_VARIABLE: { + sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_AS: { + sqlite3ExplainExpr(pOut, pExpr->pLeft); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + const char *zAff = "unk"; + switch( sqlite3AffinityType(pExpr->u.zToken) ){ + case SQLITE_AFF_TEXT: zAff = "TEXT"; break; + case SQLITE_AFF_NONE: zAff = "NONE"; break; + case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break; + case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break; + case SQLITE_AFF_REAL: zAff = "REAL"; break; + } + sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_AGG_FUNCTION: + case TK_CONST_FUNC: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(", + op==TK_AGG_FUNCTION ? "AGG_" : "", + pExpr->u.zToken); + if( pFarg ){ + sqlite3ExplainExprList(pOut, pFarg); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + sqlite3ExplainPrintf(pOut, "EXISTS("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut,")"); + break; + } + case TK_SELECT: { + sqlite3ExplainPrintf(pOut, "("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_IN: { + sqlite3ExplainPrintf(pOut, "IN("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + }else{ + sqlite3ExplainExprList(pOut, pExpr->x.pList); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pX = pExpr->pLeft; + Expr *pY = pExpr->x.pList->a[0].pExpr; + Expr *pZ = pExpr->x.pList->a[1].pExpr; + sqlite3ExplainPrintf(pOut, "BETWEEN("); + sqlite3ExplainExpr(pOut, pX); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pY); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pZ); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3ExplainPrintf(pOut, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3ExplainPrintf(pOut, "CASE("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExprList(pOut, pExpr->x.pList); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affinity ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken); + break; + } +#endif + } + if( zBinOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zBinOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,","); + sqlite3ExplainExpr(pOut, pExpr->pRight); + sqlite3ExplainPrintf(pOut,")"); + }else if( zUniOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zUniOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,")"); + } +} +#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */ + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) +/* +** Generate a human-readable explanation of an expression list. +*/ +void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ + int i; + if( pList==0 || pList->nExpr==0 ){ + sqlite3ExplainPrintf(pOut, "(empty-list)"); + return; + }else if( pList->nExpr==1 ){ + sqlite3ExplainExpr(pOut, pList->a[0].pExpr); + }else{ + sqlite3ExplainPush(pOut); + for(i=0; inExpr; i++){ + sqlite3ExplainPrintf(pOut, "item[%d] = ", i); + sqlite3ExplainPush(pOut); + sqlite3ExplainExpr(pOut, pList->a[i].pExpr); + sqlite3ExplainPop(pOut); + if( inExpr-1 ){ + sqlite3ExplainNL(pOut); + } + } + sqlite3ExplainPop(pOut); + } +} +#endif /* SQLITE_DEBUG */ + /* ** Return TRUE if pExpr is an constant expression that is appropriate ** for factoring out of a loop. Appropriate expressions are: @@ -3762,3 +4030,11 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ pParse->iRangeReg = iReg; } } + +/* +** Mark all temporary registers as being unavailable for reuse. +*/ +void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} diff --git a/src/global.c b/src/global.c index 1e691c4..7de0668 100644 --- a/src/global.c +++ b/src/global.c @@ -147,7 +147,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ - {0,0,0,0,0,0,0,0,0,0,0}, /* pcache */ + {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ (void*)0, /* pHeap */ 0, /* nHeap */ 0, 0, /* mnHeap, mxHeap */ diff --git a/src/insert.c b/src/insert.c index 277a852..6b31e24 100644 --- a/src/insert.c +++ b/src/insert.c @@ -47,7 +47,7 @@ void sqlite3OpenTable( ** 'd' INTEGER ** 'e' REAL ** -** An extra 'b' is appended to the end of the string to cover the +** An extra 'd' is appended to the end of the string to cover the ** rowid that appears as the last column in every index. ** ** Memory for the buffer containing the column index affinity string @@ -75,7 +75,7 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ for(n=0; nnColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; } - pIdx->zColAff[n++] = SQLITE_AFF_NONE; + pIdx->zColAff[n++] = SQLITE_AFF_INTEGER; pIdx->zColAff[n] = 0; } @@ -239,6 +239,7 @@ void sqlite3AutoincrementBegin(Parse *pParse){ memId = p->regCtr; assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); @@ -1106,7 +1107,7 @@ insert_cleanup: ** cause sqlite3_exec() to return immediately ** with SQLITE_CONSTRAINT. ** -** any FAIL Sqlite_exec() returns immediately with a +** any FAIL Sqlite3_exec() returns immediately with a ** return code of SQLITE_CONSTRAINT. The ** transaction is not rolled back and any ** prior changes are retained. @@ -1578,31 +1579,25 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ ** ** INSERT INTO tab1 SELECT * FROM tab2; ** -** This optimization is only attempted if +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassemblied, which greatly improves +** performance. Raw index records are transferred in the same way. ** -** (1) tab1 and tab2 have identical schemas including all the -** same indices and constraints +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. ** -** (2) tab1 and tab2 are different tables +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. ** -** (3) There must be no triggers on tab1 -** -** (4) The result set of the SELECT statement is "*" -** -** (5) The SELECT statement has no WHERE, HAVING, ORDER BY, GROUP BY, -** or LIMIT clause. -** -** (6) The SELECT statement is a simple (not a compound) select that -** contains only tab2 in its FROM clause -** -** This method for implementing the INSERT transfers raw records from -** tab2 over to tab1. The columns are not decoded. Raw records from -** the indices of tab2 are transfered to tab1 as well. In so doing, -** the resulting tab1 has much less fragmentation. -** -** This routine returns TRUE if the optimization is attempted. If any -** of the conditions above fail so that the optimization should not -** be attempted, then this routine returns FALSE. +** This optimization is particularly useful at making VACUUM run faster. */ static int xferOptimization( Parse *pParse, /* Parser context */ @@ -1639,10 +1634,8 @@ static int xferOptimization( } #endif if( onError==OE_Default ){ - onError = OE_Abort; - } - if( onError!=OE_Abort && onError!=OE_Rollback ){ - return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; } assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ if( pSelect->pSrc->nSrc!=1 ){ @@ -1748,16 +1741,12 @@ static int xferOptimization( } #endif if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ - return 0; + return 0; /* xfer opt does not play well with PRAGMA count_changes */ } - /* If we get this far, it means either: - ** - ** * We can always do the transfer if the table contains an - ** an integer primary key - ** - ** * We can conditionally do the transfer if the destination - ** table is empty. + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. */ #ifdef SQLITE_TEST sqlite3_xferopt_count++; @@ -1769,16 +1758,23 @@ static int xferOptimization( iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - if( (pDest->iPKey<0 && pDest->pIndex!=0) || destHasUniqueIdx ){ - /* If tables do not have an INTEGER PRIMARY KEY and there - ** are indices to be copied and the destination is not empty, - ** we have to disallow the transfer optimization because the - ** the rowids might change which will mess up indexing. + if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + ){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. This code makes + ** that determination. Conditions under which the destination must + ** be empty: ** - ** Or if the destination has a UNIQUE index and is not empty, - ** we also disallow the transfer optimization because we cannot - ** insure that all entries in the union of DEST and SRC will be - ** unique. + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. */ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); diff --git a/src/loadext.c b/src/loadext.c index e9c97ad..3fcf500 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -625,6 +625,7 @@ void sqlite3_reset_auto_extension(void){ void sqlite3AutoLoadExtensions(sqlite3 *db){ int i; int go = 1; + int rc; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); wsdAutoextInit; @@ -647,8 +648,8 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ } sqlite3_mutex_leave(mutex); zErrmsg = 0; - if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ - sqlite3Error(db, SQLITE_ERROR, + if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ + sqlite3Error(db, rc, "automatic extension loading failed: %s", zErrmsg); go = 0; } diff --git a/src/main.c b/src/main.c index 42bbba5..524b710 100644 --- a/src/main.c +++ b/src/main.c @@ -49,8 +49,8 @@ const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } -/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns -** zero if and only if SQLite was compiled mutexing code omitted due to +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled with mutexing code omitted due to ** the SQLITE_THREADSAFE compile-time option being set to 0. */ int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } @@ -239,8 +239,8 @@ int sqlite3_initialize(void){ */ #ifdef SQLITE_EXTRA_INIT if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){ - int SQLITE_EXTRA_INIT(void); - rc = SQLITE_EXTRA_INIT(); + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); } #endif @@ -257,6 +257,10 @@ int sqlite3_initialize(void){ */ int sqlite3_shutdown(void){ if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif sqlite3_os_end(); sqlite3_reset_auto_extension(); sqlite3GlobalConfig.isInit = 0; @@ -365,16 +369,25 @@ int sqlite3_config(int op, ...){ } case SQLITE_CONFIG_PCACHE: { - /* Specify an alternative page cache implementation */ - sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*); + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; break; } - case SQLITE_CONFIG_GETPCACHE: { - if( sqlite3GlobalConfig.pcache.xInit==0 ){ + case SQLITE_CONFIG_PCACHE2: { + /* Specify an alternative page cache implementation */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ sqlite3PCacheSetDefault(); } - *va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache; + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; break; } @@ -473,21 +486,21 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ if( db->lookaside.bMalloced ){ sqlite3_free(db->lookaside.pStart); } - /* The size of a lookaside slot needs to be larger than a pointer - ** to be useful. + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer to be useful. */ + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; if( cnt<0 ) cnt = 0; if( sz==0 || cnt==0 ){ sz = 0; pStart = 0; }else if( pBuf==0 ){ - sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ sqlite3BeginBenignMalloc(); pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); + if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; }else{ - sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ pStart = pBuf; } db->lookaside.pStart = pStart; @@ -521,6 +534,26 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ return db->mutex; } +/* +** Free up as much memory as we can from the given database +** connection. +*/ +int sqlite3_db_release_memory(sqlite3 *db){ + int i; + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + /* ** Configuration settings for an individual database connection */ @@ -1628,7 +1661,6 @@ static int createCollation( sqlite3* db, const char *zName, u8 enc, - u8 collType, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -1693,7 +1725,6 @@ static int createCollation( pColl->pUser = pCtx; pColl->xDel = xDel; pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); - pColl->type = collType; sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK; } @@ -2154,14 +2185,10 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1, - binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } @@ -2169,8 +2196,7 @@ static int openDatabase( assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ - createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, - nocaseCollatingFunc, 0); + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); /* Parse the filename/URI argument. */ db->openFlags = flags; @@ -2219,10 +2245,13 @@ static int openDatabase( /* Load automatic extensions - extensions that have been registered ** using the sqlite3_automatic_extension() API. */ - sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); - if( rc!=SQLITE_OK ){ - goto opendb_out; + if( rc==SQLITE_OK ){ + sqlite3AutoLoadExtensions(db); + rc = sqlite3_errcode(db); + if( rc!=SQLITE_OK ){ + goto opendb_out; + } } #ifdef SQLITE_ENABLE_FTS1 @@ -2363,7 +2392,7 @@ int sqlite3_create_collation( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -2383,7 +2412,7 @@ int sqlite3_create_collation_v2( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -2406,7 +2435,7 @@ int sqlite3_create_collation16( assert( !db->mallocFailed ); zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); if( zName8 ){ - rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); sqlite3DbFree(db, zName8); } rc = sqlite3ApiExit(db, rc); @@ -2889,15 +2918,6 @@ int sqlite3_test_control(int op, ...){ } #endif - /* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ) - ** - ** Return the size of a pcache header in bytes. - */ - case SQLITE_TESTCTRL_PGHDRSZ: { - rc = sizeof(PgHdr); - break; - } - /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); ** ** Pass pFree into sqlite3ScratchFree(). @@ -2925,6 +2945,22 @@ int sqlite3_test_control(int op, ...){ break; } +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) + /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, + ** sqlite3_stmt*,const char**); + ** + ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds + ** a string that describes the optimized parse tree. This test-control + ** returns a pointer to that string. + */ + case SQLITE_TESTCTRL_EXPLAIN_STMT: { + sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*); + const char **pzRet = va_arg(ap, const char**); + *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt); + break; + } +#endif + } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ @@ -2943,6 +2979,7 @@ int sqlite3_test_control(int op, ...){ ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); @@ -2952,3 +2989,41 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ } return 0; } + +/* +** Return a boolean value for a query parameter. +*/ +int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + return z ? sqlite3GetBoolean(z) : (bDflt!=0); +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +sqlite3_int64 sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ + bDflt = v; + } + return bDflt; +} + +/* +** Return the filename of the database associated with a database +** connection. +*/ +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + int i; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt && sqlite3StrICmp(zDbName, db->aDb[i].zName)==0 ){ + return sqlite3BtreeGetFilename(db->aDb[i].pBt); + } + } + return 0; +} diff --git a/src/malloc.c b/src/malloc.c index 3e38d1d..29c6b0d 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -130,7 +130,8 @@ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_int64 priorLimit; sqlite3_int64 excess; #ifndef SQLITE_OMIT_AUTOINIT - sqlite3_initialize(); + int rc = sqlite3_initialize(); + if( rc ) return -1; #endif sqlite3_mutex_enter(mem0.mutex); priorLimit = mem0.alarmThreshold; diff --git a/src/mem1.c b/src/mem1.c index 61fbf4b..bf84ce0 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -26,6 +26,47 @@ */ #ifdef SQLITE_SYSTEM_MALLOC +/* +** Windows systems have malloc_usable_size() but it is called _msize() +*/ +#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN +# define HAVE_MALLOC_USABLE_SIZE 1 +# define malloc_usable_size _msize +#endif + +#if defined(__APPLE__) + +/* +** Use the zone allocator available on apple products +*/ +#include +#include +#include +static malloc_zone_t* _sqliteZone_; +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) +#define SQLITE_MALLOCSIZE(x) \ + (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) + +#else /* if not __APPLE__ */ + +/* +** Use standard C library malloc and free on non-Apple systems. +*/ +#define SQLITE_MALLOC(x) malloc(x) +#define SQLITE_FREE(x) free(x) +#define SQLITE_REALLOC(x,y) realloc((x),(y)) + +#ifdef HAVE_MALLOC_USABLE_SIZE +#include +#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +#else +#undef SQLITE_MALLOCSIZE +#endif + +#endif /* __APPLE__ or not __APPLE__ */ + /* ** Like malloc(), but remember the size of the allocation ** so that we can find it later using sqlite3MemSize(). @@ -35,10 +76,18 @@ ** routines. */ static void *sqlite3MemMalloc(int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_MALLOC( nByte ); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return p; +#else sqlite3_int64 *p; assert( nByte>0 ); nByte = ROUND8(nByte); - p = malloc( nByte+8 ); + p = SQLITE_MALLOC( nByte+8 ); if( p ){ p[0] = nByte; p++; @@ -47,6 +96,7 @@ static void *sqlite3MemMalloc(int nByte){ sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); } return (void *)p; +#endif } /* @@ -58,10 +108,14 @@ static void *sqlite3MemMalloc(int nByte){ ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + SQLITE_FREE(pPrior); +#else sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 ); p--; - free(p); + SQLITE_FREE(p); +#endif } /* @@ -69,11 +123,15 @@ static void sqlite3MemFree(void *pPrior){ ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0; +#else sqlite3_int64 *p; if( pPrior==0 ) return 0; p = (sqlite3_int64*)pPrior; p--; return (int)p[0]; +#endif } /* @@ -87,11 +145,21 @@ static int sqlite3MemSize(void *pPrior){ ** routines and redirected to xFree. */ static void *sqlite3MemRealloc(void *pPrior, int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_REALLOC(pPrior, nByte); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + SQLITE_MALLOCSIZE(pPrior), nByte); + } + return p; +#else sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 && nByte>0 ); assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ p--; - p = realloc(p, nByte+8 ); + p = SQLITE_REALLOC(p, nByte+8 ); if( p ){ p[0] = nByte; p++; @@ -102,6 +170,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){ sqlite3MemSize(pPrior), nByte); } return (void*)p; +#endif } /* @@ -115,6 +184,34 @@ static int sqlite3MemRoundup(int n){ ** Initialize this module. */ static int sqlite3MemInit(void *NotUsed){ +#if defined(__APPLE__) + int cpuCount; + size_t len; + if( _sqliteZone_ ){ + return SQLITE_OK; + } + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + bool success; + malloc_zone_t* newzone = malloc_create_zone(4096, 0); + malloc_set_zone_name(newzone, "Sqlite_Heap"); + do{ + success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, + (void * volatile *)&_sqliteZone_); + }while(!_sqliteZone_); + if( !success ){ + /* somebody registered a zone first */ + malloc_destroy_zone(newzone); + } + } +#endif UNUSED_PARAMETER(NotUsed); return SQLITE_OK; } diff --git a/src/mutex.c b/src/mutex.c index 869a4ae..b567e7c 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -150,4 +150,4 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){ } #endif -#endif /* SQLITE_MUTEX_OMIT */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/src/mutex_noop.c b/src/mutex_noop.c index c5fd520..456e82a 100644 --- a/src/mutex_noop.c +++ b/src/mutex_noop.c @@ -202,5 +202,5 @@ sqlite3_mutex_methods const *sqlite3NoopMutex(void){ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ return sqlite3NoopMutex(); } -#endif /* SQLITE_MUTEX_NOOP */ -#endif /* SQLITE_MUTEX_OMIT */ +#endif /* defined(SQLITE_MUTEX_NOOP) */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/src/mutex_unix.c b/src/mutex_unix.c index aa9a8cf..eca7295 100644 --- a/src/mutex_unix.c +++ b/src/mutex_unix.c @@ -348,4 +348,4 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ return &sMutex; } -#endif /* SQLITE_MUTEX_PTHREAD */ +#endif /* SQLITE_MUTEX_PTHREADS */ diff --git a/src/os.c b/src/os.c index 0b13c86..b5e918a 100644 --- a/src/os.c +++ b/src/os.c @@ -27,11 +27,18 @@ ** The following functions are instrumented for malloc() failure ** testing: ** -** sqlite3OsOpen() ** sqlite3OsRead() ** sqlite3OsWrite() ** sqlite3OsSync() +** sqlite3OsFileSize() ** sqlite3OsLock() +** sqlite3OsCheckReservedLock() +** sqlite3OsFileControl() +** sqlite3OsShmMap() +** sqlite3OsOpen() +** sqlite3OsDelete() +** sqlite3OsAccess() +** sqlite3OsFullPathname() ** */ #if defined(SQLITE_TEST) @@ -90,9 +97,23 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ DO_OS_MALLOC_TEST(id); return id->pMethods->xCheckReservedLock(id, pResOut); } + +/* +** Use sqlite3OsFileControl() when we are doing something that might fail +** and we need to know about the failures. Use sqlite3OsFileControlHint() +** when simply tossing information over the wall to the VFS and we do not +** really care if the VFS receives and understands the information since it +** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() +** routine has no return value since the return value would be meaningless. +*/ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ + DO_OS_MALLOC_TEST(id); return id->pMethods->xFileControl(id, op, pArg); } +void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ + (void)id->pMethods->xFileControl(id, op, pArg); +} + int sqlite3OsSectorSize(sqlite3_file *id){ int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); @@ -116,6 +137,7 @@ int sqlite3OsShmMap( int bExtend, /* True to extend file if necessary */ void volatile **pp /* OUT: Pointer to mapping */ ){ + DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } @@ -132,7 +154,7 @@ int sqlite3OsOpen( ){ int rc; DO_OS_MALLOC_TEST(0); - /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed + /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ @@ -141,6 +163,8 @@ int sqlite3OsOpen( return rc; } int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + DO_OS_MALLOC_TEST(0); + assert( dirSync==0 || dirSync==1 ); return pVfs->xDelete(pVfs, zPath, dirSync); } int sqlite3OsAccess( @@ -158,6 +182,7 @@ int sqlite3OsFullPathname( int nPathOut, char *zPathOut ){ + DO_OS_MALLOC_TEST(0); zPathOut[0] = 0; return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } diff --git a/src/os.h b/src/os.h index 7f17c20..08cd178 100644 --- a/src/os.h +++ b/src/os.h @@ -65,17 +65,6 @@ # endif #endif -/* -** Determine if we are dealing with WindowsCE - which has a much -** reduced API. -*/ -#if defined(_WIN32_WCE) -# define SQLITE_OS_WINCE 1 -#else -# define SQLITE_OS_WINCE 0 -#endif - - /* ** Define the maximum size of a temporary filename */ @@ -100,6 +89,25 @@ # define SQLITE_TEMPNAME_SIZE 200 #endif +/* +** Determine if we are dealing with Windows NT. +*/ +#if defined(_WIN32_WINNT) +# define SQLITE_OS_WINNT 1 +#else +# define SQLITE_OS_WINNT 0 +#endif + +/* +** Determine if we are dealing with WindowsCE - which has a much +** reduced API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ @@ -111,7 +119,7 @@ ** The default size of a disk sector */ #ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 512 +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 #endif /* @@ -244,6 +252,7 @@ int sqlite3OsLock(sqlite3_file*, int); int sqlite3OsUnlock(sqlite3_file*, int); int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); int sqlite3OsFileControl(sqlite3_file*,int,void*); +void sqlite3OsFileControlHint(sqlite3_file*,int,void*); #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 int sqlite3OsSectorSize(sqlite3_file *id); int sqlite3OsDeviceCharacteristics(sqlite3_file *id); @@ -252,6 +261,7 @@ int sqlite3OsShmLock(sqlite3_file *id, int, int, int); void sqlite3OsShmBarrier(sqlite3_file *id); int sqlite3OsShmUnmap(sqlite3_file *id, int); + /* ** Functions for accessing sqlite3_vfs methods */ diff --git a/src/os_unix.c b/src/os_unix.c index 0ea6daf..13faac3 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -123,6 +123,7 @@ #include #endif + #if SQLITE_ENABLE_LOCKING_STYLE # include # if OS_VXWORKS @@ -206,6 +207,7 @@ struct UnixUnusedFd { typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ @@ -223,7 +225,6 @@ struct unixFile { unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS - int isDelete; /* Delete on close if true */ struct vxworksFileId *pId; /* Unique file ID */ #endif #ifndef NDEBUG @@ -257,6 +258,10 @@ struct unixFile { #else # define UNIXFILE_DIRSYNC 0x00 #endif +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +#define UNIXFILE_DELETE 0x20 /* Delete on close */ +#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ +#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ /* ** Include code that is common to all os_*.c files @@ -407,6 +412,12 @@ static struct unix_syscall { { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + }; /* End of the overrideable system calls */ /* @@ -1756,7 +1767,7 @@ static int closeUnixFile(sqlite3_file *id){ } #if OS_VXWORKS if( pFile->pId ){ - if( pFile->isDelete ){ + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ osUnlink(pFile->pId->zCanonicalName); } vxworksReleaseFileId(pFile->pId); @@ -1845,8 +1856,8 @@ static int nolockClose(sqlite3_file *id) { ************************* Begin dot-file Locking ****************************** ** ** The dotfile locking implementation uses the existance of separate lock -** files in order to control access to the database. This works on just -** about every filesystem imaginable. But there are serious downsides: +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: ** ** (1) There is zero concurrency. A single reader blocks all other ** connections from reading or writing the database. @@ -1857,15 +1868,15 @@ static int nolockClose(sqlite3_file *id) { ** Nevertheless, a dotlock is an appropriate locking mode for use if no ** other locking strategy is available. ** -** Dotfile locking works by creating a file in the same directory as the -** database and with the same name but with a ".lock" extension added. -** The existance of a lock file implies an EXCLUSIVE lock. All other lock -** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existance of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. */ /* ** The file suffix added to the data base filename in order to create the -** lock file. +** lock directory. */ #define DOTLOCK_SUFFIX ".lock" @@ -1932,7 +1943,6 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { */ static int dotlockLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; - int fd; char *zLockFile = (char *)pFile->lockingContext; int rc = SQLITE_OK; @@ -1952,9 +1962,9 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } /* grab an exclusive lock */ - fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); - if( fd<0 ){ - /* failed to open/create the file, someone else may have stolen the lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ int tErrno = errno; if( EEXIST == tErrno ){ rc = SQLITE_BUSY; @@ -1966,7 +1976,6 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } return rc; } - robust_close(pFile, fd, __LINE__); /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; @@ -1985,6 +1994,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { static int dotlockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; + int rc; assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, @@ -2006,9 +2016,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); - if( osUnlink(zLockFile) ){ - int rc = 0; + rc = osRmdir(zLockFile); + if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); + if( rc<0 ){ int tErrno = errno; + rc = 0; if( ENOENT != tErrno ){ rc = SQLITE_IOERR_UNLOCK; } @@ -2944,35 +2956,48 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){ */ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ int got; + int prior = 0; #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) i64 newOffset; #endif TIMER_START; + do{ #if defined(USE_PREAD) - do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); - SimulateIOError( got = -1 ); + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) - do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR); - SimulateIOError( got = -1 ); + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); #else - newOffset = lseek(id->h, offset, SEEK_SET); - SimulateIOError( newOffset-- ); - if( newOffset!=offset ){ - if( newOffset == -1 ){ - ((unixFile*)id)->lastErrno = errno; - }else{ - ((unixFile*)id)->lastErrno = 0; + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + ((unixFile*)id)->lastErrno = errno; + }else{ + ((unixFile*)id)->lastErrno = 0; + } + return -1; } - return -1; - } - do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); + got = osRead(id->h, pBuf, cnt); #endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + ((unixFile*)id)->lastErrno = errno; + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); TIMER_END; - if( got<0 ){ - ((unixFile*)id)->lastErrno = errno; - } - OSTRACE(("READ %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED)); - return got; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; } /* @@ -3477,6 +3502,22 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ return SQLITE_OK; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Information and control of an open file handle. */ @@ -3503,14 +3544,15 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return rc; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0; - }else if( bPersist==0 ){ - pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL; - }else{ - pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL; - } + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } #ifndef NDEBUG @@ -3530,9 +3572,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ - case SQLITE_FCNTL_SYNC_OMITTED: { - return SQLITE_OK; /* A no-op */ - } } return SQLITE_NOTFOUND; } @@ -3547,17 +3586,31 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int unixSectorSize(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); +static int unixSectorSize(sqlite3_file *pFile){ + (void)pFile; return SQLITE_DEFAULT_SECTOR_SIZE; } /* -** Return the device characteristics for the file. This is always 0 for unix. +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is contraversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. */ -static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return 0; +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *p = (unixFile*)id; + if( p->ctrlFlags & UNIXFILE_PSOW ){ + return SQLITE_IOCAP_POWERSAFE_OVERWRITE; + }else{ + return 0; + } } #ifndef SQLITE_OMIT_WAL @@ -3812,16 +3865,16 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } #ifdef SQLITE_SHM_DIRECTORY - nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30; + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; #else - nShmFilename = 5 + (int)strlen(pDbFd->zPath); + nShmFilename = 6 + (int)strlen(pDbFd->zPath); #endif pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); if( pShmNode==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } - memset(pShmNode, 0, sizeof(*pShmNode)); + memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; #ifdef SQLITE_SHM_DIRECTORY sqlite3_snprintf(nShmFilename, zShmFilename, @@ -3841,10 +3894,8 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } if( pInode->bProcessLock==0 ){ - const char *zRO; int openFlags = O_RDWR | O_CREAT; - zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); - if( zRO && sqlite3GetBoolean(zRO) ){ + if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ openFlags = O_RDONLY; pShmNode->isReadonly = 1; } @@ -4506,12 +4557,9 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); static int fillInUnixFile( sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ - int syncDir, /* True to sync directory on first sync */ sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename, /* Name of the file being opened */ - int noLock, /* Omit locking if true */ - int isDelete, /* Delete on close if true */ - int isReadOnly /* True if the file is opened read-only */ + int ctrlFlags /* Zero or more UNIXFILE_* values */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; @@ -4519,11 +4567,6 @@ static int fillInUnixFile( assert( pNew->pInode==NULL ); - /* Parameter isDelete is only used on vxworks. Express this explicitly - ** here to prevent compiler warnings about unused parameters. - */ - UNUSED_PARAMETER(isDelete); - /* Usually the path zFilename should not be a relative pathname. The ** exception is when opening the proxy "conch" file in builds that ** include the special Apple locking styles. @@ -4536,32 +4579,30 @@ static int fillInUnixFile( #endif /* No locking occurs in temporary files */ - assert( zFilename!=0 || noLock ); + assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; + pNew->pVfs = pVfs; pNew->zPath = zFilename; + pNew->ctrlFlags = (u8)ctrlFlags; + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; + } if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ - pNew->ctrlFlags = UNIXFILE_EXCL; - }else{ - pNew->ctrlFlags = 0; - } - if( isReadOnly ){ - pNew->ctrlFlags |= UNIXFILE_RDONLY; - } - if( syncDir ){ - pNew->ctrlFlags |= UNIXFILE_DIRSYNC; + pNew->ctrlFlags |= UNIXFILE_EXCL; } #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); if( pNew->pId==0 ){ - noLock = 1; + ctrlFlags |= UNIXFILE_NOLOCK; rc = SQLITE_NOMEM; } #endif - if( noLock ){ + if( ctrlFlags & UNIXFILE_NOLOCK ){ pLockingStyle = &nolockIoMethods; }else{ pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); @@ -4682,7 +4723,7 @@ static int fillInUnixFile( osUnlink(zFilename); isDelete = 0; } - pNew->isDelete = isDelete; + if( isDelete ) pNew->ctrlFlags |= UNIXFILE_DELETE; #endif if( rc!=SQLITE_OK ){ if( h>=0 ) robust_close(pNew, h, __LINE__); @@ -4747,18 +4788,19 @@ static int unixGetTempname(int nBuf, char *zBuf){ /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ - if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){ + if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){ return SQLITE_ERROR; } do{ - sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); + sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = (int)strlen(zBuf); sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; + zBuf[j+1] = 0; }while( osAccess(zBuf,0)==0 ); return SQLITE_OK; } @@ -4879,7 +4921,7 @@ static int findCreateFileMode( */ nDb = sqlite3Strlen30(zPath) - 1; #ifdef SQLITE_ENABLE_8_3_NAMES - while( nDb>0 && !sqlite3Isalnum(zPath[nDb]) ) nDb--; + while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; #else while( zPath[nDb]!='-' ){ @@ -4937,6 +4979,7 @@ static int unixOpen( int eType = flags&0xFFFFFF00; /* Type of file to open */ int noLock; /* True to omit locking primitives */ int rc = SQLITE_OK; /* Function Return Code */ + int ctrlFlags = 0; /* UNIXFILE_* flags */ int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); @@ -4963,7 +5006,7 @@ static int unixOpen( /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ - char zTmpname[MAX_PATHNAME+1]; + char zTmpname[MAX_PATHNAME+2]; const char *zName = zPath; /* Check the following statements are true: @@ -5006,14 +5049,24 @@ static int unixOpen( } } p->pUnused = pUnused; + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). */ + assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); + }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ assert(isDelete && !syncDir); - rc = unixGetTempname(MAX_PATHNAME+1, zTmpname); + rc = unixGetTempname(MAX_PATHNAME+2, zTmpname); if( rc!=SQLITE_OK ){ return rc; } zName = zTmpname; + + /* Generated temporary filenames are always double-zero terminated + ** for use by sqlite3_uri_parameter(). */ + assert( zName[strlen(zName)+1]==0 ); } /* Determine the value of the flags parameter passed to POSIX function @@ -5090,7 +5143,14 @@ static int unixOpen( ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; } #endif - + + /* Set up appropriate ctrlFlags */ + if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; + if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; + if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; + #if SQLITE_ENABLE_LOCKING_STYLE #if SQLITE_PREFER_PROXY_LOCKING isAutoProxy = 1; @@ -5120,8 +5180,7 @@ static int unixOpen( useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ - rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, - isDelete, isReadonly); + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); if( rc==SQLITE_OK ){ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); if( rc!=SQLITE_OK ){ @@ -5138,8 +5197,8 @@ static int unixOpen( } #endif - rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, - isDelete, isReadonly); + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); @@ -5164,7 +5223,7 @@ static int unixDelete( return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); } #ifndef SQLITE_DISABLE_DIRSYNC - if( dirSync ){ + if( (dirSync & 1)!=0 ){ int fd; rc = osOpenDirectory(zPath, &fd); if( rc==SQLITE_OK ){ @@ -5715,7 +5774,7 @@ static int proxyCreateLockPath(const char *lockPath){ if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ buf[i]='\0'; - if( mkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ int err=errno; if( err!=EEXIST ) { OSTRACE(("CREATELOCKPATH FAILED creating %s, " @@ -5810,7 +5869,7 @@ static int proxyCreateUnixFile( pUnused->flags = openFlags; pNew->pUnused = pUnused; - rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0); + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; @@ -6751,7 +6810,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==18 ); + assert( ArraySize(aSyscall)==20 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ diff --git a/src/os_win.c b/src/os_win.c index 4518030..8b86c7e 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -10,72 +10,27 @@ ** ****************************************************************************** ** -** This file contains code that is specific to windows. +** This file contains code that is specific to Windows. */ #include "sqliteInt.h" -#if SQLITE_OS_WIN /* This file is used for windows only */ - - -/* -** A Note About Memory Allocation: -** -** This driver uses malloc()/free() directly rather than going through -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers -** are designed for use on embedded systems where memory is scarce and -** malloc failures happen frequently. Win32 does not typically run on -** embedded systems, and when it does the developers normally have bigger -** problems to worry about than running out of memory. So there is not -** a compelling need to use the wrappers. -** -** But there is a good reason to not use the wrappers. If we use the -** wrappers then we will get simulated malloc() failures within this -** driver. And that causes all kinds of problems for our tests. We -** could enhance SQLite to deal with simulated malloc failures within -** the OS driver, but the code to deal with those failure would not -** be exercised on Linux (which does not need to malloc() in the driver) -** and so we would have difficulty writing coverage tests for that -** code. Better to leave the code out, we think. -** -** The point of this discussion is as follows: When creating a new -** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on windows -** desktops but not so well in embedded systems. -*/ - -#include +#if SQLITE_OS_WIN /* This file is used for Windows only */ #ifdef __CYGWIN__ # include #endif -/* -** Macros used to determine whether or not to use threads. -*/ -#if defined(THREADSAFE) && THREADSAFE -# define SQLITE_W32_THREADS 1 -#endif - /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* -** Some microsoft compilers lack this definition. +** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif -/* -** Determine if we are dealing with WindowsCE - which has a much -** reduced API. -*/ -#if SQLITE_OS_WINCE -# define AreFileApisANSI() 1 -# define FormatMessageW(a,b,c,d,e,f,g) 0 -#endif - /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ @@ -104,14 +59,13 @@ struct winFile { HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ - u8 bPersistWal; /* True to persist WAL files */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ - DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ #if SQLITE_OS_WINCE - WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ + LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hShared; /* Shared memory segment used for locking */ winceLock local; /* Locks obtained by this instance of winFile */ @@ -119,6 +73,12 @@ struct winFile { #endif }; +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ + /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. @@ -190,21 +150,13 @@ static void winMemShutdown(void *pAppData); const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ -/* -** Forward prototypes. -*/ -static int getSectorSize( - sqlite3_vfs *pVfs, - const char *zRelative /* UTF-8 file name */ -); - /* ** The following variable is (normally) set once and never changes -** thereafter. It records whether the operating system is Win95 +** thereafter. It records whether the operating system is Win9x ** or WinNT. ** ** 0: Operating system unknown. -** 1: Operating system is Win95. +** 1: Operating system is Win9x. ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture @@ -216,6 +168,536 @@ int sqlite3_os_type = 0; static int sqlite3_os_type = 0; #endif +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +#if !SQLITE_OS_WINCE +# define SQLITE_WIN32_HAS_ANSI +#endif + +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT +# define SQLITE_WIN32_HAS_WIDE +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +#if SQLITE_OS_WINCE +/* +** These macros are necessary because Windows CE does not natively support the +** Win32 APIs LockFile, UnlockFile, and LockFileEx. + */ + +# define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) +# define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) +# define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) + +/* +** These are the special syscall hacks for Windows CE. The locking related +** defines here refer to the macros defined just above. + */ + +# define osAreFileApisANSI() 1 +# define osLockFile LockFile +# define osUnlockFile UnlockFile +# define osLockFileEx LockFileEx +#endif + +static struct win_syscall { + const char *zName; /* Name of the sytem call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, + +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + + { "CreateFileMapping", (SYSCALL)CreateFileMapping, 0 }, + +#define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, + +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, + +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[35].pCurrent) + + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[36].pCurrent) + + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[39].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[40].pCurrent) + + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) + + { "LocalFree", (SYSCALL)LocalFree, 0 }, + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) + +#if !SQLITE_OS_WINCE + { "LockFile", (SYSCALL)LockFile, 0 }, + +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[45].pCurrent) +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, + +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[46].pCurrent) +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[47].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[48].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[49].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[50].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) + + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[52].pCurrent) + + { "Sleep", (SYSCALL)Sleep, 0 }, + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ + LPFILETIME))aSyscall[54].pCurrent) + +#if !SQLITE_OS_WINCE + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, + +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[55].pCurrent) +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[56].pCurrent) +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[58].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[59].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=0 ); - p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); if( !p ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p", - nBytes, GetLastError(), (void*)hHeap); + nBytes, osGetLastError(), (void*)hHeap); } return p; } @@ -276,12 +758,12 @@ static void winMemFree(void *pPrior){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ - if( !HeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", - pPrior, GetLastError(), (void*)hHeap); + pPrior, osGetLastError(), (void*)hHeap); } } @@ -297,18 +779,18 @@ static void *winMemRealloc(void *pPrior, int nBytes){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif assert( nBytes>=0 ); if( !pPrior ){ - p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); }else{ - p = HeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); } if( !p ){ sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p", - pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(), - (void*)hHeap); + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); } return p; } @@ -325,13 +807,13 @@ static int winMemSize(void *p){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif if( !p ) return 0; - n = HeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); if( n==(SIZE_T)-1 ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p", - p, GetLastError(), (void*)hHeap); + p, osGetLastError(), (void*)hHeap); return 0; } return (int)n; @@ -353,14 +835,14 @@ static int winMemInit(void *pAppData){ if( !pWinMemData ) return SQLITE_ERROR; assert( pWinMemData->magic==WINMEM_MAGIC ); if( !pWinMemData->hHeap ){ - pWinMemData->hHeap = HeapCreate(SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); if( !pWinMemData->hHeap ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u", - GetLastError(), SQLITE_WIN32_HEAP_FLAGS, SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); return SQLITE_NOMEM; } pWinMemData->bOwned = TRUE; @@ -368,7 +850,7 @@ static int winMemInit(void *pAppData){ assert( pWinMemData->hHeap!=0 ); assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif return SQLITE_OK; } @@ -383,12 +865,12 @@ static void winMemShutdown(void *pAppData){ if( pWinMemData->hHeap ){ assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif if( pWinMemData->bOwned ){ - if( !HeapDestroy(pWinMemData->hHeap) ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", - GetLastError(), (void*)pWinMemData->hHeap); + osGetLastError(), (void*)pWinMemData->hHeap); } pWinMemData->bOwned = FALSE; } @@ -424,95 +906,110 @@ void sqlite3MemSetDefault(void){ #endif /* SQLITE_WIN32_MALLOC */ /* -** Convert a UTF-8 string to microsoft unicode (UTF-16?). +** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). ** ** Space to hold the returned string is obtained from malloc. */ -static WCHAR *utf8ToUnicode(const char *zFilename){ +static LPWSTR utf8ToUnicode(const char *zFilename){ int nChar; - WCHAR *zWideFilename; + LPWSTR zWideFilename; - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); - zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar); if( nChar==0 ){ - free(zWideFilename); + sqlite3_free(zWideFilename); zWideFilename = 0; } return zWideFilename; } /* -** Convert microsoft unicode to UTF-8. Space to hold the returned string is -** obtained from malloc(). +** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is +** obtained from sqlite3_malloc(). */ -static char *unicodeToUtf8(const WCHAR *zWideFilename){ +static char *unicodeToUtf8(LPCWSTR zWideFilename){ int nByte; char *zFilename; - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); if( nByte == 0 ){ - free(zFilename); + sqlite3_free(zFilename); zFilename = 0; } return zFilename; } /* -** Convert an ansi string to microsoft unicode, based on the +** Convert an ANSI string to Microsoft Unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained -** from malloc. +** from sqlite3_malloc. */ -static WCHAR *mbcsToUnicode(const char *zFilename){ +static LPWSTR mbcsToUnicode(const char *zFilename){ int nByte; - WCHAR *zMbcsFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + LPWSTR zMbcsFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); - zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + 0)*sizeof(WCHAR); + if( nByte==0 ){ + return 0; + } + zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte); if( nByte==0 ){ - free(zMbcsFilename); + sqlite3_free(zMbcsFilename); zMbcsFilename = 0; } return zMbcsFilename; } /* -** Convert microsoft unicode to multibyte character string, based on the -** user's Ansi codepage. +** Convert Microsoft Unicode to multi-byte character string, based on the +** user's ANSI codepage. ** ** Space to hold the returned string is obtained from -** malloc(). +** sqlite3_malloc(). */ -static char *unicodeToMbcs(const WCHAR *zWideFilename){ +static char *unicodeToMbcs(LPCWSTR zWideFilename){ int nByte; char *zFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte, 0, 0); if( nByte == 0 ){ - free(zFilename); + sqlite3_free(zFilename); zFilename = 0; } return zFilename; @@ -520,35 +1017,35 @@ static char *unicodeToMbcs(const WCHAR *zWideFilename){ /* ** Convert multibyte character string to UTF-8. Space to hold the -** returned string is obtained from malloc(). +** returned string is obtained from sqlite3_malloc(). */ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ char *zFilenameUtf8; - WCHAR *zTmpWide; + LPWSTR zTmpWide; zTmpWide = mbcsToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameUtf8 = unicodeToUtf8(zTmpWide); - free(zTmpWide); + sqlite3_free(zTmpWide); return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from malloc(). +** returned string is obtained from sqlite3_malloc(). */ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; - WCHAR *zTmpWide; + LPWSTR zTmpWide; zTmpWide = utf8ToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameMbcs = unicodeToMbcs(zTmpWide); - free(zTmpWide); + sqlite3_free(zTmpWide); return zFilenameMbcs; } @@ -558,59 +1055,66 @@ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ ** is zero if the error message fits in the buffer, or non-zero ** otherwise (if the message was truncated). */ -static int getLastErrorMsg(int nBuf, char *zBuf){ +static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ /* FormatMessage returns 0 on failure. Otherwise it ** returns the number of TCHARs written to the output ** buffer, excluding the terminating null char. */ - DWORD error = GetLastError(); DWORD dwLen = 0; char *zOut = 0; if( isNT() ){ - WCHAR *zTempWide = NULL; - dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - 0, - (LPWSTR) &zTempWide, - 0, - 0); + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); zOut = unicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ - LocalFree(zTempWide); + osLocalFree(zTempWide); } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ char *zTemp = NULL; - dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - 0, - (LPSTR) &zTemp, - 0, - 0); + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ - LocalFree(zTemp); + osLocalFree(zTemp); } #endif } if( 0 == dwLen ){ - sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error); + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); }else{ /* copy a maximum of nBuf chars to output buffer */ sqlite3_snprintf(nBuf, zBuf, "%s", zOut); /* free the UTF8 buffer */ - free(zOut); + sqlite3_free(zOut); } return 0; } @@ -630,26 +1134,26 @@ static int getLastErrorMsg(int nBuf, char *zBuf){ ** The two subsequent arguments should be the name of the OS function that ** failed and the the associated file-system path, if any. */ -#define winLogError(a,b,c) winLogErrorAtLine(a,b,c,__LINE__) +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) static int winLogErrorAtLine( int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ const char *zFunc, /* Name of OS function that failed */ const char *zPath, /* File path associated with error */ int iLine /* Source line number where error occurred */ ){ char zMsg[500]; /* Human readable error text */ int i; /* Loop counter */ - DWORD iErrno = GetLastError(); /* Error code */ zMsg[0] = 0; - getLastErrorMsg(sizeof(zMsg), zMsg); + getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); assert( errcode!=SQLITE_OK ); if( zPath==0 ) zPath = ""; for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} zMsg[i] = 0; sqlite3_log(errcode, "os_win.c:%d: (%d) %s(%s) - %s", - iLine, iErrno, zFunc, zPath, zMsg + iLine, lastErrno, zFunc, zPath, zMsg ); return errcode; @@ -675,19 +1179,24 @@ static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; ** to see if it should be retried. Return TRUE to retry. Return FALSE ** to give up with an error. */ -static int retryIoerr(int *pnRetry){ - DWORD e; +static int retryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); if( *pnRetry>=win32IoerrRetry ){ + if( pError ){ + *pError = e; + } return 0; } - e = GetLastError(); if( e==ERROR_ACCESS_DENIED || e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ - Sleep(win32IoerrRetryDelay*(1+*pnRetry)); + osSleep(win32IoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } + if( pError ){ + *pError = e; + } return 0; } @@ -708,7 +1217,7 @@ static void logIoerr(int nRetry){ ** This section contains code for WinCE only. */ /* -** WindowsCE does not have a localtime() function. So create a +** Windows CE does not have a localtime() function. So create a ** substitute. */ #include @@ -722,8 +1231,8 @@ struct tm *__cdecl localtime(const time_t *t) t64 = (t64 + 11644473600)*10000000; uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); uTm.dwHighDateTime= (DWORD)(t64 >> 32); - FileTimeToLocalFileTime(&uTm,&lTm); - FileTimeToSystemTime(&lTm,&pTm); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&lTm,&pTm); y.tm_year = pTm.wYear - 1900; y.tm_mon = pTm.wMonth - 1; y.tm_wday = pTm.wDayOfWeek; @@ -734,13 +1243,6 @@ struct tm *__cdecl localtime(const time_t *t) return &y; } -/* This will never be called, but defined to make the code compile */ -#define GetTempPathA(a,b) - -#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) -#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) -#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) - #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] /* @@ -762,26 +1264,32 @@ static void winceMutexAcquire(HANDLE h){ ** descriptor pFile */ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ - WCHAR *zTok; - WCHAR *zName = utf8ToUnicode(zFilename); + LPWSTR zTok; + LPWSTR zName; BOOL bInit = TRUE; + zName = utf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return FALSE; + } + /* Initialize the local lockdata */ - ZeroMemory(&pFile->local, sizeof(pFile->local)); + memset(&pFile->local, 0, sizeof(pFile->local)); /* Replace the backslashes from the filename and lowercase it ** to derive a mutex name. */ - zTok = CharLowerW(zName); + zTok = osCharLowerW(zName); for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ - pFile->hMutex = CreateMutexW(NULL, FALSE, zName); + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ - pFile->lastErrno = GetLastError(); - winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename); - free(zName); + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); + sqlite3_free(zName); return FALSE; } @@ -792,28 +1300,29 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ ** case-sensitive, take advantage of that by uppercasing the mutex name ** and using that as the shared filemapping name. */ - CharUpperW(zName); - pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, sizeof(winceLock), - zName); + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ - if (GetLastError() == ERROR_ALREADY_EXISTS){ + if (osGetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } - free(zName); + sqlite3_free(zName); /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ - pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, + pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ - pFile->lastErrno = GetLastError(); - winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename); - CloseHandle(pFile->hShared); + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_ERROR, pFile->lastErrno, + "winceCreateLock2", zFilename); + osCloseHandle(pFile->hShared); pFile->hShared = NULL; } } @@ -821,14 +1330,14 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* If shared memory could not be created, then close the mutex and fail */ if (pFile->hShared == NULL){ winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); + osCloseHandle(pFile->hMutex); pFile->hMutex = NULL; return FALSE; } /* Initialize the shared memory if we're supposed to */ if (bInit) { - ZeroMemory(pFile->shared, sizeof(winceLock)); + memset(pFile->shared, 0, sizeof(winceLock)); } winceMutexRelease(pFile->hMutex); @@ -859,18 +1368,18 @@ static void winceDestroyLock(winFile *pFile){ } /* De-reference and close our copy of the shared memory handle */ - UnmapViewOfFile(pFile->shared); - CloseHandle(pFile->hShared); + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); /* Done with the mutex */ winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); + osCloseHandle(pFile->hMutex); pFile->hMutex = NULL; } } /* -** An implementation of the LockFile() API of windows for wince +** An implementation of the LockFile() API of Windows for CE */ static BOOL winceLockFile( HANDLE *phFile, @@ -934,7 +1443,7 @@ static BOOL winceLockFile( } /* -** An implementation of the UnlockFile API of windows for wince +** An implementation of the UnlockFile API of Windows for CE */ static BOOL winceUnlockFile( HANDLE *phFile, @@ -996,7 +1505,7 @@ static BOOL winceUnlockFile( } /* -** An implementation of the LockFileEx() API of windows for wince +** An implementation of the LockFileEx() API of Windows for CE */ static BOOL winceLockFileEx( HANDLE *phFile, @@ -1029,7 +1538,7 @@ static BOOL winceLockFileEx( ******************************************************************************/ /* -** Some microsoft compilers lack this definition. +** Some Microsoft compilers lack this definition. */ #ifndef INVALID_SET_FILE_POINTER # define INVALID_SET_FILE_POINTER ((DWORD)-1) @@ -1044,6 +1553,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ LONG upperBits; /* Most sig. 32 bits of new offset */ LONG lowerBits; /* Least sig. 32 bits of new offset */ DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ upperBits = (LONG)((iOffset>>32) & 0x7fffffff); lowerBits = (LONG)(iOffset & 0xffffffff); @@ -1055,10 +1565,13 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ ** whether an error has actually occured, it is also necessary to call ** GetLastError(). */ - dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){ - pFile->lastErrno = GetLastError(); - winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath); + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "seekWinFile", pFile->zPath); return 1; } @@ -1069,7 +1582,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ ** Close a file. ** ** It is reported that an attempt to close a handle might sometimes -** fail. This is a very unreasonable result, but windows is notorious +** fail. This is a very unreasonable result, but Windows is notorious ** for being unreasonable so I do not doubt that it might happen. If ** the close fails, we pause for 100 milliseconds and try again. As ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before @@ -1084,28 +1597,29 @@ static int winClose(sqlite3_file *id){ assert( pFile->pShm==0 ); OSTRACE(("CLOSE %d\n", pFile->h)); do{ - rc = CloseHandle(pFile->h); + rc = osCloseHandle(pFile->h); /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ int cnt = 0; while( - DeleteFileW(pFile->zDeleteOnClose)==0 - && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff && cnt++ < WINCE_DELETION_ATTEMPTS ){ - Sleep(100); /* Wait a little before trying again */ + osSleep(100); /* Wait a little before trying again */ } - free(pFile->zDeleteOnClose); + sqlite3_free(pFile->zDeleteOnClose); } #endif OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OpenCounter(-1); return rc ? SQLITE_OK - : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath); + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), + "winClose", pFile->zPath); } /* @@ -1130,10 +1644,12 @@ static int winRead( if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } - while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ - if( retryIoerr(&nRetry) ) continue; - pFile->lastErrno = GetLastError(); - return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + DWORD lastErrno; + if( retryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); } logIoerr(nRetry); if( nRead<(DWORD)amt ){ @@ -1171,10 +1687,11 @@ static int winWrite( u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ while( nRem>0 ){ - if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ - if( retryIoerr(&nRetry) ) continue; + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ + if( retryIoerr(&nRetry, &lastErrno) ) continue; break; } if( nWrite<=0 ) break; @@ -1182,7 +1699,7 @@ static int winWrite( nRem -= nWrite; } if( nRem>0 ){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = lastErrno; rc = 1; } } @@ -1192,7 +1709,8 @@ static int winWrite( || ( pFile->lastErrno==ERROR_DISK_FULL )){ return SQLITE_FULL; } - return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite", pFile->zPath); }else{ logIoerr(nRetry); } @@ -1222,10 +1740,12 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ if( seekWinFile(pFile, nByte) ){ - rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath); - }else if( 0==SetEndOfFile(pFile->h) ){ - pFile->lastErrno = GetLastError(); - rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath); + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); + }else if( 0==osSetEndOfFile(pFile->h) ){ + pFile->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); } OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); @@ -1290,13 +1810,14 @@ static int winSync(sqlite3_file *id, int flags){ #ifdef SQLITE_NO_SYNC return SQLITE_OK; #else - rc = FlushFileBuffers(pFile->h); + rc = osFlushFileBuffers(pFile->h); SimulateIOError( rc=FALSE ); if( rc ){ return SQLITE_OK; }else{ - pFile->lastErrno = GetLastError(); - return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath); + pFile->lastErrno = osGetLastError(); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync", pFile->zPath); } #endif } @@ -1308,16 +1829,17 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ DWORD upperBits; DWORD lowerBits; winFile *pFile = (winFile*)id; - DWORD error; + DWORD lastErrno; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_FSTAT); - lowerBits = GetFileSize(pFile->h, &upperBits); + lowerBits = osGetFileSize(pFile->h, &upperBits); if( (lowerBits == INVALID_FILE_SIZE) - && ((error = GetLastError()) != NO_ERROR) ) + && ((lastErrno = osGetLastError())!=NO_ERROR) ) { - pFile->lastErrno = error; - return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath); + pFile->lastErrno = lastErrno; + return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); } *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; return SQLITE_OK; @@ -1333,7 +1855,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this -** is Win95 or WinNT. +** is Win9x or WinNT. */ static int getReadLock(winFile *pFile){ int res; @@ -1342,8 +1864,8 @@ static int getReadLock(winFile *pFile){ ovlp.Offset = SHARED_FIRST; ovlp.OffsetHigh = 0; ovlp.hEvent = 0; - res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, - 0, SHARED_SIZE, 0, &ovlp); + res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, + 0, SHARED_SIZE, 0, &ovlp); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 @@ -1351,11 +1873,11 @@ static int getReadLock(winFile *pFile){ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); #endif } if( res == 0 ){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); /* No need to log a failure to lock */ } return res; @@ -1366,18 +1888,20 @@ static int getReadLock(winFile *pFile){ */ static int unlockReadLock(winFile *pFile){ int res; + DWORD lastErrno; if( isNT() ){ - res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ - res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); + res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } - if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){ - pFile->lastErrno = GetLastError(); - winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath); + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "unlockReadLock", pFile->zPath); } return res; } @@ -1410,11 +1934,11 @@ static int unlockReadLock(winFile *pFile){ */ static int winLock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ - int res = 1; /* Result of a windows lock call */ + int res = 1; /* Result of a Windows lock call */ int newLocktype; /* Set pFile->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ winFile *pFile = (winFile*)id; - DWORD error = NO_ERROR; + DWORD lastErrno = NO_ERROR; assert( id!=0 ); OSTRACE(("LOCK %d %d was %d(%d)\n", @@ -1444,16 +1968,19 @@ static int winLock(sqlite3_file *id, int locktype){ && (pFile->locktype==RESERVED_LOCK)) ){ int cnt = 3; - while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ - /* Try 3 times to get the pending lock. The pending lock might be - ** held by another reader process who will release it momentarily. + while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for Windows only. */ OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); - Sleep(1); + if( cnt ) osSleep(1); } gotPendingLock = res; if( !res ){ - error = GetLastError(); + lastErrno = osGetLastError(); } } @@ -1465,7 +1992,7 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ newLocktype = SHARED_LOCK; }else{ - error = GetLastError(); + lastErrno = osGetLastError(); } } @@ -1473,11 +2000,11 @@ static int winLock(sqlite3_file *id, int locktype){ */ if( locktype==RESERVED_LOCK && res ){ assert( pFile->locktype==SHARED_LOCK ); - res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( res ){ newLocktype = RESERVED_LOCK; }else{ - error = GetLastError(); + lastErrno = osGetLastError(); } } @@ -1494,12 +2021,12 @@ static int winLock(sqlite3_file *id, int locktype){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); OSTRACE(("unreadlock = %d\n", res)); - res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ - error = GetLastError(); - OSTRACE(("error-code = %d\n", error)); + lastErrno = osGetLastError(); + OSTRACE(("error-code = %d\n", lastErrno)); getReadLock(pFile); } } @@ -1508,7 +2035,7 @@ static int winLock(sqlite3_file *id, int locktype){ ** release it now. */ if( gotPendingLock && locktype==SHARED_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } /* Update the state of the lock has held in the file descriptor then @@ -1519,7 +2046,7 @@ static int winLock(sqlite3_file *id, int locktype){ }else{ OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, locktype, newLocktype)); - pFile->lastErrno = error; + pFile->lastErrno = lastErrno; rc = SQLITE_BUSY; } pFile->locktype = (u8)newLocktype; @@ -1542,9 +2069,9 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ - rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } rc = !rc; OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); @@ -1574,26 +2101,43 @@ static int winUnlock(sqlite3_file *id, int locktype){ pFile->locktype, pFile->sharedLockByte)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ - UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath); + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), + "winUnlock", pFile->zPath); } } if( type>=RESERVED_LOCK ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ unlockReadLock(pFile); } if( type>=PENDING_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = (u8)locktype; return rc; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Control and query of the open file handle. */ @@ -1629,15 +2173,15 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = pFile->bPersistWal; - }else{ - pFile->bPersistWal = bPersist!=0; - } + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } - case SQLITE_FCNTL_SYNC_OMITTED: { + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("win32"); return SQLITE_OK; } case SQLITE_FCNTL_WIN32_AV_RETRY: { @@ -1669,16 +2213,17 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ ** same for both. */ static int winSectorSize(sqlite3_file *id){ - assert( id!=0 ); - return (int)(((winFile*)id)->sectorSize); + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; } /* ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ - UNUSED_PARAMETER(id); - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; + winFile *p = (winFile*)id; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } #ifndef SQLITE_OMIT_WAL @@ -1825,15 +2370,15 @@ static int winShmSystemLock( /* Release/Acquire the system-level lock */ if( lockType==_SHM_UNLCK ){ - rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); + rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); }else{ - rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); + rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); } if( rc!= 0 ){ rc = SQLITE_OK; }else{ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); rc = SQLITE_BUSY; } @@ -1867,13 +2412,13 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ int i; if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; inRegion; i++){ - bRc = UnmapViewOfFile(p->aRegion[i].pMap); + bRc = osUnmapViewOfFile(p->aRegion[i].pMap); OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", - (int)GetCurrentProcessId(), i, + (int)osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); - bRc = CloseHandle(p->aRegion[i].hMap); + bRc = osCloseHandle(p->aRegion[i].hMap); OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", - (int)GetCurrentProcessId(), i, + (int)osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); } if( p->hFile.h != INVALID_HANDLE_VALUE ){ @@ -1883,7 +2428,9 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ } if( deleteFlag ){ SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); winDelete(pVfs, p->zFilename, 0); + sqlite3EndBenignMalloc(); SimulateIOErrorBenign(0); } *pp = p->pNext; @@ -1915,15 +2462,15 @@ static int winOpenSharedMemory(winFile *pDbFd){ ** allocate space for a new winShmNode and filename. */ p = sqlite3_malloc( sizeof(*p) ); - if( p==0 ) return SQLITE_NOMEM; + if( p==0 ) return SQLITE_IOERR_NOMEM; memset(p, 0, sizeof(*p)); nName = sqlite3Strlen30(pDbFd->zPath); - pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 ); + pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 ); if( pNew==0 ){ sqlite3_free(p); - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } - memset(pNew, 0, sizeof(*pNew)); + memset(pNew, 0, sizeof(*pNew) + nName + 17); pNew->zFilename = (char*)&pNew[1]; sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); @@ -1949,7 +2496,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ - rc = SQLITE_NOMEM; + rc = SQLITE_IOERR_NOMEM; goto shm_open_err; } @@ -1959,7 +2506,6 @@ static int winOpenSharedMemory(winFile *pDbFd){ SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */ 0); if( SQLITE_OK!=rc ){ - rc = SQLITE_CANTOPEN_BKPT; goto shm_open_err; } @@ -1969,7 +2515,8 @@ static int winOpenSharedMemory(winFile *pDbFd){ if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winOpenShm", pDbFd->zPath); } } if( rc==SQLITE_OK ){ @@ -2154,7 +2701,7 @@ static int winShmLock( } sqlite3_mutex_leave(pShmNode->mutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", - p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, + p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask, rc ? "failed" : "ok")); return rc; } @@ -2228,7 +2775,8 @@ static int winShmMap( */ rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap1", pDbFd->zPath); goto shmpage_out; } @@ -2242,7 +2790,8 @@ static int winShmMap( if( !isWrite ) goto shmpage_out; rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap2", pDbFd->zPath); goto shmpage_out; } } @@ -2261,26 +2810,27 @@ static int winShmMap( HANDLE hMap; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ - hMap = CreateFileMapping(pShmNode->hFile.h, + hMap = osCreateFileMapping(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", - (int)GetCurrentProcessId(), pShmNode->nRegion, nByte, + (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); if( hMap ){ int iOffset = pShmNode->nRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; - pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, iOffset - iOffsetShift, szRegion + iOffsetShift ); OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", - (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion, - pMap ? "ok" : "failed")); + (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); } if( !pMap ){ - pShmNode->lastErrno = GetLastError(); - rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath); - if( hMap ) CloseHandle(hMap); + pShmNode->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); + if( hMap ) osCloseHandle(hMap); goto shmpage_out; } @@ -2378,7 +2928,7 @@ static int getTempname(int nBuf, char *zBuf){ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; - char zTempPath[MAX_PATH+1]; + char zTempPath[MAX_PATH+2]; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this @@ -2391,29 +2941,29 @@ static int getTempname(int nBuf, char *zBuf){ }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; - GetTempPathW(MAX_PATH-30, zWidePath); + osGetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); - free(zMulti); + sqlite3_free(zMulti); }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ char *zUtf8; char zMbcsPath[MAX_PATH]; - GetTempPathA(MAX_PATH-30, zMbcsPath); + osGetTempPathA(MAX_PATH-30, zMbcsPath); zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); - free(zUtf8); + sqlite3_free(zUtf8); }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } #endif } @@ -2421,14 +2971,14 @@ static int getTempname(int nBuf, char *zBuf){ /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ - if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){ + if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ return SQLITE_ERROR; } for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; - sqlite3_snprintf(nBuf-17, zBuf, + sqlite3_snprintf(nBuf-18, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); j = sqlite3Strlen30(zBuf); sqlite3_randomness(15, &zBuf[j]); @@ -2436,6 +2986,7 @@ static int getTempname(int nBuf, char *zBuf){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; + zBuf[j+1] = 0; OSTRACE(("TEMP FILENAME: %s\n", zBuf)); return SQLITE_OK; @@ -2452,6 +3003,7 @@ static int winOpen( int *pOutFlags /* Status return flags */ ){ HANDLE h; + DWORD lastErrno; DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; @@ -2467,7 +3019,7 @@ static int winOpen( /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ - char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */ + char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */ int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE @@ -2526,17 +3078,24 @@ static int winOpen( */ if( !zUtf8Name ){ assert(isDelete && !isOpenJournal); - rc = getTempname(MAX_PATH+1, zTmpname); + rc = getTempname(MAX_PATH+2, zTmpname); if( rc!=SQLITE_OK ){ return rc; } zUtf8Name = zTmpname; } + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). + */ + assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || + zUtf8Name[strlen(zUtf8Name)+1]==0 ); + /* Convert the filename to the system encoding. */ zConverted = convertUtf8Filename(zUtf8Name); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isReadWrite ){ @@ -2582,26 +3141,26 @@ static int winOpen( #endif if( isNT() ){ - while( (h = CreateFileW((WCHAR*)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + while( (h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt, &lastErrno) ){} /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - while( (h = CreateFileA((char*)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + while( (h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt, &lastErrno) ){} #endif } @@ -2612,9 +3171,9 @@ static int winOpen( h==INVALID_HANDLE_VALUE ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ - pFile->lastErrno = GetLastError(); - winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name); - free(zConverted); + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); + sqlite3_free(zConverted); if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); @@ -2638,14 +3197,16 @@ static int winOpen( pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; - pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pFile->ctrlFlags |= WINFILE_PSOW; + } #if SQLITE_OS_WINCE if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB && !winceCreateLock(zName, pFile) ){ - CloseHandle(h); - free(zConverted); + osCloseHandle(h); + sqlite3_free(zConverted); return SQLITE_CANTOPEN_BKPT; } if( isTemp ){ @@ -2653,7 +3214,7 @@ static int winOpen( }else #endif { - free(zConverted); + sqlite3_free(zConverted); } OpenCounter(+1); @@ -2663,7 +3224,7 @@ static int winOpen( /* ** Delete the named file. ** -** Note that windows does not allow a file to be deleted if some other +** Note that Windows does not allow a file to be deleted if some other ** process has it open. Sometimes a virus scanner or indexing program ** will open a journal file shortly after it is created in order to do ** whatever it does. While this other process is holding the @@ -2679,6 +3240,7 @@ static int winDelete( ){ int cnt = 0; int rc; + DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); @@ -2686,31 +3248,32 @@ static int winDelete( SimulateIOError(return SQLITE_IOERR_DELETE); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isNT() ){ rc = 1; - while( GetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = DeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} + while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ rc = 1; - while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){} + while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; #endif } if( rc ){ - rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, + "winDelete", zFilename); }else{ logIoerr(cnt); } - free(zConverted); + sqlite3_free(zConverted); OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); return rc; } @@ -2726,21 +3289,22 @@ static int winAccess( ){ DWORD attr; int rc = 0; + DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); SimulateIOError( return SQLITE_IOERR_ACCESS; ); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isNT() ){ int cnt = 0; WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); - while( !(rc = GetFileAttributesExW((WCHAR*)zConverted, + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, - &sAttrData)) && retryIoerr(&cnt) ){} + &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} if( rc ){ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file ** as if it does not exist. @@ -2754,24 +3318,24 @@ static int winAccess( } }else{ logIoerr(cnt); - if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ - winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename); - free(zConverted); + if( lastErrno!=ERROR_FILE_NOT_FOUND ){ + winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); + sqlite3_free(zConverted); return SQLITE_IOERR_ACCESS; }else{ attr = INVALID_FILE_ATTRIBUTES; } } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - attr = GetFileAttributesA((char*)zConverted); + attr = osGetFileAttributesA((char*)zConverted); #endif } - free(zConverted); + sqlite3_free(zConverted); switch( flags ){ case SQLITE_ACCESS_READ: case SQLITE_ACCESS_EXISTS: @@ -2836,117 +3400,50 @@ static int winFullPathname( SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } if( isNT() ){ - WCHAR *zTemp; - nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; } - GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); - free(zConverted); + osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + sqlite3_free(zConverted); zOut = unicodeToUtf8(zTemp); - free(zTemp); + sqlite3_free(zTemp); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ char *zTemp; - nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; } - GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); - free(zConverted); + osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + sqlite3_free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); - free(zTemp); + sqlite3_free(zTemp); #endif } if( zOut ){ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); - free(zOut); + sqlite3_free(zOut); return SQLITE_OK; }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } #endif } -/* -** Get the sector size of the device used to store -** file. -*/ -static int getSectorSize( - sqlite3_vfs *pVfs, - const char *zRelative /* UTF-8 file name */ -){ - DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; - /* GetDiskFreeSpace is not supported under WINCE */ -#if SQLITE_OS_WINCE - UNUSED_PARAMETER(pVfs); - UNUSED_PARAMETER(zRelative); -#else - char zFullpath[MAX_PATH+1]; - int rc; - DWORD dwRet = 0; - DWORD dwDummy; - - /* - ** We need to get the full path name of the file - ** to get the drive letter to look up the sector - ** size. - */ - SimulateIOErrorBenign(1); - rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); - SimulateIOErrorBenign(0); - if( rc == SQLITE_OK ) - { - void *zConverted = convertUtf8Filename(zFullpath); - if( zConverted ){ - if( isNT() ){ - /* trim path to just drive reference */ - WCHAR *p = zConverted; - for(;*p;p++){ - if( *p == '\\' ){ - *p = '\0'; - break; - } - } - dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); - }else{ - /* trim path to just drive reference */ - char *p = (char *)zConverted; - for(;*p;p++){ - if( *p == '\\' ){ - *p = '\0'; - break; - } - } - dwRet = GetDiskFreeSpaceA((char*)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); - } - free(zConverted); - } - if( !dwRet ){ - bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; - } - } -#endif - return (int) bytesPerSector; -} - #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points @@ -2964,37 +3461,30 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ return 0; } if( isNT() ){ - h = LoadLibraryW((WCHAR*)zConverted); + h = osLoadLibraryW((LPCWSTR)zConverted); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - h = LoadLibraryA((char*)zConverted); + h = osLoadLibraryA((char*)zConverted); #endif } - free(zConverted); + sqlite3_free(zConverted); return (void*)h; } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ UNUSED_PARAMETER(pVfs); - getLastErrorMsg(nBuf, zBufOut); + getLastErrorMsg(osGetLastError(), nBuf, zBufOut); } static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ UNUSED_PARAMETER(pVfs); -#if SQLITE_OS_WINCE - /* The GetProcAddressA() routine is only available on wince. */ - return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol); -#else - /* All other windows platforms expect GetProcAddress() to take - ** an Ansi string regardless of the _UNICODE setting */ - return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol); -#endif + return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol); } static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ UNUSED_PARAMETER(pVfs); - FreeLibrary((HANDLE)pHandle); + osFreeLibrary((HANDLE)pHandle); } #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ #define winDlOpen 0 @@ -3016,23 +3506,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ #else if( sizeof(SYSTEMTIME)<=nBuf-n ){ SYSTEMTIME x; - GetSystemTime(&x); + osGetSystemTime(&x); memcpy(&zBuf[n], &x, sizeof(x)); n += sizeof(x); } if( sizeof(DWORD)<=nBuf-n ){ - DWORD pid = GetCurrentProcessId(); + DWORD pid = osGetCurrentProcessId(); memcpy(&zBuf[n], &pid, sizeof(pid)); n += sizeof(pid); } if( sizeof(DWORD)<=nBuf-n ){ - DWORD cnt = GetTickCount(); + DWORD cnt = osGetTickCount(); memcpy(&zBuf[n], &cnt, sizeof(cnt)); n += sizeof(cnt); } if( sizeof(LARGE_INTEGER)<=nBuf-n ){ LARGE_INTEGER i; - QueryPerformanceCounter(&i); + osQueryPerformanceCounter(&i); memcpy(&zBuf[n], &i, sizeof(i)); n += sizeof(i); } @@ -3045,7 +3535,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ ** Sleep for a little while. Return the amount of time slept. */ static int winSleep(sqlite3_vfs *pVfs, int microsec){ - Sleep((microsec+999)/1000); + osSleep((microsec+999)/1000); UNUSED_PARAMETER(pVfs); return ((microsec+999)/1000)*1000; } @@ -3084,13 +3574,13 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ #if SQLITE_OS_WINCE SYSTEMTIME time; - GetSystemTime(&time); + osGetSystemTime(&time); /* if SystemTimeToFileTime() fails, it returns zero. */ - if (!SystemTimeToFileTime(&time,&ft)){ + if (!osSystemTimeToFileTime(&time,&ft)){ return SQLITE_ERROR; } #else - GetSystemTimeAsFileTime( &ft ); + osGetSystemTimeAsFileTime( &ft ); #endif *piNow = winFiletimeEpoch + @@ -3123,8 +3613,8 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ /* ** The idea is that this function works like a combination of -** GetLastError() and FormatMessage() on windows (or errno and -** strerror_r() on unix). After an error is returned by an OS +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS ** function, SQLite calls this function with zBuf pointing to ** a buffer of nBuf bytes. The OS layer should populate the ** buffer with a nul-terminated UTF-8 encoded error message @@ -3153,11 +3643,9 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ */ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ UNUSED_PARAMETER(pVfs); - return getLastErrorMsg(nBuf, zBuf); + return getLastErrorMsg(osGetLastError(), nBuf, zBuf); } - - /* ** Initialize and deinitialize the operating system interface. */ @@ -3182,21 +3670,26 @@ int sqlite3_os_init(void){ winCurrentTime, /* xCurrentTime */ winGetLastError, /* xGetLastError */ winCurrentTimeInt64, /* xCurrentTimeInt64 */ - 0, /* xSetSystemCall */ - 0, /* xGetSystemCall */ - 0, /* xNextSystemCall */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ }; + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==60 ); + #ifndef SQLITE_OMIT_WAL /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); - GetSystemInfo(&winSysInfo); + osGetSystemInfo(&winSysInfo); assert(winSysInfo.dwAllocationGranularity > 0); #endif sqlite3_vfs_register(&winVfs, 1); return SQLITE_OK; } + int sqlite3_os_end(void){ return SQLITE_OK; } diff --git a/src/pager.c b/src/pager.c index ad6f831..fe2408d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -616,6 +616,7 @@ struct Pager { u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ + u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ @@ -786,7 +787,7 @@ static int pagerUseWal(Pager *pPager){ #else # define pagerUseWal(x) 0 # define pagerRollbackWal(x) 0 -# define pagerWalFrames(v,w,x,y,z) 0 +# define pagerWalFrames(v,w,x,y) 0 # define pagerOpenWalIfPresent(z) SQLITE_OK # define pagerBeginReadTransaction(z) SQLITE_OK #endif @@ -2485,10 +2486,9 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ if( rc==SQLITE_OK && currentSize!=newSize ){ if( currentSize>newSize ){ rc = sqlite3OsTruncate(pPager->fd, newSize); - }else{ + }else if( (currentSize+szPage)<=newSize ){ char *pTmp = pPager->pTmpSpace; memset(pTmp, 0, szPage); - testcase( (newSize-szPage) < currentSize ); testcase( (newSize-szPage) == currentSize ); testcase( (newSize-szPage) > currentSize ); rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); @@ -2514,23 +2514,36 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ ** the value returned by the xSectorSize() method rounded up to 32 if ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it ** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. */ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); - if( !pPager->tempFile ){ + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 + ){ /* Sector size doesn't matter for temporary files. Also, the file ** may not have been opened yet, in which case the OsSectorSize() - ** call will segfault. - */ - pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); - } - if( pPager->sectorSize<32 ){ + ** call will segfault. */ pPager->sectorSize = 512; - } - if( pPager->sectorSize>MAX_SECTOR_SIZE ){ - assert( MAX_SECTOR_SIZE>=512 ); - pPager->sectorSize = MAX_SECTOR_SIZE; + }else{ + pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); + if( pPager->sectorSize<32 ){ + pPager->sectorSize = 512; + } + if( pPager->sectorSize>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + pPager->sectorSize = MAX_SECTOR_SIZE; + } } } @@ -2733,10 +2746,11 @@ end_playback: ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the ** assertion that the transaction counter was modified. */ - assert( - pPager->fd->pMethods==0 || - sqlite3OsFileControl(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0)>=SQLITE_OK - ); +#ifdef SQLITE_DEBUG + if( pPager->fd->pMethods ){ + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); + } +#endif /* If this playback is happening automatically as a result of an IO or ** malloc error that occurred after the change-counter was updated but @@ -2955,8 +2969,7 @@ static int pagerWalFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ Pgno nTruncate, /* Database size after this commit */ - int isCommit, /* True if this is a commit */ - int syncFlags /* Flags to pass to OsSync() (or 0) */ + int isCommit /* True if this is a commit */ ){ int rc; /* Return code */ #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) @@ -2987,7 +3000,7 @@ static int pagerWalFrames( if( pList->pgno==1 ) pager_write_changecounter(pList); rc = sqlite3WalFrames(pPager->pWal, - pPager->pageSize, pList, nTruncate, isCommit, syncFlags + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ PgHdr *p; @@ -3074,10 +3087,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ return rc; } } - nPage = (Pgno)(n / pPager->pageSize); - if( nPage==0 && n>0 ){ - nPage = 1; - } + nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); } /* If the current number of pages in the file is greater than the @@ -3267,13 +3277,13 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ */ if( pSavepoint ){ u32 ii; /* Loop counter */ - i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize); + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); if( pagerUseWal(pPager) ){ rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); } for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ - assert( offset==ii*(4+pPager->pageSize) ); + assert( offset==(i64)ii*(4+pPager->pageSize) ); rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); } assert( rc!=SQLITE_DONE ); @@ -3294,6 +3304,13 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); } +/* +** Free as much memory as possible from the pager. +*/ +void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + /* ** Adjust the robustness of the database to damage due to OS crashes ** or power failures by changing the number of syncs()s when writing @@ -3360,6 +3377,10 @@ void sqlite3PagerSetSafetyLevel( pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } + pPager->walSyncFlags = pPager->syncFlags; + if( pPager->fullSync ){ + pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + } } #endif @@ -3497,7 +3518,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ if( rc==SQLITE_OK ){ pager_reset(pPager); - pPager->dbSize = (Pgno)(nByte/pageSize); + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); pPager->pageSize = pageSize; sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; @@ -4005,7 +4026,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){ sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; - sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); pPager->dbHintSize = pPager->dbSize; } @@ -4114,7 +4135,7 @@ static int subjournalPage(PgHdr *pPg){ ** write the journal record into the file. */ if( rc==SQLITE_OK ){ void *pData = pPg->pData; - i64 offset = pPager->nSubRec*(4+pPager->pageSize); + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); @@ -4187,7 +4208,7 @@ static int pagerStress(void *p, PgHdr *pPg){ rc = subjournalPage(pPg); } if( rc==SQLITE_OK ){ - rc = pagerWalFrames(pPager, pPg, 0, 0, 0); + rc = pagerWalFrames(pPager, pPg, 0, 0); } }else{ @@ -4346,7 +4367,8 @@ int sqlite3PagerOpen( z += sqlite3Strlen30(z)+1; z += sqlite3Strlen30(z)+1; } - nUri = &z[1] - zUri; + nUri = (int)(&z[1] - zUri); + assert( nUri>=0 ); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname @@ -4380,9 +4402,9 @@ int sqlite3PagerOpen( ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ nPathname + 1 + nUri + /* zFilename */ - nPathname + 8 + 1 /* zJournal */ + nPathname + 8 + 2 /* zJournal */ #ifndef SQLITE_OMIT_WAL - + nPathname + 4 + 1 /* zWal */ + + nPathname + 4 + 2 /* zWal */ #endif ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); @@ -4405,12 +4427,12 @@ int sqlite3PagerOpen( memcpy(pPager->zFilename, zPathname, nPathname); memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); memcpy(pPager->zJournal, zPathname, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal", 8); + memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1); sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); #ifndef SQLITE_OMIT_WAL pPager->zWal = &pPager->zJournal[nPathname+8+1]; memcpy(pPager->zWal, zPathname, nPathname); - memcpy(&pPager->zWal[nPathname], "-wal", 4); + memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); #endif sqlite3_free(zPathname); @@ -4526,9 +4548,17 @@ int sqlite3PagerOpen( pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; - pPager->fullSync = pPager->noSync ?0:1; - pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = pPager->syncFlags; + if( pPager->noSync ){ + assert( pPager->fullSync==0 ); + assert( pPager->syncFlags==0 ); + assert( pPager->walSyncFlags==0 ); + assert( pPager->ckptSyncFlags==0 ); + }else{ + pPager->fullSync = 1; + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ @@ -5661,7 +5691,10 @@ int sqlite3PagerSync(Pager *pPager){ rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); }else if( isOpen(pPager->fd) ){ assert( !MEMDB ); - sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, (void *)&rc); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0); + if( rc==SQLITE_NOTFOUND ){ + rc = SQLITE_OK; + } } return rc; } @@ -5758,9 +5791,7 @@ int sqlite3PagerCommitPhaseOne( } assert( rc==SQLITE_OK ); if( ALWAYS(pList) ){ - rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, - (pPager->fullSync ? pPager->syncFlags : 0) - ); + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ @@ -6019,7 +6050,8 @@ int sqlite3PagerRollback(Pager *pPager){ } assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); - assert( rc==SQLITE_OK || rc==SQLITE_FULL || (rc&0xFF)==SQLITE_IOERR ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR ); /* If an error occurs during a ROLLBACK, we can no longer trust the pager ** cache. So call pager_error() on the way out to make any error persistent. @@ -6660,6 +6692,15 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +void sqlite3PagerClearCache(Pager *pPager){ + if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + #ifndef SQLITE_OMIT_WAL /* ** This function is called when the user invokes "PRAGMA wal_checkpoint", @@ -6836,13 +6877,6 @@ int sqlite3PagerCloseWal(Pager *pPager){ return rc; } -/* -** Unless this is an in-memory or temporary database, clear the pager cache. -*/ -void sqlite3PagerClearCache(Pager *pPager){ - if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); -} - #ifdef SQLITE_HAS_CODEC /* ** This function is called by the wal module when writing page content diff --git a/src/pager.h b/src/pager.h index e36e6c2..f68b19f 100644 --- a/src/pager.h +++ b/src/pager.h @@ -103,6 +103,7 @@ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); +void sqlite3PagerShrink(Pager*); void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerSetJournalMode(Pager *, int); diff --git a/src/parse.y b/src/parse.y index 92abd5c..2b8e917 100644 --- a/src/parse.y +++ b/src/parse.y @@ -33,12 +33,10 @@ UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); - pParse->parseError = 1; } %stack_overflow { UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */ sqlite3ErrorMsg(pParse, "parser stack overflow"); - pParse->parseError = 1; } // The name of the generated procedure that implements the parser @@ -396,6 +394,9 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); + sqlite3ExplainBegin(pParse->pVdbe); + sqlite3ExplainSelect(pParse->pVdbe, X); + sqlite3ExplainFinish(pParse->pVdbe); sqlite3SelectDelete(pParse->db, X); } diff --git a/src/pcache.c b/src/pcache.c index f37511e..482a188 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -20,7 +20,7 @@ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ int nRef; /* Number of referenced pages */ - int nMax; /* Configured cache size */ + int szCache; /* Configured cache size */ int szPage; /* Size of every page in this cache */ int szExtra; /* Size of extra space for each page */ int bPurgeable; /* True if pages are on backing store */ @@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0); } } @@ -141,18 +141,18 @@ static void pcacheUnpin(PgHdr *p){ ** functions are threadsafe. */ int sqlite3PcacheInitialize(void){ - if( sqlite3GlobalConfig.pcache.xInit==0 ){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ sqlite3PCacheSetDefault(); } - return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg); + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } void sqlite3PcacheShutdown(void){ - if( sqlite3GlobalConfig.pcache.xShutdown ){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ - sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg); + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); } } @@ -181,7 +181,7 @@ void sqlite3PcacheOpen( p->bPurgeable = bPurgeable; p->xStress = xStress; p->pStress = pStress; - p->nMax = 100; + p->szCache = 100; } /* @@ -191,13 +191,24 @@ void sqlite3PcacheOpen( void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ assert( pCache->nRef==0 && pCache->pDirty==0 ); if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); pCache->pCache = 0; pCache->pPage1 = 0; } pCache->szPage = szPage; } +/* +** Compute the number of pages of cache requested. +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + return p->szCache; + }else{ + return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + } +} + /* ** Try to obtain a page from the cache. */ @@ -207,7 +218,8 @@ int sqlite3PcacheFetch( int createFlag, /* If true, create page if it does not exist already */ PgHdr **ppPage /* Write the page here */ ){ - PgHdr *pPage = 0; + sqlite3_pcache_page *pPage = 0; + PgHdr *pPgHdr = 0; int eCreate; assert( pCache!=0 ); @@ -219,19 +231,19 @@ int sqlite3PcacheFetch( */ if( !pCache->pCache && createFlag ){ sqlite3_pcache *p; - int nByte; - nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr); - p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable); + p = sqlite3GlobalConfig.pcache2.xCreate( + pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable + ); if( !p ){ return SQLITE_NOMEM; } - sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax); + sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache)); pCache->pCache = p; } eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); if( pCache->pCache ){ - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); } if( !pPage && eCreate==1 ){ @@ -258,7 +270,7 @@ int sqlite3PcacheFetch( "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), - pCache->nMax); + numberOfCachePages(pCache)); #endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ @@ -266,33 +278,36 @@ int sqlite3PcacheFetch( } } - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); } if( pPage ){ - if( !pPage->pData ){ - memset(pPage, 0, sizeof(PgHdr)); - pPage->pData = (void *)&pPage[1]; - pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage]; - memset(pPage->pExtra, 0, pCache->szExtra); - pPage->pCache = pCache; - pPage->pgno = pgno; - } - assert( pPage->pCache==pCache ); - assert( pPage->pgno==pgno ); - assert( pPage->pData==(void *)&pPage[1] ); - assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] ); + pPgHdr = (PgHdr *)pPage->pExtra; - if( 0==pPage->nRef ){ + if( !pPgHdr->pPage ){ + memset(pPgHdr, 0, sizeof(PgHdr)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, pCache->szExtra); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + } + assert( pPgHdr->pCache==pCache ); + assert( pPgHdr->pgno==pgno ); + assert( pPgHdr->pData==pPage->pBuf ); + assert( pPgHdr->pExtra==(void *)&pPgHdr[1] ); + + if( 0==pPgHdr->nRef ){ pCache->nRef++; } - pPage->nRef++; + pPgHdr->nRef++; if( pgno==1 ){ - pCache->pPage1 = pPage; + pCache->pPage1 = pPgHdr; } } - *ppPage = pPage; - return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; + *ppPage = pPgHdr; + return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; } /* @@ -339,7 +354,7 @@ void sqlite3PcacheDrop(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1); } /* @@ -397,7 +412,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); - sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheRemoveFromDirtyList(p); @@ -434,7 +449,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ memset(pCache->pPage1->pData, 0, pCache->szPage); pgno = 1; } - sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1); + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); } } @@ -443,7 +458,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ */ void sqlite3PcacheClose(PCache *pCache){ if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } } @@ -555,7 +570,7 @@ int sqlite3PcachePageRefcount(PgHdr *p){ int sqlite3PcachePagecount(PCache *pCache){ int nPage = 0; if( pCache->pCache ){ - nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache); + nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); } return nPage; } @@ -565,7 +580,7 @@ int sqlite3PcachePagecount(PCache *pCache){ ** Get the suggested cache-size value. */ int sqlite3PcacheGetCachesize(PCache *pCache){ - return pCache->nMax; + return numberOfCachePages(pCache); } #endif @@ -573,9 +588,19 @@ int sqlite3PcacheGetCachesize(PCache *pCache){ ** Set the suggested cache-size value. */ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ - pCache->nMax = mxPage; + pCache->szCache = mxPage; if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage); + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); + } +} + +/* +** Free up as much memory as possible from the page cache. +*/ +void sqlite3PcacheShrink(PCache *pCache){ + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); } } diff --git a/src/pcache.h b/src/pcache.h index 33735d2..82543db 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -23,7 +23,8 @@ typedef struct PCache PCache; ** structure. */ struct PgHdr { - void *pData; /* Content of this page */ + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ void *pExtra; /* Extra content */ PgHdr *pDirty; /* Transient list of dirty pages */ Pgno pgno; /* Page number for this page */ @@ -141,6 +142,9 @@ void sqlite3PcacheSetCachesize(PCache *, int); int sqlite3PcacheGetCachesize(PCache *); #endif +/* Free up as much memory as possible from the page cache */ +void sqlite3PcacheShrink(PCache*); + #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* Try to return memory used by the pcache module to the main memory heap */ int sqlite3PcacheReleaseMemory(int); diff --git a/src/pcache1.c b/src/pcache1.c index 077a7b2..f76d7c8 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -24,7 +24,6 @@ typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; - /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set ** of one or more PCaches that are able to recycle each others unpinned ** pages when they are under memory pressure. A PGroup is an instance of @@ -41,7 +40,7 @@ typedef struct PGroup PGroup; ** Mode 1 uses more memory (since PCache instances are not able to rob ** unused pages from other PCaches) but it also operates without a mutex, ** and is therefore often faster. Mode 2 requires a mutex in order to be -** threadsafe, but is able recycle pages more efficient. +** threadsafe, but recycles pages more efficiently. ** ** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single ** PGroup which is the pcache1.grp global variable and its mutex is @@ -49,10 +48,10 @@ typedef struct PGroup PGroup; */ struct PGroup { sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ - int nMaxPage; /* Sum of nMax for purgeable caches */ - int nMinPage; /* Sum of nMin for purgeable caches */ - int mxPinned; /* nMaxpage + 10 - nMinPage */ - int nCurrentPage; /* Number of purgeable pages allocated */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nCurrentPage; /* Number of purgeable pages allocated */ PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ }; @@ -67,11 +66,12 @@ struct PGroup { struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable ** flag (bPurgeable) are set when the cache is created. nMax may be - ** modified at any time by a call to the pcache1CacheSize() method. + ** modified at any time by a call to the pcache1Cachesize() method. ** The PGroup mutex must be held when accessing nMax. */ PGroup *pGroup; /* PGroup this cache belongs to */ int szPage; /* Size of allocated pages in bytes */ + int szExtra; /* Size of extra space in bytes */ int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ @@ -90,11 +90,12 @@ struct PCache1 { /* ** Each cache entry is represented by an instance of the following -** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated -** directly before this structure in memory (see the PGHDR1_TO_PAGE() -** macro below). +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. */ struct PgHdr1 { + sqlite3_pcache_page page; unsigned int iKey; /* Key value (page number) */ PgHdr1 *pNext; /* Next in hash table chain */ PCache1 *pCache; /* Cache that currently owns this page */ @@ -144,21 +145,6 @@ static SQLITE_WSD struct PCacheGlobal { */ #define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) -/* -** When a PgHdr1 structure is allocated, the associated PCache1.szPage -** bytes of data are located directly before it in memory (i.e. the total -** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The -** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as -** an argument and returns a pointer to the associated block of szPage -** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is -** a pointer to a block of szPage bytes of data and the return value is -** a pointer to the associated PgHdr1 structure. -** -** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X ); -*/ -#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage) -#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage) - /* ** Macros to enter and leave the PCache LRU mutex. */ @@ -241,8 +227,9 @@ static void *pcache1Alloc(int nByte){ /* ** Free an allocated buffer obtained from pcache1Alloc(). */ -static void pcache1Free(void *p){ - if( p==0 ) return; +static int pcache1Free(void *p){ + int nFreed = 0; + if( p==0 ) return 0; if( p>=pcache1.pStart && pszPage; PgHdr1 *p = 0; void *pPg; @@ -297,16 +283,29 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ ** this mutex is not held. */ assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); pcache1LeaveMutex(pCache->pGroup); - pPg = pcache1Alloc(nByte); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else + pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra); + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif pcache1EnterMutex(pCache->pGroup); if( pPg ){ - p = PAGE_TO_PGHDR1(pCache, pPg); + p->page.pBuf = pPg; + p->page.pExtra = &p[1]; if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage++; } + return p; } - return p; + return 0; } /* @@ -320,7 +319,10 @@ static void pcache1FreePage(PgHdr1 *p){ if( ALWAYS(p) ){ PCache1 *pCache = p->pCache; assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); - pcache1Free(PGHDR1_TO_PAGE(p)); + pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage--; } @@ -355,13 +357,13 @@ void sqlite3PageFree(void *p){ ** for all page cache needs and we should not need to spill the ** allocation onto the heap. ** -** Or, the heap is used for all page cache memory put the heap is +** Or, the heap is used for all page cache memory but the heap is ** under memory pressure, then again it is desirable to avoid ** allocating a new page cache entry in order to avoid stressing ** the heap even further. */ static int pcache1UnderMemoryPressure(PCache1 *pCache){ - if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ return pcache1.bUnderPressure; }else{ return sqlite3HeapNearlyFull(); @@ -552,7 +554,7 @@ static void pcache1Shutdown(void *NotUsed){ ** ** Allocate a new cache. */ -static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ PCache1 *pCache; /* The newly created page cache */ PGroup *pGroup; /* The group the new page cache will belong to */ int sz; /* Bytes of memory required to allocate the new cache */ @@ -575,6 +577,9 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ int separateCache = sqlite3GlobalConfig.bCoreMutex>0; #endif + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; pCache = (PCache1 *)sqlite3_malloc(sz); if( pCache ){ @@ -587,6 +592,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ } pCache->pGroup = pGroup; pCache->szPage = szPage; + pCache->szExtra = szExtra; pCache->bPurgeable = (bPurgeable ? 1 : 0); if( bPurgeable ){ pCache->nMin = 10; @@ -618,6 +624,25 @@ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ } } +/* +** Implementation of the sqlite3_pcache.xShrink method. +** +** Free up as much memory as possible. +*/ +static void pcache1Shrink(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1*)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pGroup); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + /* ** Implementation of the sqlite3_pcache.xPagecount method. */ @@ -643,7 +668,7 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** For a non-purgeable cache (a cache used as the storage for an in-memory ** database) there is really no difference between createFlag 1 and 2. So ** the calling function (pcache.c) will never have a createFlag of 1 on -** a non-purgable cache. +** a non-purgeable cache. ** ** There are three different approaches to obtaining space for a page, ** depending on the value of parameter createFlag (which may be 0, 1 or 2). @@ -684,8 +709,12 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** ** 5. Otherwise, allocate and return a new page buffer. */ -static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ - int nPinned; +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + unsigned int nPinned; PCache1 *pCache = (PCache1 *)p; PGroup *pGroup; PgHdr1 *pPage = 0; @@ -719,15 +748,14 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ pGroup = pCache->pGroup; #endif - /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); nPinned = pCache->nPage - pCache->nRecyclable; - assert( nPinned>=0 ); assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); assert( pCache->n90pct == pCache->nMax*9/10 ); if( createFlag==1 && ( nPinned>=pGroup->mxPinned - || nPinned>=(int)pCache->n90pct + || nPinned>=pCache->n90pct || pcache1UnderMemoryPressure(pCache) )){ goto fetch_out; @@ -743,16 +771,24 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ || pGroup->nCurrentPage>=pGroup->nMaxPage || pcache1UnderMemoryPressure(pCache) )){ - PCache1 *pOtherCache; + PCache1 *pOther; pPage = pGroup->pLruTail; pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); - if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){ + pOther = pPage->pCache; + + /* We want to verify that szPage and szExtra are the same for pOther + ** and pCache. Assert that we can verify this by comparing sums. */ + assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); + assert( pCache->szExtra<512 ); + assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); + assert( pOther->szExtra<512 ); + + if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ pcache1FreePage(pPage); pPage = 0; }else{ - pGroup->nCurrentPage -= - (pOtherCache->bPurgeable - pCache->bPurgeable); + pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); } } @@ -773,7 +809,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ pPage->pCache = pCache; pPage->pLruPrev = 0; pPage->pLruNext = 0; - *(void **)(PGHDR1_TO_PAGE(pPage)) = 0; + *(void **)pPage->page.pExtra = 0; pCache->apHash[h] = pPage; } @@ -782,7 +818,7 @@ fetch_out: pCache->iMaxKey = iKey; } pcache1LeaveMutex(pGroup); - return (pPage ? PGHDR1_TO_PAGE(pPage) : 0); + return &pPage->page; } @@ -791,9 +827,13 @@ fetch_out: ** ** Mark a page as unpinned (eligible for asynchronous recycling). */ -static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); + PgHdr1 *pPage = (PgHdr1 *)pPg; PGroup *pGroup = pCache->pGroup; assert( pPage->pCache==pCache ); @@ -829,12 +869,12 @@ static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ */ static void pcache1Rekey( sqlite3_pcache *p, - void *pPg, + sqlite3_pcache_page *pPg, unsigned int iOld, unsigned int iNew ){ PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); + PgHdr1 *pPage = (PgHdr1 *)pPg; PgHdr1 **pp; unsigned int h; assert( pPage->iKey==iOld ); @@ -888,7 +928,9 @@ static void pcache1Destroy(sqlite3_pcache *p){ assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); pGroup->nMinPage -= pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1EnforceMaxPage(pGroup); @@ -903,7 +945,8 @@ static void pcache1Destroy(sqlite3_pcache *p){ ** already provided an alternative. */ void sqlite3PCacheSetDefault(void){ - static const sqlite3_pcache_methods defaultMethods = { + static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ 0, /* pArg */ pcache1Init, /* xInit */ pcache1Shutdown, /* xShutdown */ @@ -914,9 +957,10 @@ void sqlite3PCacheSetDefault(void){ pcache1Unpin, /* xUnpin */ pcache1Rekey, /* xRekey */ pcache1Truncate, /* xTruncate */ - pcache1Destroy /* xDestroy */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ }; - sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT @@ -937,7 +981,10 @@ int sqlite3PcacheReleaseMemory(int nReq){ PgHdr1 *p; pcache1EnterMutex(&pcache1.grp); while( (nReq<0 || nFreepage.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); @@ -965,8 +1012,8 @@ void sqlite3PcacheStats( nRecyclable++; } *pnCurrent = pcache1.grp.nCurrentPage; - *pnMax = pcache1.grp.nMaxPage; - *pnMin = pcache1.grp.nMinPage; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; *pnRecyclable = nRecyclable; } #endif diff --git a/src/pragma.c b/src/pragma.c index d9047e1..5ca1792 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -346,7 +346,7 @@ void sqlite3Pragma( goto pragma_out; } -#ifndef SQLITE_OMIT_PAGER_PRAGMAS +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N @@ -395,7 +395,9 @@ void sqlite3Pragma( sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } }else +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) /* ** PRAGMA [database.]page_size ** PRAGMA [database.]page_size=N @@ -416,7 +418,7 @@ void sqlite3Pragma( ** buffer that the pager module resizes using sqlite3_realloc(). */ db->nextPagesize = sqlite3Atoi(zRight); - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ db->mallocFailed = 1; } } @@ -456,6 +458,10 @@ void sqlite3Pragma( ** second form attempts to change this setting. Both ** forms return the current setting. ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** ** PRAGMA [database.]page_count ** ** Return the number of pages in the specified database. @@ -470,7 +476,8 @@ void sqlite3Pragma( if( sqlite3Tolower(zLeft[0])=='p' ){ sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); }else{ - sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight)); + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, + sqlite3AbsInt32(sqlite3Atoi(zRight))); } sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); sqlite3VdbeSetNumCols(v, 1); @@ -684,14 +691,11 @@ void sqlite3Pragma( ** PRAGMA [database.]cache_size=N ** ** The first form reports the current local setting for the - ** page cache size. The local setting can be different from - ** the persistent cache size value that is stored in the database - ** file itself. The value returned is the maximum number of - ** pages in the page cache. The second form sets the local - ** page cache size value. It does not change the persistent - ** cache size stored on the disk so the cache size will revert - ** to its default value when the database is closed and reopened. - ** N should be a positive integer. + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. */ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -699,7 +703,7 @@ void sqlite3Pragma( if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ - int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } @@ -791,7 +795,7 @@ void sqlite3Pragma( Pager *pPager = sqlite3BtreePager(pDb->pBt); char *proxy_file_path = NULL; sqlite3_file *pFile = sqlite3PagerFile(pPager); - sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE, + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, &proxy_file_path); if( proxy_file_path ){ @@ -1434,6 +1438,16 @@ void sqlite3Pragma( }else #endif + /* + ** PRAGMA shrink_memory + ** + ** This pragma attempts to free as much memory as possible from the + ** current database connection. + */ + if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ + sqlite3_db_release_memory(db); + }else + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases @@ -1515,13 +1529,13 @@ void sqlite3Pragma( extern int codec_set_page_size(sqlite3*, int, int); codec_set_page_size(db, iDb, atoi(zRight)); // change page size }else + if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){ + extern void codec_set_default_use_hmac(int); + codec_set_default_use_hmac(sqlite3GetBoolean(zRight)); + }else if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){ extern int codec_set_use_hmac(sqlite3*, int, int); - if(sqlite3GetBoolean(zRight)) { - codec_set_use_hmac(db, iDb, 1); - } else { - codec_set_use_hmac(db, iDb, 0); - } + codec_set_use_hmac(db, iDb, sqlite3GetBoolean(zRight)); }else /** END CRYPTO **/ #endif diff --git a/src/prepare.c b/src/prepare.c index fc45b8e..faeefa8 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -278,9 +278,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } diff --git a/src/printf.c b/src/printf.c index 0babee5..58cfd2b 100644 --- a/src/printf.c +++ b/src/printf.c @@ -136,7 +136,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ /* ** Append N space characters to the given string buffer. */ -static void appendSpace(StrAccum *pAccum, int N){ +void sqlite3AppendSpace(StrAccum *pAccum, int N){ static const char zSpaces[] = " "; while( N>=(int)sizeof(zSpaces)-1 ){ sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1); @@ -664,7 +664,7 @@ void sqlite3VXPrintf( register int nspace; nspace = width-length; if( nspace>0 ){ - appendSpace(pAccum, nspace); + sqlite3AppendSpace(pAccum, nspace); } } if( length>0 ){ @@ -674,7 +674,7 @@ void sqlite3VXPrintf( register int nspace; nspace = width-length; if( nspace>0 ){ - appendSpace(pAccum, nspace); + sqlite3AppendSpace(pAccum, nspace); } } sqlite3_free(zExtra); diff --git a/src/resolve.c b/src/resolve.c index 6d857f0..3da4813 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -799,7 +799,7 @@ static int resolveCompoundOrderBy( pE->pColl = pColl; pE->flags |= EP_IntValue | flags; pE->u.iValue = iCol; - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; @@ -848,12 +848,12 @@ int sqlite3ResolveOrderGroupBy( pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - if( pItem->iCol ){ - if( pItem->iCol>pEList->nExpr ){ + if( pItem->iOrderByCol ){ + if( pItem->iOrderByCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType); + resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType); } } return 0; @@ -900,7 +900,7 @@ static int resolveOrderGroupBy( ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } if( sqlite3ExprIsInteger(pE, &iCol) ){ @@ -911,12 +911,12 @@ static int resolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, nResult); return 1; } - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ - pItem->iCol = 0; + pItem->iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } diff --git a/src/select.c b/src/select.c index 571a778..188050e 100644 --- a/src/select.c +++ b/src/select.c @@ -2219,8 +2219,8 @@ static int multiSelectOrderBy( for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ struct ExprList_item *pItem; for(j=0, pItem=pOrderBy->a; jiCol>0 ); - if( pItem->iCol==i ) break; + assert( pItem->iOrderByCol>0 ); + if( pItem->iOrderByCol==i ) break; } if( j==nOrderBy ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); @@ -2228,7 +2228,7 @@ static int multiSelectOrderBy( pNew->flags |= EP_IntValue; pNew->u.iValue = i; pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - pOrderBy->a[nOrderBy++].iCol = (u16)i; + pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; } } } @@ -2244,8 +2244,8 @@ static int multiSelectOrderBy( if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; iiCol>0 && pItem->iCol<=p->pEList->nExpr ); - aPermute[i] = pItem->iCol - 1; + assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->iOrderByCol - 1; } pKeyMerge = sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1)); @@ -2588,9 +2588,8 @@ static void substSelect( #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* -** This routine attempts to flatten subqueries in order to speed -** execution. It returns 1 if it makes changes and 0 if no flattening -** occurs. +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** ** To understand the concept of flattening, consider the following ** query: @@ -2632,7 +2631,10 @@ static void substSelect( ** (6) The subquery does not use aggregates or the outer query is not ** DISTINCT. ** -** (7) The subquery has a FROM clause. +** (7) The subquery has a FROM clause. TODO: For subqueries without +** 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. ** @@ -2665,11 +2667,14 @@ static void substSelect( ** ** * is not itself part of a compound select, ** * is not an aggregate or DISTINCT query, and -** * has no other tables or sub-selects in the FROM clause. +** * is not a join ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, -** LIMIT and OFFSET clauses. +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). ** ** (18) If the sub-query is a compound select, then all terms of the ** ORDER by clause of the parent must be simple references to @@ -2681,7 +2686,7 @@ static void substSelect( ** (20) If the sub-query is a compound select, then it must not use ** an ORDER BY clause. Ticket #3773. We could relax this constraint ** somewhat by saying that the terms of the ORDER BY clause must -** appear as unmodified result columns in the outer query. But +** appear as unmodified result columns in the outer query. But we ** have other optimizations in mind to deal with that case. ** ** (21) The subquery does not use LIMIT or the outer query is not @@ -2810,19 +2815,21 @@ static int flattenSubquery( for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 || (pSub1->pPrior && pSub1->op!=TK_ALL) - || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1 + || pSub1->pSrc->nSrc<1 ){ return 0; } + testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction 18. */ if( p->pOrderBy ){ int ii; for(ii=0; iipOrderBy->nExpr; ii++){ - if( p->pOrderBy->a[ii].iCol==0 ) return 0; + if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; } } } @@ -3845,12 +3852,11 @@ int sqlite3Select( topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); - if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){ + if( pItem->isCorrelated==0 ){ /* If the subquery is no correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - int regOnce = ++pParse->nMem; - onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); + onceAddr = sqlite3CodeOnce(pParse); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); @@ -3860,7 +3866,7 @@ int sqlite3Select( retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); - + sqlite3ClearTempRegCache(pParse); } if( /*pParse->nErr ||*/ db->mallocFailed ){ goto select_end; @@ -4155,6 +4161,7 @@ int sqlite3Select( VdbeComment((v, "clear abort flag")); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. ** This might involve two separate loops with an OP_Sort in between, or @@ -4494,98 +4501,98 @@ select_end: return rc; } -#if defined(SQLITE_DEBUG) +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) /* -******************************************************************************* -** The following code is used for testing and debugging only. The code -** that follows does not appear in normal builds. -** -** These routines are used to print out the content of all or part of a -** parse structures such as Select or Expr. Such printouts are useful -** for helping to understand what is happening inside the code generator -** during the execution of complex SELECT statements. -** -** These routine are not called anywhere from within the normal -** code base. Then are intended to be called from within the debugger -** or from temporary "printf" statements inserted for debugging. +** Generate a human-readable description of a the Select object. */ -void sqlite3PrintExpr(Expr *p){ - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - sqlite3DebugPrintf("(%s", p->u.zToken); - }else{ - sqlite3DebugPrintf("(%d", p->op); - } - if( p->pLeft ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pLeft); - } - if( p->pRight ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pRight); - } - sqlite3DebugPrintf(")"); -} -void sqlite3PrintExprList(ExprList *pList){ - int i; - for(i=0; inExpr; i++){ - sqlite3PrintExpr(pList->a[i].pExpr); - if( inExpr-1 ){ - sqlite3DebugPrintf(", "); +static void explainOneSelect(Vdbe *pVdbe, Select *p){ + sqlite3ExplainPrintf(pVdbe, "SELECT "); + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + if( p->selFlags & SF_Distinct ){ + sqlite3ExplainPrintf(pVdbe, "DISTINCT "); } + if( p->selFlags & SF_Aggregate ){ + sqlite3ExplainPrintf(pVdbe, "agg_flag "); + } + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, " "); } -} -void sqlite3PrintSelect(Select *p, int indent){ - sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p); - sqlite3PrintExprList(p->pEList); - sqlite3DebugPrintf("\n"); - if( p->pSrc ){ - char *zPrefix; + sqlite3ExplainExprList(pVdbe, p->pEList); + sqlite3ExplainNL(pVdbe); + if( p->pSrc && p->pSrc->nSrc ){ int i; - zPrefix = "FROM"; + sqlite3ExplainPrintf(pVdbe, "FROM "); + sqlite3ExplainPush(pVdbe); for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; - sqlite3DebugPrintf("%*s ", indent+6, zPrefix); - zPrefix = ""; + sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor); if( pItem->pSelect ){ - sqlite3DebugPrintf("(\n"); - sqlite3PrintSelect(pItem->pSelect, indent+10); - sqlite3DebugPrintf("%*s)", indent+8, ""); + sqlite3ExplainSelect(pVdbe, pItem->pSelect); + if( pItem->pTab ){ + sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName); + } }else if( pItem->zName ){ - sqlite3DebugPrintf("%s", pItem->zName); - } - if( pItem->pTab ){ - sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName); + sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName); } if( pItem->zAlias ){ - sqlite3DebugPrintf(" AS %s", pItem->zAlias); + sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); } - if( ipSrc->nSrc-1 ){ - sqlite3DebugPrintf(","); + if( pItem->jointype & JT_LEFT ){ + sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN"); } - sqlite3DebugPrintf("\n"); + sqlite3ExplainNL(pVdbe); } + sqlite3ExplainPop(pVdbe); } if( p->pWhere ){ - sqlite3DebugPrintf("%*s WHERE ", indent, ""); - sqlite3PrintExpr(p->pWhere); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, "WHERE "); + sqlite3ExplainExpr(pVdbe, p->pWhere); + sqlite3ExplainNL(pVdbe); } if( p->pGroupBy ){ - sqlite3DebugPrintf("%*s GROUP BY ", indent, ""); - sqlite3PrintExprList(p->pGroupBy); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, "GROUPBY "); + sqlite3ExplainExprList(pVdbe, p->pGroupBy); + sqlite3ExplainNL(pVdbe); } if( p->pHaving ){ - sqlite3DebugPrintf("%*s HAVING ", indent, ""); - sqlite3PrintExpr(p->pHaving); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, "HAVING "); + sqlite3ExplainExpr(pVdbe, p->pHaving); + sqlite3ExplainNL(pVdbe); } if( p->pOrderBy ){ - sqlite3DebugPrintf("%*s ORDER BY ", indent, ""); - sqlite3PrintExprList(p->pOrderBy); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, "ORDERBY "); + sqlite3ExplainExprList(pVdbe, p->pOrderBy); + sqlite3ExplainNL(pVdbe); + } + if( p->pLimit ){ + sqlite3ExplainPrintf(pVdbe, "LIMIT "); + sqlite3ExplainExpr(pVdbe, p->pLimit); + sqlite3ExplainNL(pVdbe); + } + if( p->pOffset ){ + sqlite3ExplainPrintf(pVdbe, "OFFSET "); + sqlite3ExplainExpr(pVdbe, p->pOffset); + sqlite3ExplainNL(pVdbe); } } +void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ + if( p==0 ){ + sqlite3ExplainPrintf(pVdbe, "(null-select)"); + return; + } + while( p->pPrior ) p = p->pPrior; + sqlite3ExplainPush(pVdbe); + while( p ){ + explainOneSelect(pVdbe, p); + p = p->pNext; + if( p==0 ) break; + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op)); + } + sqlite3ExplainPrintf(pVdbe, "END"); + sqlite3ExplainPop(pVdbe); +} + /* End of the structure debug printing code *****************************************************************************/ #endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ diff --git a/src/shell.c b/src/shell.c index 07623e5..31d3dd8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1127,6 +1127,15 @@ static int shell_exec( fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); } + /* Output TESTCTRL_EXPLAIN text of requested */ + if( pArg && pArg->mode==MODE_Explain ){ + const char *zExplain = 0; + sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); + if( zExplain && zExplain[0] ){ + fprintf(pArg->out, "%s", zExplain); + } + } + /* perform the first step. this will tell us if we ** have a result set or not and how wide it is. */ @@ -1396,6 +1405,7 @@ static char zHelp[] = " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" + ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" ; @@ -2085,7 +2095,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ " (SELECT sql sql, type type, tbl_name tbl_name, name name" " FROM sqlite_master UNION ALL" " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " - "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL " + "WHERE lower(tbl_name) LIKE shellstatic()" + " AND type!='meta' AND sql NOTNULL " "ORDER BY substr(type,2,1), name", callback, &data, &zErrMsg); zShellStatic = 0; @@ -2219,7 +2230,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, }; int testctrl = -1; @@ -2264,7 +2274,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ case SQLITE_TESTCTRL_PRNG_SAVE: case SQLITE_TESTCTRL_PRNG_RESTORE: case SQLITE_TESTCTRL_PRNG_RESET: - case SQLITE_TESTCTRL_PGHDRSZ: if( nArg==2 ){ rc = sqlite3_test_control(testctrl); printf("%d (0x%08x)\n", rc, rc); @@ -2336,10 +2345,22 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - printf("SQLite %s %s\n", + printf("SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); }else + if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ + const char *zDbName = nArg==2 ? azArg[1] : "main"; + char *zVfsName = 0; + if( p->db ){ + sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); + if( zVfsName ){ + printf("%s\n", zVfsName); + sqlite3_free(zVfsName); + } + } + }else + if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); @@ -2933,7 +2954,7 @@ int main(int argc, char **argv){ char *zHistory = 0; int nHistory; printf( - "SQLite version %s %.19s\n" + "SQLite version %s %.19s\n" /*extra-version-info*/ "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ed18330..e8f76e7 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -172,7 +172,7 @@ const char *sqlite3_compileoption_get(int N); ** CAPI3REF: Test To See If The Library Is Threadsafe ** ** ^The sqlite3_threadsafe() function returns zero if and only if -** SQLite was compiled mutexing code omitted due to the +** SQLite was compiled with mutexing code omitted due to the ** [SQLITE_THREADSAFE] compile-time option being set to 0. ** ** SQLite can be compiled with or without mutexes. When @@ -366,7 +366,7 @@ int sqlite3_exec( ** KEYWORDS: {result code} {result codes} ** ** Many SQLite functions return an integer result code from the set shown -** here in order to indicates success or failure. +** here in order to indicate success or failure. ** ** New error codes may be added in future versions of SQLite. ** @@ -504,7 +504,11 @@ int sqlite3_exec( ** first then the size of the file is extended, never the other ** way around. The SQLITE_IOCAP_SEQUENTIAL property means that ** information is written to disk in the same order as calls -** to xWrite(). +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -518,6 +522,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 /* ** CAPI3REF: File Locking Levels @@ -739,12 +744,12 @@ struct sqlite3_io_methods { ** ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the -** windows [VFS] in order to work to provide robustness against +** windows [VFS] in order to provide robustness in the presence of ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay ** of 25 milliseconds before the first retry and with the delay increasing ** by an additional 25 milliseconds with each subsequent retry. This -** opcode allows those to values (10 retries and 25 milliseconds of delay) +** 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 i the new retry count and the second @@ -767,22 +772,44 @@ struct sqlite3_io_methods { ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. +** +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. */ -#define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 -#define SQLITE_FCNTL_SIZE_HINT 5 -#define SQLITE_FCNTL_CHUNK_SIZE 6 -#define SQLITE_FCNTL_FILE_POINTER 7 -#define SQLITE_FCNTL_SYNC_OMITTED 8 -#define SQLITE_FCNTL_WIN32_AV_RETRY 9 -#define SQLITE_FCNTL_PERSIST_WAL 10 -#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 /* ** CAPI3REF: Mutex Handle @@ -837,7 +864,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** from xFullPathname() with an optional suffix added. ** ^If a suffix is added to the zFilename parameter, it will ** consist of a single "-" character followed by no more than -** 10 alphanumeric and/or "-" characters. +** 11 alphanumeric and/or "-" characters. ** ^SQLite further guarantees that ** the string will be valid and unchanged until xClose() is ** called. Because of the previous sentence, @@ -1368,7 +1395,7 @@ struct sqlite3_mem_methods { **
^This option specifies a static memory buffer that SQLite can use for ** the database page cache with the default page cache implementation. ** This configuration should not be used if an application-define page -** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option. ** There are three arguments to this option: A pointer to 8-byte aligned ** memory, the size of each page buffer (sz), and the number of pages (N). ** The sz argument should be the size of the largest database page @@ -1437,15 +1464,15 @@ struct sqlite3_mem_methods { ** verb to [sqlite3_db_config()] can be used to change the lookaside ** configuration on individual connections.)^
** -** [[SQLITE_CONFIG_PCACHE]]
SQLITE_CONFIG_PCACHE
+** [[SQLITE_CONFIG_PCACHE2]]
SQLITE_CONFIG_PCACHE2
**
^(This option takes a single argument which is a pointer to -** an [sqlite3_pcache_methods] object. This object specifies the interface +** an [sqlite3_pcache_methods2] object. This object specifies the interface ** to a custom page cache implementation.)^ ^SQLite makes a copy of the ** object and uses it for page cache memory allocations.
** -** [[SQLITE_CONFIG_GETPCACHE]]
SQLITE_CONFIG_GETPCACHE
+** [[SQLITE_CONFIG_GETPCACHE2]]
SQLITE_CONFIG_GETPCACHE2
**
^(This option takes a single argument which is a pointer to an -** [sqlite3_pcache_methods] object. SQLite copies of the current +** [sqlite3_pcache_methods2] object. SQLite copies of the current ** page cache implementation into that object.)^
** ** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
@@ -1478,6 +1505,11 @@ struct sqlite3_mem_methods { ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE +**
These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1493,10 +1525,12 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ -#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ #define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ /* ** CAPI3REF: Database Connection Configuration Options @@ -1981,7 +2015,7 @@ void sqlite3_free_table(char **result); ** All of the usual printf() formatting options apply. In addition, there ** is are "%q", "%Q", and "%z" options. ** -** ^(The %q option works like %s in that it substitutes a null-terminated +** ^(The %q option works like %s in that it substitutes a nul-terminated ** string from the argument list. But %q also doubles every '\'' character. ** %q is designed for use inside a string literal.)^ By doubling each '\'' ** character it escapes that character and allows it to be inserted into @@ -2589,21 +2623,40 @@ int sqlite3_open_v2( /* ** CAPI3REF: Obtain Values For URI Parameters ** -** This is a utility routine, useful to VFS implementations, that checks +** These are utility routines, useful to VFS implementations, that check ** to see if a database file was a URI that contained a specific query -** parameter, and if so obtains the value of the query parameter. +** parameter, and if so obtains the value of that query parameter. ** -** The zFilename argument is the filename pointer passed into the xOpen() -** method of a VFS implementation. The zParam argument is the name of the -** query parameter we seek. This routine returns the value of the zParam -** parameter if it exists. If the parameter does not exist, this routine -** returns a NULL pointer. +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. ** -** If the zFilename argument to this function is not a pointer that SQLite -** passed into the xOpen VFS method, then the behavior of this routine -** is undefined and probably undesirable. +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The value of P is true if it is "yes" or "true" or "on" or +** a non-zero number and is false otherwise. If P is not a query parameter +** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* @@ -2925,6 +2978,25 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt); */ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +int sqlite3_stmt_busy(sqlite3_stmt*); + /* ** CAPI3REF: Dynamically Typed Value Object ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} @@ -3466,7 +3538,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** bytes in the string, not the number of characters. ** ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), -** even empty strings, are always zero terminated. ^The return +** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** ** ^The object returned by [sqlite3_column_value()] is an @@ -4366,6 +4438,22 @@ int sqlite3_get_autocommit(sqlite3*); */ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +/* +** CAPI3REF: Return The Filename For A Database Connection +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); + /* ** CAPI3REF: Find the next prepared statement ** @@ -4401,13 +4489,15 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** on the same [database connection] D, or NULL for ** the first call for each function on D. ** +** The commit and rollback hook callbacks are not reentrant. ** The callback implementation must not do anything that will modify ** the database connection that invoked the callback. Any actions ** to modify the database connection must be deferred until after the ** completion of the [sqlite3_step()] call that triggered the commit ** or rollback hook in the first place. -** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their -** database connections for the meaning of "modify" in this paragraph. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. ** ** ^Registering a NULL function disables the callback. ** @@ -4520,9 +4610,24 @@ int sqlite3_enable_shared_cache(int); ** which might be more or less than the amount requested. ** ^The sqlite3_release_memory() routine is a no-op returning zero ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] */ int sqlite3_release_memory(int); +/* +** CAPI3REF: Free Memory Used By A Database Connection +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is effect even +** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +int sqlite3_db_release_memory(sqlite3*); + /* ** CAPI3REF: Impose A Limit On Heap Size ** @@ -4537,7 +4642,8 @@ int sqlite3_release_memory(int); ** is advisory only. ** ** ^The return value from sqlite3_soft_heap_limit64() is the size of -** the soft heap limit prior to the call. ^If the argument N is negative +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative ** then no change is made to the soft heap limit. Hence, the current ** size of the soft heap limit can be determined by invoking ** sqlite3_soft_heap_limit64() with a negative argument. @@ -4553,7 +4659,7 @@ int sqlite3_release_memory(int); ** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. **
  • An alternative page cache implementation is specified using -** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...). +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). **
  • The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. @@ -5295,7 +5401,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** **
      **
    • SQLITE_MUTEX_OS2 -**
    • SQLITE_MUTEX_PTHREAD +**
    • SQLITE_MUTEX_PTHREADS **
    • SQLITE_MUTEX_W32 **
    • SQLITE_MUTEX_NOOP **
    )^ @@ -5303,7 +5409,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in ** a single-threaded application. ^The SQLITE_MUTEX_OS2, -** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations ** are appropriate for use on OS/2, Unix, and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor @@ -5493,7 +5599,7 @@ struct sqlite3_mutex_methods { ** ^These routines should return true if the mutex in their argument ** is held or not held, respectively, by the calling thread. ** -** ^The implementation is not required to provided versions of these +** ^The implementation is not required to provide versions of these ** routines that actually work. If the implementation does not provide working ** versions of these routines, it should at least provide stubs that always ** return true so that one does not get spurious assertion failures. @@ -5621,9 +5727,9 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_PGHDRSZ 17 -#define SQLITE_TESTCTRL_SCRATCHMALLOC 18 -#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_LAST 19 /* @@ -5926,17 +6032,33 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** sqlite3_pcache object except by holding and passing pointers ** to the object. ** -** See [sqlite3_pcache_methods] for additional information. +** See [sqlite3_pcache_methods2] for additional information. */ typedef struct sqlite3_pcache sqlite3_pcache; +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + /* ** CAPI3REF: Application Defined Page Cache. ** KEYWORDS: {page cache} ** -** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can ** register an alternative page cache implementation by passing in an -** instance of the sqlite3_pcache_methods structure.)^ +** instance of the sqlite3_pcache_methods2 structure.)^ ** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. ** By implementing a @@ -5950,7 +6072,7 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** extreme measure that is only needed by the most demanding applications. ** The built-in page cache is recommended for most uses. ** -** ^(The contents of the sqlite3_pcache_methods structure are copied to an +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an ** internal buffer by SQLite within the call to [sqlite3_config]. Hence ** the application may discard the parameter after the call to ** [sqlite3_config()] returns.)^ @@ -5959,7 +6081,7 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ^(The xInit() method is called once for each effective ** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() -** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^ +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ ** The intent of the xInit() method is to set up global data structures ** required by the custom page cache implementation. ** ^(If the xInit() method is NULL, then the @@ -5986,17 +6108,15 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will not be a power of two. ^szPage -** will the page size of the database file that is to be cached plus an -** increment (here called "R") of less than 250. SQLite will use the -** extra R bytes on each page to store metadata about the underlying -** database page on disk. The value of R depends +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends ** on the SQLite version, the target platform, and how SQLite was compiled. -** ^(R is constant for a particular build of SQLite. Except, there are two -** distinct values of R when SQLite is compiled with the proprietary -** ZIPVFS extension.)^ ^The second argument to -** xCreate(), bPurgeable, is true if the cache being created will -** be used to cache database pages of a file stored on disk, or +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation ** does not have to do anything special based with the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will @@ -6020,11 +6140,16 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ** [[the xFetch() page cache methods]] ** The xFetch() method locates a page in the cache and returns a pointer to -** the page, or a NULL pointer. -** A "page", in this context, means a buffer of szPage bytes aligned at an -** 8-byte boundary. The page to be fetched is determined by the key. ^The -** minimum key value is 1. After it has been retrieved using xFetch, the page -** is considered to be "pinned". +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content @@ -6077,8 +6202,37 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] -** handle invalid, and will not use it with any other sqlite3_pcache_methods +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 ** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. */ typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; struct sqlite3_pcache_methods { @@ -6095,6 +6249,7 @@ struct sqlite3_pcache_methods { void (*xDestroy)(sqlite3_pcache*); }; + /* ** CAPI3REF: Online Backup Object ** diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9e27654..6e48b1c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -125,6 +125,14 @@ #endif #endif +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + /* ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. ** It determines whether or not the features related to @@ -346,7 +354,7 @@ */ #define SQLITE_MAX_FILE_FORMAT 4 #ifndef SQLITE_DEFAULT_FILE_FORMAT -# define SQLITE_DEFAULT_FILE_FORMAT 1 +# define SQLITE_DEFAULT_FILE_FORMAT 4 #endif /* @@ -1144,20 +1152,11 @@ struct Column { struct CollSeq { char *zName; /* Name of the collating sequence, UTF-8 encoded */ u8 enc; /* Text encoding handled by xCmp() */ - u8 type; /* One of the SQLITE_COLL_... values below */ void *pUser; /* First argument to xCmp() */ int (*xCmp)(void*,int, const void*, int, const void*); void (*xDel)(void*); /* Destructor for pUser */ }; -/* -** Allowed values of CollSeq.type: -*/ -#define SQLITE_COLL_BINARY 1 /* The default memcmp() collating sequence */ -#define SQLITE_COLL_NOCASE 2 /* The built-in NOCASE collating sequence */ -#define SQLITE_COLL_REVERSE 3 /* The built-in REVERSE collating sequence */ -#define SQLITE_COLL_USER 0 /* Any other user-defined collating sequence */ - /* ** A sort order can be either ASC or DESC. */ @@ -1443,7 +1442,7 @@ struct KeyInfo { struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ u16 nField; /* Number of entries in apMem[] */ - u16 flags; /* Boolean settings. UNPACKED_... below */ + u8 flags; /* Boolean settings. UNPACKED_... below */ i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */ Mem *aMem; /* Values */ }; @@ -1451,12 +1450,9 @@ struct UnpackedRecord { /* ** Allowed values of UnpackedRecord.flags */ -#define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */ -#define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */ -#define UNPACKED_IGNORE_ROWID 0x0004 /* Ignore trailing rowid on key1 */ -#define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */ -#define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */ -#define UNPACKED_PREFIX_SEARCH 0x0020 /* A prefix match is considered OK */ +#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */ +#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */ +#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */ /* ** Each SQL index is represented in memory by an @@ -1719,10 +1715,10 @@ struct Expr { #define EP_FixedDest 0x0200 /* Result needed in a specific register */ #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */ - -#define EP_Reduced 0x1000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ -#define EP_TokenOnly 0x2000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ -#define EP_Static 0x4000 /* Held in memory not obtained from malloc() */ +#define EP_Hint 0x1000 /* Optimizer hint. Not required for correctness */ +#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ +#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ +#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */ /* ** The following are the meanings of bits in the Expr.flags2 field. @@ -1784,7 +1780,7 @@ struct ExprList { char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ u8 done; /* A flag to indicate when processing is finished */ - u16 iCol; /* For ORDER BY, column number in result set */ + u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } *a; /* One entry for each expression */ }; @@ -2084,13 +2080,13 @@ struct Select { ** Allowed values for Select.selFlags. The "SF" prefix stands for ** "Select Flag". */ -#define SF_Distinct 0x0001 /* Output should be DISTINCT */ -#define SF_Resolved 0x0002 /* Identifiers have been resolved */ -#define SF_Aggregate 0x0004 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ -#define SF_UseSorter 0x0040 /* Sort using a sorter */ +#define SF_Distinct 0x01 /* Output should be DISTINCT */ +#define SF_Resolved 0x02 /* Identifiers have been resolved */ +#define SF_Aggregate 0x04 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */ +#define SF_UseSorter 0x40 /* Sort using a sorter */ /* @@ -2205,10 +2201,8 @@ struct Parse { char *zErrMsg; /* An error message */ Vdbe *pVdbe; /* An engine for executing database bytecode */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ - u8 nameClash; /* A permanent table name clashes with temp table name */ u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ - u8 parseError; /* True after a parsing error. Ticket #1794 */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 nTempInUse; /* Number of aTempReg[] currently checked out */ int aTempReg[8]; /* Holding area for temporary registers */ @@ -2218,11 +2212,12 @@ struct Parse { int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ + int nOnce; /* Number of OP_Once instructions so far */ int ckBase; /* Base register of data during check constraints */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ - u8 nColCache; /* Number of entries in the column cache */ - u8 iColCache; /* Next entry of the cache to replace */ + u8 nColCache; /* Number of entries in aColCache[] */ + u8 iColCache; /* Next entry in aColCache[] to replace */ struct yColCache { int iTable; /* Table cursor number */ int iColumn; /* Table column number */ @@ -2264,7 +2259,6 @@ struct Parse { char **azVar; /* Pointers to names of parameters */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ int nAlias; /* Number of aliased result set columns */ - int nAliasAlloc; /* Number of allocated slots for aAlias[] */ int *aAlias; /* Register used to hold aliased result */ u8 explain; /* True if the EXPLAIN flag is found on the query */ Token sNameToken; /* Token with unqualified schema object name */ @@ -2459,7 +2453,7 @@ struct Sqlite3Config { int nLookaside; /* Default lookaside buffer count */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ - sqlite3_pcache_methods pcache; /* Low-level page-cache interface */ + sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ @@ -2665,6 +2659,29 @@ char *sqlite3MAppendf(sqlite3*,char*,const char*,...); #if defined(SQLITE_TEST) void *sqlite3TestTextToPtr(const char*); #endif + +/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */ +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) + void sqlite3ExplainBegin(Vdbe*); + void sqlite3ExplainPrintf(Vdbe*, const char*, ...); + void sqlite3ExplainNL(Vdbe*); + void sqlite3ExplainPush(Vdbe*); + void sqlite3ExplainPop(Vdbe*); + void sqlite3ExplainFinish(Vdbe*); + void sqlite3ExplainSelect(Vdbe*, Select*); + void sqlite3ExplainExpr(Vdbe*, Expr*); + void sqlite3ExplainExprList(Vdbe*, ExprList*); + const char *sqlite3VdbeExplanation(Vdbe*); +#else +# define sqlite3ExplainBegin(X) +# define sqlite3ExplainSelect(A,B) +# define sqlite3ExplainExpr(A,B) +# define sqlite3ExplainExprList(A,B) +# define sqlite3ExplainFinish(X) +# define sqlite3VdbeExplanation(X) 0 +#endif + + void sqlite3SetString(char **, sqlite3*, const char*, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); int sqlite3Dequote(char*); @@ -2675,6 +2692,7 @@ int sqlite3GetTempReg(Parse*); void sqlite3ReleaseTempReg(Parse*,int); int sqlite3GetTempRange(Parse*,int); void sqlite3ReleaseTempRange(Parse*,int,int); +void sqlite3ClearTempRegCache(Parse*); Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); @@ -2706,6 +2724,7 @@ void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); +int sqlite3CodeOnce(Parse *); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); @@ -3044,6 +3063,7 @@ int sqlite3OpenTempDatabase(Parse *); void sqlite3StrAccumInit(StrAccum*, char*, int, int); void sqlite3StrAccumAppend(StrAccum*,const char*,int); +void sqlite3AppendSpace(StrAccum*,int); char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index c8f0fbd..967b1a0 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3001,6 +3001,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } + }else if( strcmp(zArg, "-uri")==0 ){ + int b; + if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; + if( b ){ + flags |= SQLITE_OPEN_URI; + }else{ + flags &= ~SQLITE_OPEN_URI; + } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; @@ -3009,7 +3017,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( objc<3 || (objc&1)!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" - " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" + " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" #ifdef SQLITE_HAS_CODEC " ?-key CODECKEY?" #endif diff --git a/src/test1.c b/src/test1.c index 2634252..9cc5d63 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2330,6 +2330,33 @@ static int test_stmt_readonly( return TCL_OK; } +/* +** Usage: sqlite3_stmt_busy STMT +** +** Return true if STMT is a non-NULL pointer to a statement +** that has been stepped but not to completion. +*/ +static int test_stmt_busy( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int rc; + + if( objc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " STMT", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + rc = sqlite3_stmt_busy(pStmt); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc)); + return TCL_OK; +} + /* ** Usage: uses_stmt_journal STMT ** @@ -4593,6 +4620,54 @@ static int test_release_memory( return TCL_OK; } + +/* +** Usage: sqlite3_db_release_memory DB +** +** Attempt to release memory currently held by database DB. Return the +** result code (which in the current implementation is always zero). +*/ +static int test_db_release_memory( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + rc = sqlite3_db_release_memory(db); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** Usage: sqlite3_db_filename DB DBNAME +** +** Return the name of a file associated with a database. +*/ +static int test_db_filename( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + const char *zDbName; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zDbName = Tcl_GetString(objv[2]); + Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0); + return TCL_OK; +} + /* ** Usage: sqlite3_soft_heap_limit ?N? ** @@ -5160,6 +5235,71 @@ static int file_control_persist_wal( return TCL_OK; } +/* +** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG +** +** This TCL command runs the sqlite3_file_control interface with +** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode. +*/ +static int file_control_powersafe_overwrite( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + int rc; + int b; + char z[100]; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR; + rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b); + Tcl_AppendResult(interp, z, (char*)0); + return TCL_OK; +} + + +/* +** tclcmd: file_control_vfsname DB ?AUXDB? +** +** Return a string that describes the stack of VFSes. +*/ +static int file_control_vfsname( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + const char *zDbName = "main"; + char *zVfsName = 0; + + if( objc!=2 && objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( objc==3 ){ + zDbName = Tcl_GetString(objv[2]); + } + sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName); + Tcl_AppendResult(interp, zVfsName, (char*)0); + sqlite3_free(zVfsName); + return TCL_OK; +} + /* ** tclcmd: sqlite3_vfs_list @@ -5912,9 +6052,12 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_sql", test_sql ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, + { "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, + { "sqlite3_db_release_memory", test_db_release_memory, 0}, + { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, @@ -5982,6 +6125,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, + { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0}, + { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test2.c b/src/test2.c index fa7dd76..8343692 100644 --- a/src/test2.c +++ b/src/test2.c @@ -537,6 +537,8 @@ static int fake_big_file( int rc; int n; i64 offset; + char *zFile; + int nFile; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N-MEGABYTES FILE\"", 0); @@ -545,17 +547,24 @@ static int fake_big_file( if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; pVfs = sqlite3_vfs_find(0); - rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, + nFile = strlen(argv[2]); + zFile = sqlite3_malloc( nFile+2 ); + if( zFile==0 ) return TCL_ERROR; + memcpy(zFile, argv[2], nFile+1); + zFile[nFile+1] = 0; + rc = sqlite3OsOpenMalloc(pVfs, zFile, &fd, (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0 ); if( rc ){ Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0); + sqlite3_free(zFile); return TCL_ERROR; } offset = n; offset *= 1024*1024; rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset); sqlite3OsCloseFree(fd); + sqlite3_free(zFile); if( rc ){ Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0); return TCL_ERROR; diff --git a/src/test3.c b/src/test3.c index 4eabdcc..9bac2ca 100644 --- a/src/test3.c +++ b/src/test3.c @@ -66,6 +66,8 @@ static int btree_open( Btree *pBt; int rc, nCache; char zBuf[100]; + int n; + char *zFilename; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME NCACHE FLAGS\"", 0); @@ -78,8 +80,14 @@ static int btree_open( sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); sqlite3_mutex_enter(sDb.mutex); } - rc = sqlite3BtreeOpen(sDb.pVfs, argv[1], &sDb, &pBt, 0, + n = strlen(argv[1]); + zFilename = sqlite3_malloc( n+2 ); + if( zFilename==0 ) return TCL_ERROR; + memcpy(zFilename, argv[1], n+1); + zFilename[n+1] = 0; + rc = sqlite3BtreeOpen(sDb.pVfs, zFilename, &sDb, &pBt, 0, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); + sqlite3_free(zFilename); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; diff --git a/src/test6.c b/src/test6.c index 23fb14c..89f4a09 100644 --- a/src/test6.c +++ b/src/test6.c @@ -705,17 +705,18 @@ static int processDevSymArgs( char *zName; int iValue; } aFlag[] = { - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; diff --git a/src/test_config.c b/src/test_config.c index ce72f87..18442a4 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -37,6 +37,14 @@ ** procedures use this to determine when tests should be omitted. */ static void set_options(Tcl_Interp *interp){ +#ifdef HAVE_MALLOC_USABLE_SIZE + Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "1", + TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "0", + TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_32BIT_ROWID Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); #else diff --git a/src/test_func.c b/src/test_func.c index a123943..fff070e 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -149,13 +149,13 @@ static void test_destructor_count( ** arguments. It returns the text value returned by the sqlite3_errmsg16() ** API function. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_OMIT_BUILTIN_TEST void sqlite3BeginBenignMalloc(void); void sqlite3EndBenignMalloc(void); -#else - #define sqlite3BeginBenignMalloc() - #define sqlite3EndBenignMalloc() -#endif +#else + #define sqlite3BeginBenignMalloc() + #define sqlite3EndBenignMalloc() +#endif static void test_agg_errmsg16_step(sqlite3_context *a, int b,sqlite3_value **c){ } static void test_agg_errmsg16_final(sqlite3_context *ctx){ diff --git a/src/test_init.c b/src/test_init.c index a67b678..e3724d8 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -30,9 +30,9 @@ #include static struct Wrapped { - sqlite3_pcache_methods pcache; - sqlite3_mem_methods mem; - sqlite3_mutex_methods mutex; + sqlite3_pcache_methods2 pcache; + sqlite3_mem_methods mem; + sqlite3_mutex_methods mutex; int mem_init; /* True if mem subsystem is initalized */ int mem_fail; /* True to fail mem subsystem inialization */ @@ -123,8 +123,8 @@ static void wrPCacheShutdown(void *pArg){ wrapped.pcache_init = 0; } -static sqlite3_pcache *wrPCacheCreate(int a, int b){ - return wrapped.pcache.xCreate(a, b); +static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){ + return wrapped.pcache.xCreate(a, b, c); } static void wrPCacheCachesize(sqlite3_pcache *p, int n){ wrapped.pcache.xCachesize(p, n); @@ -132,13 +132,18 @@ static void wrPCacheCachesize(sqlite3_pcache *p, int n){ static int wrPCachePagecount(sqlite3_pcache *p){ return wrapped.pcache.xPagecount(p); } -static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){ +static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){ return wrapped.pcache.xFetch(p, a, b); } -static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){ +static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){ wrapped.pcache.xUnpin(p, a, b); } -static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){ +static void wrPCacheRekey( + sqlite3_pcache *p, + sqlite3_pcache_page *a, + unsigned b, + unsigned c +){ wrapped.pcache.xRekey(p, a, b, c); } static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){ @@ -154,8 +159,8 @@ static void installInitWrappers(void){ wrMutexFree, wrMutexEnter, wrMutexTry, wrMutexLeave, wrMutexHeld, wrMutexNotheld }; - sqlite3_pcache_methods pcachemethods = { - 0, + sqlite3_pcache_methods2 pcachemethods = { + 1, 0, wrPCacheInit, wrPCacheShutdown, wrPCacheCreate, wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch, wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate, @@ -173,10 +178,10 @@ static void installInitWrappers(void){ sqlite3_shutdown(); sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex); sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem); - sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache); + sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache); sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods); sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods); - sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods); } static int init_wrapper_install( @@ -218,7 +223,7 @@ static int init_wrapper_uninstall( sqlite3_shutdown(); sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex); sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem); - sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache); return TCL_OK; } diff --git a/src/test_journal.c b/src/test_journal.c index 6886972..00567db 100644 --- a/src/test_journal.c +++ b/src/test_journal.c @@ -391,7 +391,7 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){ while( rc==SQLITE_OK && iTrunk>0 ){ u32 nLeaf; u32 iLeaf; - sqlite3_int64 iOff = (iTrunk-1)*pMain->nPagesize; + sqlite3_int64 iOff = (i64)(iTrunk-1)*pMain->nPagesize; rc = sqlite3OsRead(p, aData, pMain->nPagesize, iOff); nLeaf = decodeUint32(&aData[4]); for(iLeaf=0; rc==SQLITE_OK && iLeafpReal, aData, pMain->nPagesize, iOff); pMain->aCksum[ii] = genCksum(aData, pMain->nPagesize); + if( ii+1==pMain->nPage && rc==SQLITE_IOERR_SHORT_READ ) rc = SQLITE_OK; } } @@ -662,7 +663,7 @@ static int jtCheckReservedLock(sqlite3_file *pFile, int *pResOut){ */ static int jtFileControl(sqlite3_file *pFile, int op, void *pArg){ jt_file *p = (jt_file *)pFile; - return sqlite3OsFileControl(p->pReal, op, pArg); + return p->pReal->pMethods->xFileControl(p->pReal, op, pArg); } /* diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 5d29607..af41c0b 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -81,6 +81,9 @@ #define sqlite3_mutex_notheld(X) ((void)(X),1) #endif /* SQLITE_THREADSAFE==0 */ +/* First chunk for rollback journal files */ +#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 + /************************ Shim Definitions ******************************/ @@ -96,26 +99,16 @@ # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112 #endif -/* Default limit on number of chunks. Care should be taken -** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT -** format specifier. It may be changed by calling -** the xFileControl() interface. +/* This used to be the default limit on number of chunks, but +** it is no longer enforced. There is currently no limit to the +** number of chunks. +** +** May be changed by calling the xFileControl() interface. */ #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS -# define SQLITE_MULTIPLEX_MAX_CHUNKS 32 +# define SQLITE_MULTIPLEX_MAX_CHUNKS 12 #endif -/* If SQLITE_MULTIPLEX_EXT_OVWR is defined, the -** last SQLITE_MULTIPLEX_EXT_SZ characters of the -** filename will be overwritten, otherwise, the -** multiplex extension is simply appended to the filename. -** Ex. (undefined) test.db -> test.db01 -** (defined) test.db -> test.01 -** Chunk 0 does not have a modified extension. -*/ -#define SQLITE_MULTIPLEX_EXT_FMT "%02d" -#define SQLITE_MULTIPLEX_EXT_SZ 2 - /************************ Object Definitions ******************************/ /* Forward declaration of all object types */ @@ -140,7 +133,8 @@ struct multiplexGroup { int nName; /* Length of base filename */ int flags; /* Flags used for original opening */ unsigned int szChunk; /* Chunk size used for this group */ - int bEnabled; /* TRUE to use Multiplex VFS for this file */ + unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */ + unsigned char bTruncate; /* TRUE to enable truncation of databases */ multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */ }; @@ -224,68 +218,58 @@ static int multiplexStrlen30(const char *z){ } /* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at pOrigVfs->mxPathname characters. This function departs -** from the traditional temporary name generation in the os_win -** and os_unix VFS in several ways, but is necessary so that -** the file name is known for temporary files (like those used -** during vacuum.) +** Generate the file-name for chunk iChunk of the group with base name +** zBase. The file-name is written to buffer zOut before returning. Buffer +** zOut must be allocated by the caller so that it is at least (nBase+5) +** bytes in size, where nBase is the length of zBase, not including the +** nul-terminator. ** -** N.B. This routine assumes your underlying VFS is ok with using -** "/" as a directory seperator. This is the default for UNIXs -** and is allowed (even mixed) for most versions of Windows. +** If iChunk is 0 (or 400 - the number for the first journal file chunk), +** the output is a copy of the input string. Otherwise, if +** SQLITE_ENABLE_8_3_NAMES is not defined or the input buffer does not contain +** a "." character, then the output is a copy of the input string with the +** three-digit zero-padded decimal representation if iChunk appended to it. +** For example: +** +** zBase="test.db", iChunk=4 -> zOut="test.db004" +** +** Or, if SQLITE_ENABLE_8_3_NAMES is defined and the input buffer contains +** a "." character, then everything after the "." is replaced by the +** three-digit representation of iChunk. +** +** zBase="test.db", iChunk=4 -> zOut="test.004" +** +** The output buffer string is terminated by 2 0x00 bytes. This makes it safe +** to pass to sqlite3_uri_parameter() and similar. */ -static int multiplexGetTempname(sqlite3_vfs *pOrigVfs, int nBuf, char *zBuf){ - static char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i,j; - int attempts = 0; - int exists = 0; - int rc = SQLITE_ERROR; - - /* Check that the output buffer is large enough for - ** pVfs->mxPathname characters. - */ - if( pOrigVfs->mxPathname <= nBuf ){ - char *zTmp = sqlite3_malloc(pOrigVfs->mxPathname); - if( zTmp==0 ) return SQLITE_NOMEM; - - /* sqlite3_temp_directory should always be less than - ** pVfs->mxPathname characters. - */ - sqlite3_snprintf(pOrigVfs->mxPathname, - zTmp, - "%s/", - sqlite3_temp_directory ? sqlite3_temp_directory : "."); - rc = pOrigVfs->xFullPathname(pOrigVfs, zTmp, nBuf, zBuf); - sqlite3_free(zTmp); - if( rc ) return rc; - - /* Check that the output buffer is large enough for the temporary file - ** name. - */ - j = multiplexStrlen30(zBuf); - if( (j + 8 + 1 + 3 + 1) <= nBuf ){ - /* Make 3 attempts to generate a unique name. */ - do { - attempts++; - sqlite3_randomness(8, &zBuf[j]); - for(i=0; i<8; i++){ - unsigned char uc = (unsigned char)zBuf[j+i]; - zBuf[j+i] = (char)zChars[uc%(sizeof(zChars)-1)]; - } - memcpy(&zBuf[j+i], ".tmp", 5); - rc = pOrigVfs->xAccess(pOrigVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists); - } while ( (rc==SQLITE_OK) && exists && (attempts<3) ); - if( rc==SQLITE_OK && exists ){ - rc = SQLITE_ERROR; - } +static void multiplexFilename( + const char *zBase, /* Filename for chunk 0 */ + int nBase, /* Size of zBase in bytes (without \0) */ + int flags, /* Flags used to open file */ + int iChunk, /* Chunk to generate filename for */ + char *zOut /* Buffer to write generated name to */ +){ + int n = nBase; + memcpy(zOut, zBase, n+1); + if( iChunk!=0 && iChunk!=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ +#ifdef SQLITE_ENABLE_8_3_NAMES + int i; + for(i=n-1; i>0 && i>=n-4 && zOut[i]!='.'; i--){} + if( i>=n-4 ) n = i+1; + if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ + /* The extensions on overflow files for main databases are 001, 002, + ** 003 and so forth. To avoid name collisions, add 400 to the + ** extensions of journal files so that they are 401, 402, 403, .... + */ + iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; } +#endif + sqlite3_snprintf(4,&zOut[n],"%03d",iChunk); + n += 3; } - return rc; + assert( zOut[n]=='\0' ); + zOut[n+1] = '\0'; } /* Compute the filename for the iChunk-th chunk @@ -301,50 +285,71 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ pGroup->aReal = p; pGroup->nReal = iChunk+1; } - if( pGroup->aReal[iChunk].z==0 ){ + if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; - pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+3 ); + pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+5 ); if( z==0 ){ return SQLITE_NOMEM; } - memcpy(z, pGroup->zName, n+1); - if( iChunk>0 ){ -#ifdef SQLITE_ENABLE_8_3_NAMES - if( n>3 && z[n-3]=='.' ){ - n--; - }else if( n>4 && z[n-4]=='.' ){ - n -= 2; - } -#endif - sqlite3_snprintf(3,&z[n],"%02d",iChunk); - } + multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z); } return SQLITE_OK; } /* Translate an sqlite3_file* that is really a multiplexGroup* into ** the sqlite3_file* for the underlying original VFS. +** +** For chunk 0, the pGroup->flags determines whether or not a new file +** is created if it does not already exist. For chunks 1 and higher, the +** file is created only if createFlag is 1. */ static sqlite3_file *multiplexSubOpen( - multiplexGroup *pGroup, - int iChunk, - int *rc, - int *pOutFlags + multiplexGroup *pGroup, /* The multiplexor group */ + int iChunk, /* Which chunk to open. 0==original file */ + int *rc, /* Result code in and out */ + int *pOutFlags, /* Output flags */ + int createFlag /* True to create if iChunk>0 */ ){ sqlite3_file *pSubOpen = 0; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ + +#ifdef SQLITE_ENABLE_8_3_NAMES + /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are + ** part of a database journal are named db.401, db.402, and so on. A + ** database may therefore not grow to larger than 400 chunks. Attempting + ** to open chunk 401 indicates the database is full. */ + if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ + *rc = SQLITE_FULL; + return 0; + } +#endif + *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ + int flags, bExists; + flags = pGroup->flags; + if( createFlag ){ + flags |= SQLITE_OPEN_CREATE; + }else if( iChunk==0 ){ + /* Fall through */ + }else if( pGroup->aReal[iChunk].z==0 ){ + return 0; + }else{ + *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z, + SQLITE_ACCESS_EXISTS, &bExists); + if( *rc || !bExists ) return 0; + flags &= ~SQLITE_OPEN_CREATE; + } pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile ); if( pSubOpen==0 ){ - *rc = SQLITE_NOMEM; + *rc = SQLITE_IOERR_NOMEM; return 0; } pGroup->aReal[iChunk].p = pSubOpen; *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen, - pGroup->flags, pOutFlags); - if( *rc!=SQLITE_OK ){ + flags, pOutFlags); + if( (*rc)!=SQLITE_OK ){ sqlite3_free(pSubOpen); pGroup->aReal[iChunk].p = 0; return 0; @@ -353,6 +358,26 @@ static sqlite3_file *multiplexSubOpen( return pSubOpen; } +/* +** Return the size, in bytes, of chunk number iChunk. If that chunk +** does not exist, then return 0. This function does not distingish between +** non-existant files and zero-length files. +*/ +static sqlite3_int64 multiplexSubSize( + multiplexGroup *pGroup, /* The multiplexor group */ + int iChunk, /* Which chunk to open. 0==original file */ + int *rc /* Result code in and out */ +){ + sqlite3_file *pSub; + sqlite3_int64 sz = 0; + + if( *rc ) return 0; + pSub = multiplexSubOpen(pGroup, iChunk, rc, NULL, 0); + if( pSub==0 ) return 0; + *rc = pSub->pMethods->xFileSize(pSub, &sz); + return sz; +} + /* ** This is the implementation of the multiplex_control() SQL function. */ @@ -420,7 +445,9 @@ static void multiplexSubClose( sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p; if( pSubOpen ){ pSubOpen->pMethods->xClose(pSubOpen); - if( pOrigVfs ) pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + if( pOrigVfs && pGroup->aReal[iChunk].z ){ + pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + } sqlite3_free(pGroup->aReal[iChunk].p); } sqlite3_free(pGroup->aReal[iChunk].z); @@ -466,6 +493,7 @@ static int multiplexOpen( UNUSED_PARAMETER(pVfs); memset(pConn, 0, pVfs->szOsFile); + assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) ); /* We need to create a group structure and manage ** access to this group of files. @@ -473,23 +501,9 @@ static int multiplexOpen( multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; - /* If the second argument to this function is NULL, generate a - ** temporary file name to use. This will be handled by the - ** original xOpen method. We just need to allocate space for - ** it. - */ - if( !zName ){ - zName = zToFree = sqlite3_malloc( pOrigVfs->mxPathname + 10 ); - if( zName==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = multiplexGetTempname(pOrigVfs, pOrigVfs->mxPathname, zToFree); - } - } - if( rc==SQLITE_OK ){ /* allocate space for group */ - nName = multiplexStrlen30(zName); + nName = zName ? multiplexStrlen30(zName) : 0; sz = sizeof(multiplexGroup) /* multiplexGroup */ + nName + 1; /* zName */ pGroup = sqlite3_malloc( sz ); @@ -499,63 +513,90 @@ static int multiplexOpen( } if( rc==SQLITE_OK ){ + const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0; /* assign pointers to extra space allocated */ - char *p = (char *)&pGroup[1]; - pMultiplexOpen->pGroup = pGroup; memset(pGroup, 0, sz); + pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = -1; - pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; - if( flags & SQLITE_OPEN_URI ){ - const char *zChunkSize; - zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); - if( zChunkSize ){ - unsigned int n = 0; - int i; - for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ - n = n*10 + zChunkSize[i] - '0'; - } - if( n>0 ){ - pGroup->szChunk = (n+0xffff)&~0xffff; - }else{ - /* A zero or negative chunksize disabled the multiplexor */ - pGroup->bEnabled = 0; - } + pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate", + (flags & SQLITE_OPEN_MAIN_DB)==0); + pGroup->szChunk = sqlite3_uri_int64(zUri, "chunksize", + SQLITE_MULTIPLEX_CHUNK_SIZE); + pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff; + if( zName ){ + char *p = (char *)&pGroup[1]; + pGroup->zName = p; + memcpy(pGroup->zName, zName, nName+1); + pGroup->nName = nName; + } + if( pGroup->bEnabled ){ + /* Make sure that the chunksize is such that the pending byte does not + ** falls at the end of a chunk. A region of up to 64K following + ** the pending byte is never written, so if the pending byte occurs + ** near the end of a chunk, that chunk will be too small. */ +#ifndef SQLITE_OMIT_WSD + extern int sqlite3PendingByte; +#else + int sqlite3PendingByte = 0x40000000; +#endif + while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){ + pGroup->szChunk += 65536; } } - pGroup->zName = p; - /* save off base filename, name length, and original open flags */ - memcpy(pGroup->zName, zName, nName+1); - pGroup->nName = nName; pGroup->flags = flags; rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ - pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags); + pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0); + if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN; } - if( pSubOpen ){ - int exists, rc2, rc3; + if( rc==SQLITE_OK ){ sqlite3_int64 sz; - rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2==SQLITE_OK ){ - /* If the first overflow file exists and if the size of the main file - ** is different from the chunk size, that means the chunk size is set - ** set incorrectly. So fix it. - ** - ** Or, if the first overflow file does not exist and the main file is - ** larger than the chunk size, that means the chunk size is too small. - ** But we have no way of determining the intended chunk size, so - ** just disable the multiplexor all togethre. - */ - rc3 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, - SQLITE_ACCESS_EXISTS, &exists); - if( rc3==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0 - && sz!=pGroup->szChunk ){ - pGroup->szChunk = sz; - }else if( rc3==SQLITE_OK && !exists && sz>pGroup->szChunk ){ - pGroup->bEnabled = 0; + rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); + if( rc==SQLITE_OK && zName ){ + int bExists; + if( sz==0 ){ + if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ + /* If opening a main journal file and the first chunk is zero + ** bytes in size, delete any subsequent chunks from the + ** file-system. */ + int iChunk = 1; + do { + rc = pOrigVfs->xAccess(pOrigVfs, + pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists + ); + if( rc==SQLITE_OK && bExists ){ + rc = pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + if( rc==SQLITE_OK ){ + rc = multiplexSubFilename(pGroup, ++iChunk); + } + } + }while( rc==SQLITE_OK && bExists ); + } + }else{ + /* If the first overflow file exists and if the size of the main file + ** is different from the chunk size, that means the chunk size is set + ** set incorrectly. So fix it. + ** + ** Or, if the first overflow file does not exist and the main file is + ** larger than the chunk size, that means the chunk size is too small. + ** But we have no way of determining the intended chunk size, so + ** just disable the multiplexor all togethre. + */ + rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, + SQLITE_ACCESS_EXISTS, &bExists); + bExists = multiplexSubSize(pGroup, 1, &rc)>0; + if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0 + && sz!=pGroup->szChunk ){ + pGroup->szChunk = sz; + }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){ + pGroup->bEnabled = 0; + } } } + } + if( rc==SQLITE_OK ){ if( pSubOpen->pMethods->iVersion==1 ){ pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1; }else{ @@ -584,8 +625,33 @@ static int multiplexDelete( const char *zName, /* Name of file to delete */ int syncDir ){ + int rc; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ - return pOrigVfs->xDelete(pOrigVfs, zName, syncDir); + rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir); + if( rc==SQLITE_OK ){ + /* If the main chunk was deleted successfully, also delete any subsequent + ** chunks - starting with the last (highest numbered). + */ + int nName = strlen(zName); + char *z; + z = sqlite3_malloc(nName + 5); + if( z==0 ){ + rc = SQLITE_IOERR_NOMEM; + }else{ + int iChunk = 0; + int bExists; + do{ + multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, ++iChunk, z); + rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists); + }while( rc==SQLITE_OK && bExists ); + while( rc==SQLITE_OK && iChunk>1 ){ + multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, --iChunk, z); + rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir); + } + } + sqlite3_free(z); + } + return rc; } static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){ @@ -662,7 +728,7 @@ static int multiplexRead( int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_READ; }else{ @@ -671,7 +737,7 @@ static int multiplexRead( }else{ while( iAmt > 0 ){ int i = (int)(iOfst / pGroup->szChunk); - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1); if( pSubOpen ){ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; if( extra<0 ) extra = 0; @@ -707,16 +773,16 @@ static int multiplexWrite( int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_WRITE; }else{ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); } }else{ - while( iAmt > 0 ){ + while( rc==SQLITE_OK && iAmt>0 ){ int i = (int)(iOfst / pGroup->szChunk); - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1); if( pSubOpen ){ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; @@ -724,13 +790,9 @@ static int multiplexWrite( iAmt -= extra; rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->szChunk); - if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; iAmt = extra; - }else{ - rc = SQLITE_IOERR_WRITE; - break; } } } @@ -748,28 +810,35 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_TRUNCATE; }else{ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size); } }else{ - int rc2; int i; + int iBaseGroup = (int)(size / pGroup->szChunk); sqlite3_file *pSubOpen; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ /* delete the chunks above the truncate limit */ - for(i=(int)(size / pGroup->szChunk)+1; inReal; i++){ - multiplexSubClose(pGroup, i, pOrigVfs); + for(i = pGroup->nReal-1; i>iBaseGroup && rc==SQLITE_OK; i--){ + if( pGroup->bTruncate ){ + multiplexSubClose(pGroup, i, pOrigVfs); + }else{ + pSubOpen = multiplexSubOpen(pGroup, i, &rc, 0, 0); + if( pSubOpen ){ + rc = pSubOpen->pMethods->xTruncate(pSubOpen, 0); + } + } } - pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->szChunk), &rc2,0); - if( pSubOpen ){ - rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); - if( rc2!=SQLITE_OK ) rc = rc2; - }else{ - rc = SQLITE_IOERR_TRUNCATE; + if( rc==SQLITE_OK ){ + pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0); + if( pSubOpen ){ + rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); + } } + if( rc ) rc = SQLITE_IOERR_TRUNCATE; } multiplexLeave(); return rc; @@ -801,47 +870,21 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ multiplexConn *p = (multiplexConn*)pConn; multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; - int rc2; int i; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_FSTAT; }else{ rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize); } }else{ - sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; *pSize = 0; - for(i=0; 1; i++){ - sqlite3_file *pSubOpen = 0; - int exists = 0; - rc = multiplexSubFilename(pGroup, i); - if( rc ) break; - rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, - SQLITE_ACCESS_EXISTS, &exists); - if( rc2==SQLITE_OK && exists){ - /* if it exists, open it */ - pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); - }else{ - /* stop at first "gap" */ - break; - } - if( pSubOpen ){ - sqlite3_int64 sz; - rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2!=SQLITE_OK ){ - rc = rc2; - }else{ - if( sz>pGroup->szChunk ){ - rc = SQLITE_IOERR_FSTAT; - } - *pSize += sz; - } - }else{ - break; - } + for(i=0; rc==SQLITE_OK; i++){ + sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc); + if( sz==0 ) break; + *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; } } multiplexLeave(); @@ -853,7 +896,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ static int multiplexLock(sqlite3_file *pConn, int lock){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xLock(pSubOpen, lock); } @@ -865,7 +908,7 @@ static int multiplexLock(sqlite3_file *pConn, int lock){ static int multiplexUnlock(sqlite3_file *pConn, int lock){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xUnlock(pSubOpen, lock); } @@ -877,7 +920,7 @@ static int multiplexUnlock(sqlite3_file *pConn, int lock){ static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut); } @@ -925,9 +968,12 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ rc = SQLITE_OK; break; default: - pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg); + } } break; } @@ -939,8 +985,8 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ static int multiplexSectorSize(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); - if( pSubOpen ){ + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); + if( pSubOpen && pSubOpen->pMethods->xSectorSize ){ return pSubOpen->pMethods->xSectorSize(pSubOpen); } return DEFAULT_SECTOR_SIZE; @@ -951,7 +997,7 @@ static int multiplexSectorSize(sqlite3_file *pConn){ static int multiplexDeviceCharacteristics(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xDeviceCharacteristics(pSubOpen); } @@ -969,7 +1015,7 @@ static int multiplexShmMap( ){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmMap(pSubOpen, iRegion, szRegion, bExtend,pp); } @@ -986,7 +1032,7 @@ static int multiplexShmLock( ){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmLock(pSubOpen, ofst, n, flags); } @@ -998,7 +1044,7 @@ static int multiplexShmLock( static void multiplexShmBarrier(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ pSubOpen->pMethods->xShmBarrier(pSubOpen); } @@ -1009,7 +1055,7 @@ static void multiplexShmBarrier(sqlite3_file *pConn){ static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmUnmap(pSubOpen, deleteFlag); } @@ -1191,9 +1237,13 @@ static int test_multiplex_dump( for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ pGroupTerm = Tcl_NewObj(); - pGroup->zName[pGroup->nName] = '\0'; - Tcl_ListObjAppendElement(interp, pGroupTerm, + if( pGroup->zName ){ + pGroup->zName[pGroup->nName] = '\0'; + Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewStringObj(pGroup->zName, -1)); + }else{ + Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj()); + } Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(pGroup->nName)); Tcl_ListObjAppendElement(interp, pGroupTerm, diff --git a/src/test_osinst.c b/src/test_osinst.c index 50d6250..b7f3505 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -389,7 +389,11 @@ static int vfslogCheckReservedLock(sqlite3_file *pFile, int *pResOut){ */ static int vfslogFileControl(sqlite3_file *pFile, int op, void *pArg){ VfslogFile *p = (VfslogFile *)pFile; - return p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + int rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("vfslog/%z", *(char**)pArg); + } + return rc; } /* diff --git a/src/test_pcache.c b/src/test_pcache.c index 98aa136..8fcfe7e 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -100,15 +100,16 @@ static void testpcacheShutdown(void *pArg){ typedef struct testpcache testpcache; struct testpcache { int szPage; /* Size of each page. Multiple of 8. */ + int szExtra; /* Size of extra data that accompanies each page */ int bPurgeable; /* True if the page cache is purgeable */ int nFree; /* Number of unused slots in a[] */ int nPinned; /* Number of pinned slots in a[] */ unsigned iRand; /* State of the PRNG */ unsigned iMagic; /* Magic number for sanity checking */ struct testpcachePage { + sqlite3_pcache_page page; /* Base class */ unsigned key; /* The key for this page. 0 means unallocated */ int isPinned; /* True if the page is pinned */ - void *pData; /* Data for this page */ } a[TESTPCACHE_NPAGE]; /* All pages in the cache */ }; @@ -129,27 +130,33 @@ static unsigned testpcacheRandom(testpcache *p){ /* ** Allocate a new page cache instance. */ -static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){ +static sqlite3_pcache *testpcacheCreate( + int szPage, + int szExtra, + int bPurgeable +){ int nMem; char *x; testpcache *p; int i; assert( testpcacheGlobal.pDummy!=0 ); szPage = (szPage+7)&~7; - nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*szPage; + nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra); p = sqlite3_malloc( nMem ); if( p==0 ) return 0; x = (char*)&p[1]; p->szPage = szPage; + p->szExtra = szExtra; p->nFree = TESTPCACHE_NPAGE; p->nPinned = 0; p->iRand = testpcacheGlobal.prngSeed; p->bPurgeable = bPurgeable; p->iMagic = TESTPCACHE_VALID; - for(i=0; ia[i].key = 0; p->a[i].isPinned = 0; - p->a[i].pData = (void*)x; + p->a[i].page.pBuf = (void*)x; + p->a[i].page.pExtra = (void*)&x[szPage]; } testpcacheGlobal.nInstance++; return (sqlite3_pcache*)p; @@ -161,7 +168,6 @@ static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){ static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){ testpcache *p = (testpcache*)pCache; assert( p->iMagic==TESTPCACHE_VALID ); - assert( newSize>=1 ); assert( testpcacheGlobal.pDummy!=0 ); assert( testpcacheGlobal.nInstance>0 ); } @@ -181,7 +187,7 @@ static int testpcachePagecount(sqlite3_pcache *pCache){ /* ** Fetch a page. */ -static void *testpcacheFetch( +static sqlite3_pcache_page *testpcacheFetch( sqlite3_pcache *pCache, unsigned key, int createFlag @@ -200,7 +206,7 @@ static void *testpcacheFetch( assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); p->a[i].isPinned = 1; } - return p->a[i].pData; + return &p->a[i].page; } } @@ -237,11 +243,12 @@ static void *testpcacheFetch( if( p->a[j].key==0 ){ p->a[j].key = key; p->a[j].isPinned = 1; - memset(p->a[j].pData, 0, p->szPage); + memset(p->a[j].page.pBuf, 0, p->szPage); + memset(p->a[j].page.pExtra, 0, p->szExtra); p->nPinned++; p->nFree--; assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); - return p->a[j].pData; + return &p->a[j].page; } } @@ -263,10 +270,11 @@ static void *testpcacheFetch( if( p->a[j].key>0 && p->a[j].isPinned==0 ){ p->a[j].key = key; p->a[j].isPinned = 1; - memset(p->a[j].pData, 0, p->szPage); + memset(p->a[j].page.pBuf, 0, p->szPage); + memset(p->a[j].page.pExtra, 0, p->szExtra); p->nPinned++; assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); - return p->a[j].pData; + return &p->a[j].page; } } @@ -280,7 +288,7 @@ static void *testpcacheFetch( */ static void testpcacheUnpin( sqlite3_pcache *pCache, - void *pOldPage, + sqlite3_pcache_page *pOldPage, int discard ){ testpcache *p = (testpcache*)pCache; @@ -300,7 +308,7 @@ static void testpcacheUnpin( } for(i=0; ia[i].pData==pOldPage ){ + if( &p->a[i].page==pOldPage ){ /* The pOldPage pointer always points to a pinned page */ assert( p->a[i].isPinned ); p->a[i].isPinned = 0; @@ -325,7 +333,7 @@ static void testpcacheUnpin( */ static void testpcacheRekey( sqlite3_pcache *pCache, - void *pOldPage, + sqlite3_pcache_page *pOldPage, unsigned oldKey, unsigned newKey ){ @@ -354,7 +362,7 @@ static void testpcacheRekey( for(i=0; ia[i].key==oldKey ){ /* The oldKey and pOldPage parameters match */ - assert( p->a[i].pData==pOldPage ); + assert( &p->a[i].page==pOldPage ); /* Page to be rekeyed must be pinned */ assert( p->a[i].isPinned ); p->a[i].key = newKey; @@ -422,7 +430,8 @@ void installTestPCache( unsigned prngSeed, /* Seed for the PRNG */ unsigned highStress /* Call xStress agressively */ ){ - static const sqlite3_pcache_methods testPcache = { + static const sqlite3_pcache_methods2 testPcache = { + 1, (void*)&testpcacheGlobal, testpcacheInit, testpcacheShutdown, @@ -435,7 +444,7 @@ void installTestPCache( testpcacheTruncate, testpcacheDestroy, }; - static sqlite3_pcache_methods defaultPcache; + static sqlite3_pcache_methods2 defaultPcache; static int isInstalled = 0; assert( testpcacheGlobal.nInstance==0 ); @@ -446,12 +455,12 @@ void installTestPCache( testpcacheGlobal.highStress = highStress; if( installFlag!=isInstalled ){ if( installFlag ){ - sqlite3_config(SQLITE_CONFIG_GETPCACHE, &defaultPcache); + sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache); assert( defaultPcache.xCreate!=testpcacheCreate ); - sqlite3_config(SQLITE_CONFIG_PCACHE, &testPcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache); }else{ assert( defaultPcache.xCreate!=0 ); - sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultPcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache); } isInstalled = installFlag; } diff --git a/src/test_quota.c b/src/test_quota.c index 74d1a6d..c8ed738 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -27,7 +27,7 @@ ** files within the group is less than the new quota, then the write ** continues as if nothing had happened. */ -#include "sqlite3.h" +#include "test_quota.h" #include #include @@ -111,6 +111,18 @@ struct quotaConn { /* The underlying VFS sqlite3_file is appended to this object */ }; +/* +** An instance of the following object records the state of an +** open file. This object is opaque to all users - the internal +** structure is only visible to the functions below. +*/ +struct quota_FILE { + FILE *f; /* Open stdio file pointer */ + sqlite3_int64 iOfst; /* Current offset into the file */ + quotaFile *pFile; /* The file record in the quota system */ +}; + + /************************* Global Variables **********************************/ /* ** All global variables used by this file are containing within the following @@ -225,9 +237,11 @@ static void quotaGroupDeref(quotaGroup *pGroup){ ** ** [^...] Matches one character not in the enclosed list. ** +** / Matches "/" or "\\" +** */ static int quotaStrglob(const char *zGlob, const char *z){ - int c, c2; + int c, c2, cx; int invert; int seen; @@ -244,8 +258,9 @@ static int quotaStrglob(const char *zGlob, const char *z){ } return (*z)!=0; } + cx = (c=='/') ? '\\' : c; while( (c2 = (*(z++)))!=0 ){ - while( c2!=c ){ + while( c2!=c && c2!=cx ){ c2 = *(z++); if( c2==0 ) return 0; } @@ -283,6 +298,9 @@ static int quotaStrglob(const char *zGlob, const char *z){ c2 = *(zGlob++); } if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='/' ){ + if( z[0]!='/' && z[0]!='\\' ) return 0; + z++; }else{ if( c!=(*(z++)) ) return 0; } @@ -313,14 +331,131 @@ static sqlite3_file *quotaSubOpen(sqlite3_file *pConn){ /* Find a file in a quota group and return a pointer to that file. ** Return NULL if the file is not in the group. */ -static quotaFile *quotaFindFile(quotaGroup *pGroup, const char *zName){ +static quotaFile *quotaFindFile( + quotaGroup *pGroup, /* Group in which to look for the file */ + const char *zName, /* Full pathname of the file */ + int createFlag /* Try to create the file if not found */ +){ quotaFile *pFile = pGroup->pFiles; while( pFile && strcmp(pFile->zFilename, zName)!=0 ){ pFile = pFile->pNext; } + if( pFile==0 && createFlag ){ + int nName = strlen(zName); + pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 ); + if( pFile ){ + memset(pFile, 0, sizeof(*pFile)); + pFile->zFilename = (char*)&pFile[1]; + memcpy(pFile->zFilename, zName, nName+1); + pFile->pNext = pGroup->pFiles; + if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext; + pFile->ppPrev = &pGroup->pFiles; + pGroup->pFiles = pFile; + pFile->pGroup = pGroup; + } + } return pFile; } +/* +** Figure out if we are dealing with Unix, Windows, or some other +** operating system. After the following block of preprocess macros, +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** will defined to either 1 or 0. One of the four will be 1. The other +** three will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# undef SQLITE_OS_OS2 +# define SQLITE_OS_OS2 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \ + || defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \ + || defined(_OS2_) || defined(__OS2__) +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 1 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# define SQLITE_OS_OS2 0 +# endif +# else +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +#if SQLITE_OS_UNIX +# include +#endif +#if SQLITE_OS_WIN +# include +# include +#endif + +/* +** Translate UTF8 to MBCS for use in fopen() calls. Return a pointer to the +** translated text.. Call quota_mbcs_free() to deallocate any memory +** used to store the returned pointer when done. +*/ +static char *quota_utf8_to_mbcs(const char *zUtf8){ +#if SQLITE_OS_WIN + int n; /* Bytes in zUtf8 */ + int nWide; /* number of UTF-16 characters */ + int nMbcs; /* Bytes of MBCS */ + LPWSTR zTmpWide; /* The UTF16 text */ + char *zMbcs; /* The MBCS text */ + int codepage; /* Code page used by fopen() */ + + n = strlen(zUtf8); + nWide = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); + if( nWide==0 ) return 0; + zTmpWide = (LPWSTR)sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) ); + if( zTmpWide==0 ) return 0; + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide); + codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0); + zMbcs = nMbcs ? (char*)sqlite3_malloc( nMbcs+1 ) : 0; + if( zMbcs ){ + WideCharToMultiByte(codepage, 0, zTmpWide, nWide, zMbcs, nMbcs, 0, 0); + } + sqlite3_free(zTmpWide); + return zMbcs; +#else + return (char*)zUtf8; /* No-op on unix */ +#endif +} + +/* +** Deallocate any memory allocated by quota_utf8_to_mbcs(). +*/ +static void quota_mbcs_free(char *zOld){ +#if SQLITE_OS_WIN + sqlite3_free(zOld); +#else + /* No-op on unix */ +#endif +} + /************************* VFS Method Wrappers *****************************/ /* ** This is the xOpen method used for the "quota" VFS. @@ -364,25 +499,13 @@ static int quotaOpen( pSubOpen = quotaSubOpen(pConn); rc = pOrigVfs->xOpen(pOrigVfs, zName, pSubOpen, flags, pOutFlags); if( rc==SQLITE_OK ){ - pFile = quotaFindFile(pGroup, zName); + pFile = quotaFindFile(pGroup, zName, 1); if( pFile==0 ){ - int nName = strlen(zName); - pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 ); - if( pFile==0 ){ - quotaLeave(); - pSubOpen->pMethods->xClose(pSubOpen); - return SQLITE_NOMEM; - } - memset(pFile, 0, sizeof(*pFile)); - pFile->zFilename = (char*)&pFile[1]; - memcpy(pFile->zFilename, zName, nName+1); - pFile->pNext = pGroup->pFiles; - if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext; - pFile->ppPrev = &pGroup->pFiles; - pGroup->pFiles = pFile; - pFile->pGroup = pGroup; - pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0; + quotaLeave(); + pSubOpen->pMethods->xClose(pSubOpen); + return SQLITE_NOMEM; } + pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0; pFile->nRef++; pQuotaOpen->pFile = pFile; if( pSubOpen->pMethods->iVersion==1 ){ @@ -423,7 +546,7 @@ static int quotaDelete( quotaEnter(); pGroup = quotaGroupFind(zName); if( pGroup ){ - pFile = quotaFindFile(pGroup, zName); + pFile = quotaFindFile(pGroup, zName, 0); if( pFile ){ if( pFile->nRef ){ pFile->deleteOnClose = 1; @@ -455,7 +578,10 @@ static int quotaClose(sqlite3_file *pConn){ pFile->nRef--; if( pFile->nRef==0 ){ quotaGroup *pGroup = pFile->pGroup; - if( pFile->deleteOnClose ) quotaRemoveFile(pFile); + if( pFile->deleteOnClose ){ + gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + } quotaGroupDeref(pGroup); } quotaLeave(); @@ -589,7 +715,13 @@ static int quotaCheckReservedLock(sqlite3_file *pConn, int *pResOut){ */ static int quotaFileControl(sqlite3_file *pConn, int op, void *pArg){ sqlite3_file *pSubOpen = quotaSubOpen(pConn); - return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + int rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); +#if defined(SQLITE_FCNTL_VFSNAME) + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("quota/%z", *(char**)pArg); + } +#endif + return rc; } /* Pass xSectorSize requests through to the original VFS unchanged. @@ -805,33 +937,256 @@ int sqlite3_quota_file(const char *zFilename){ int rc; int outFlags = 0; sqlite3_int64 iSize; - fd = sqlite3_malloc(gQuota.sThisVfs.szOsFile + gQuota.sThisVfs.mxPathname+1); - if( fd==0 ) return SQLITE_NOMEM; - zFull = gQuota.sThisVfs.szOsFile + (char*)fd; - rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, - gQuota.sThisVfs.mxPathname+1, zFull); + int nAlloc = gQuota.sThisVfs.szOsFile + gQuota.sThisVfs.mxPathname+2; + + /* Allocate space for a file-handle and the full path for file zFilename */ + fd = (sqlite3_file *)sqlite3_malloc(nAlloc); + if( fd==0 ){ + rc = SQLITE_NOMEM; + }else{ + zFull = &((char *)fd)[gQuota.sThisVfs.szOsFile]; + rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, + gQuota.sThisVfs.mxPathname+1, zFull); + } + if( rc==SQLITE_OK ){ + zFull[strlen(zFull)+1] = '\0'; rc = quotaOpen(&gQuota.sThisVfs, zFull, fd, SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB, &outFlags); - } - if( rc==SQLITE_OK ){ - fd->pMethods->xFileSize(fd, &iSize); - fd->pMethods->xClose(fd); - }else if( rc==SQLITE_CANTOPEN ){ - quotaGroup *pGroup; - quotaFile *pFile; - quotaEnter(); - pGroup = quotaGroupFind(zFull); - if( pGroup ){ - pFile = quotaFindFile(pGroup, zFull); - if( pFile ) quotaRemoveFile(pFile); + if( rc==SQLITE_OK ){ + fd->pMethods->xFileSize(fd, &iSize); + fd->pMethods->xClose(fd); + }else if( rc==SQLITE_CANTOPEN ){ + quotaGroup *pGroup; + quotaFile *pFile; + quotaEnter(); + pGroup = quotaGroupFind(zFull); + if( pGroup ){ + pFile = quotaFindFile(pGroup, zFull, 0); + if( pFile ) quotaRemoveFile(pFile); + } + quotaLeave(); } - quotaLeave(); } + sqlite3_free(fd); return rc; } +/* +** Open a potentially quotaed file for I/O. +*/ +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){ + quota_FILE *p = 0; + char *zFull = 0; + char *zFullTranslated; + int rc; + quotaGroup *pGroup; + quotaFile *pFile; + + zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + if( zFull==0 ) return 0; + rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, + gQuota.sThisVfs.mxPathname+1, zFull); + if( rc ) goto quota_fopen_error; + p = (quota_FILE*)sqlite3_malloc(sizeof(*p)); + if( p==0 ) goto quota_fopen_error; + memset(p, 0, sizeof(*p)); + zFullTranslated = quota_utf8_to_mbcs(zFull); + if( zFullTranslated==0 ) goto quota_fopen_error; + p->f = fopen(zFullTranslated, zMode); + quota_mbcs_free(zFullTranslated); + if( p->f==0 ) goto quota_fopen_error; + quotaEnter(); + pGroup = quotaGroupFind(zFull); + if( pGroup ){ + pFile = quotaFindFile(pGroup, zFull, 1); + if( pFile==0 ){ + quotaLeave(); + goto quota_fopen_error; + } + pFile->nRef++; + p->pFile = pFile; + } + quotaLeave(); + sqlite3_free(zFull); + return p; + +quota_fopen_error: + sqlite3_free(zFull); + if( p && p->f ) fclose(p->f); + sqlite3_free(p); + return 0; +} + +/* +** Read content from a quota_FILE +*/ +size_t sqlite3_quota_fread( + void *pBuf, /* Store the content here */ + size_t size, /* Size of each element */ + size_t nmemb, /* Number of elements to read */ + quota_FILE *p /* Read from this quota_FILE object */ +){ + return fread(pBuf, size, nmemb, p->f); +} + +/* +** Write content into a quota_FILE. Invoke the quota callback and block +** the write if we exceed quota. +*/ +size_t sqlite3_quota_fwrite( + void *pBuf, /* Take content to write from here */ + size_t size, /* Size of each element */ + size_t nmemb, /* Number of elements */ + quota_FILE *p /* Write to this quota_FILE objecct */ +){ + sqlite3_int64 iOfst; + sqlite3_int64 iEnd; + sqlite3_int64 szNew; + quotaFile *pFile; + + iOfst = ftell(p->f); + iEnd = iOfst + size*nmemb; + pFile = p->pFile; + if( pFile && pFile->iSizepGroup; + quotaEnter(); + szNew = pGroup->iSize - pFile->iSize + iEnd; + if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ + if( pGroup->xCallback ){ + pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, + pGroup->pArg); + } + if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ + iEnd = pGroup->iLimit - pGroup->iSize + pFile->iSize; + nmemb = (iEnd - iOfst)/size; + iEnd = iOfst + size*nmemb; + szNew = pGroup->iSize - pFile->iSize + iEnd; + } + } + pGroup->iSize = szNew; + pFile->iSize = iEnd; + quotaLeave(); + } + return fwrite(pBuf, size, nmemb, p->f); +} + +/* +** Close an open quota_FILE stream. +*/ +int sqlite3_quota_fclose(quota_FILE *p){ + int rc; + quotaFile *pFile; + rc = fclose(p->f); + pFile = p->pFile; + if( pFile ){ + quotaEnter(); + pFile->nRef--; + if( pFile->nRef==0 ){ + quotaGroup *pGroup = pFile->pGroup; + if( pFile->deleteOnClose ){ + gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + } + quotaGroupDeref(pGroup); + } + quotaLeave(); + } + sqlite3_free(p); + return rc; +} + +/* +** Flush memory buffers for a quota_FILE to disk. +*/ +int sqlite3_quota_fflush(quota_FILE *p, int doFsync){ + int rc; + rc = fflush(p->f); + if( rc==0 && doFsync ){ +#if SQLITE_OS_UNIX + rc = fsync(fileno(p->f)); +#endif +#if SQLITE_OS_WIN + rc = _commit(_fileno(p->f)); +#endif + } + return rc!=0; +} + +/* +** Seek on a quota_FILE stream. +*/ +int sqlite3_quota_fseek(quota_FILE *p, long offset, int whence){ + return fseek(p->f, offset, whence); +} + +/* +** rewind a quota_FILE stream. +*/ +void sqlite3_quota_rewind(quota_FILE *p){ + rewind(p->f); +} + +/* +** Tell the current location of a quota_FILE stream. +*/ +long sqlite3_quota_ftell(quota_FILE *p){ + return ftell(p->f); +} + +/* +** Remove a managed file. Update quotas accordingly. +*/ +int sqlite3_quota_remove(const char *zFilename){ + char *zFull; /* Full pathname for zFilename */ + int nFull; /* Number of bytes in zFilename */ + int rc; /* Result code */ + quotaGroup *pGroup; /* Group containing zFilename */ + quotaFile *pFile; /* A file in the group */ + quotaFile *pNextFile; /* next file in the group */ + int diff; /* Difference between filenames */ + char c; /* First character past end of pattern */ + + zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + if( zFull==0 ) return SQLITE_NOMEM; + rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, + gQuota.sThisVfs.mxPathname+1, zFull); + if( rc ){ + sqlite3_free(zFull); + return rc; + } + + /* Figure out the length of the full pathname. If the name ends with + ** / (or \ on windows) then remove the trailing /. + */ + nFull = strlen(zFull); + if( nFull>0 && (zFull[nFull-1]=='/' || zFull[nFull-1]=='\\') ){ + nFull--; + zFull[nFull] = 0; + } + + quotaEnter(); + pGroup = quotaGroupFind(zFull); + if( pGroup ){ + for(pFile=pGroup->pFiles; pFile && rc==SQLITE_OK; pFile=pNextFile){ + pNextFile = pFile->pNext; + diff = memcmp(zFull, pFile->zFilename, nFull); + if( diff==0 && ((c = pFile->zFilename[nFull])==0 || c=='/' || c=='\\') ){ + if( pFile->nRef ){ + pFile->deleteOnClose = 1; + }else{ + rc = gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + quotaGroupDeref(pGroup); + } + } + } + } + quotaLeave(); + sqlite3_free(zFull); + return rc; +} /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST @@ -1060,9 +1415,13 @@ static int test_quota_dump( Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewWideIntObj(pGroup->iSize)); for(pFile=pGroup->pFiles; pFile; pFile=pFile->pNext){ + int i; + char zTemp[1000]; pFileTerm = Tcl_NewObj(); + sqlite3_snprintf(sizeof(zTemp), zTemp, "%s", pFile->zFilename); + for(i=0; zTemp[i]; i++){ if( zTemp[i]=='\\' ) zTemp[i] = '/'; } Tcl_ListObjAppendElement(interp, pFileTerm, - Tcl_NewStringObj(pFile->zFilename, -1)); + Tcl_NewStringObj(zTemp, -1)); Tcl_ListObjAppendElement(interp, pFileTerm, Tcl_NewWideIntObj(pFile->iSize)); Tcl_ListObjAppendElement(interp, pFileTerm, @@ -1078,6 +1437,272 @@ static int test_quota_dump( return TCL_OK; } +/* +** tclcmd: sqlite3_quota_fopen FILENAME MODE +*/ +static int test_quota_fopen( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zFilename; /* File pattern to configure */ + const char *zMode; /* Mode string */ + quota_FILE *p; /* Open string object */ + char zReturn[50]; /* Name of pointer to return */ + + /* Process arguments */ + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME MODE"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + zMode = Tcl_GetString(objv[2]); + p = sqlite3_quota_fopen(zFilename, zMode); + sqlite3_snprintf(sizeof(zReturn), zReturn, "%p", p); + Tcl_SetResult(interp, zReturn, TCL_VOLATILE); + return TCL_OK; +} + +/* Defined in test1.c */ +extern void *sqlite3TestTextToPtr(const char*); + +/* +** tclcmd: sqlite3_quota_fread HANDLE SIZE NELEM +*/ +static int test_quota_fread( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + char *zBuf; + int sz; + int nElem; + int got; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR; + zBuf = (char*)sqlite3_malloc( sz*nElem + 1 ); + if( zBuf==0 ){ + Tcl_SetResult(interp, "out of memory", TCL_STATIC); + return TCL_ERROR; + } + got = sqlite3_quota_fread(zBuf, sz, nElem, p); + if( got<0 ) got = 0; + zBuf[got*sz] = 0; + Tcl_SetResult(interp, zBuf, TCL_VOLATILE); + sqlite3_free(zBuf); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fwrite HANDLE SIZE NELEM CONTENT +*/ +static int test_quota_fwrite( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + char *zBuf; + int sz; + int nElem; + int got; + + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM CONTENT"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR; + zBuf = Tcl_GetString(objv[4]); + got = sqlite3_quota_fwrite(zBuf, sz, nElem, p); + Tcl_SetObjResult(interp, Tcl_NewIntObj(got)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fclose HANDLE +*/ +static int test_quota_fclose( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + rc = sqlite3_quota_fclose(p); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fflush HANDLE ?HARDSYNC? +*/ +static int test_quota_fflush( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int rc; + int doSync = 0; + + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?HARDSYNC?"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( objc==3 ){ + if( Tcl_GetBooleanFromObj(interp, objv[2], &doSync) ) return TCL_ERROR; + } + rc = sqlite3_quota_fflush(p, doSync); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fseek HANDLE OFFSET WHENCE +*/ +static int test_quota_fseek( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int ofst; + const char *zWhence; + int whence; + int rc; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET WHENCE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &ofst) ) return TCL_ERROR; + zWhence = Tcl_GetString(objv[3]); + if( strcmp(zWhence, "SEEK_SET")==0 ){ + whence = SEEK_SET; + }else if( strcmp(zWhence, "SEEK_CUR")==0 ){ + whence = SEEK_CUR; + }else if( strcmp(zWhence, "SEEK_END")==0 ){ + whence = SEEK_END; + }else{ + Tcl_AppendResult(interp, + "WHENCE should be SEEK_SET, SEEK_CUR, or SEEK_END", (char*)0); + return TCL_ERROR; + } + rc = sqlite3_quota_fseek(p, ofst, whence); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_rewind HANDLE +*/ +static int test_quota_rewind( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + sqlite3_quota_rewind(p); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_ftell HANDLE +*/ +static int test_quota_ftell( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + sqlite3_int64 x; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + x = sqlite3_quota_ftell(p); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_remove FILENAME +*/ +static int test_quota_remove( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zFilename; /* File pattern to configure */ + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + rc = sqlite3_quota_remove(zFilename); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_glob PATTERN TEXT +** +** Test the glob pattern matching. Return 1 if TEXT matches PATTERN +** and return 0 if it does not. +*/ +static int test_quota_glob( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zPattern; /* The glob pattern */ + const char *zText; /* Text to compare agains the pattern */ + int rc; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT"); + return TCL_ERROR; + } + zPattern = Tcl_GetString(objv[1]); + zText = Tcl_GetString(objv[2]); + rc = quotaStrglob(zPattern, zText); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + /* ** This routine registers the custom TCL commands defined in this ** module. This should be the only procedure visible from outside @@ -1089,10 +1714,20 @@ int Sqlitequota_Init(Tcl_Interp *interp){ Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_quota_initialize", test_quota_initialize }, - { "sqlite3_quota_shutdown", test_quota_shutdown }, - { "sqlite3_quota_set", test_quota_set }, - { "sqlite3_quota_file", test_quota_file }, - { "sqlite3_quota_dump", test_quota_dump }, + { "sqlite3_quota_shutdown", test_quota_shutdown }, + { "sqlite3_quota_set", test_quota_set }, + { "sqlite3_quota_file", test_quota_file }, + { "sqlite3_quota_dump", test_quota_dump }, + { "sqlite3_quota_fopen", test_quota_fopen }, + { "sqlite3_quota_fread", test_quota_fread }, + { "sqlite3_quota_fwrite", test_quota_fwrite }, + { "sqlite3_quota_fclose", test_quota_fclose }, + { "sqlite3_quota_fflush", test_quota_fflush }, + { "sqlite3_quota_fseek", test_quota_fseek }, + { "sqlite3_quota_rewind", test_quota_rewind }, + { "sqlite3_quota_ftell", test_quota_ftell }, + { "sqlite3_quota_remove", test_quota_remove }, + { "sqlite3_quota_glob", test_quota_glob }, }; int i; diff --git a/src/test_quota.h b/src/test_quota.h new file mode 100644 index 0000000..a2fddbb --- /dev/null +++ b/src/test_quota.h @@ -0,0 +1,209 @@ +/* +** 2011 December 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the interface definition for the quota a VFS shim. +** +** This particular shim enforces a quota system on files. One or more +** database files are in a "quota group" that is defined by a GLOB +** pattern. A quota is set for the combined size of all files in the +** the group. A quota of zero means "no limit". If the total size +** of all files in the quota group is greater than the limit, then +** write requests that attempt to enlarge a file fail with SQLITE_FULL. +** +** However, before returning SQLITE_FULL, the write requests invoke +** a callback function that is configurable for each quota group. +** This callback has the opportunity to enlarge the quota. If the +** callback does enlarge the quota such that the total size of all +** files within the group is less than the new quota, then the write +** continues as if nothing had happened. +*/ +#ifndef _QUOTA_H_ +#include "sqlite3.h" +#include + +/* Make this callable from C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Initialize the quota VFS shim. Use the VFS named zOrigVfsName +** as the VFS that does the actual work. Use the default if +** zOrigVfsName==NULL. +** +** The quota VFS shim is named "quota". It will become the default +** VFS if makeDefault is non-zero. +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once +** during start-up. +*/ +int sqlite3_quota_initialize(const char *zOrigVfsName, int makeDefault); + +/* +** Shutdown the quota system. +** +** All SQLite database connections must be closed before calling this +** routine. +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while +** shutting down in order to free all remaining quota groups. +*/ +int sqlite3_quota_shutdown(void); + +/* +** Create or destroy a quota group. +** +** The quota group is defined by the zPattern. When calling this routine +** with a zPattern for a quota group that already exists, this routine +** merely updates the iLimit, xCallback, and pArg values for that quota +** group. If zPattern is new, then a new quota group is created. +** +** The zPattern is always compared against the full pathname of the file. +** Even if APIs are called with relative pathnames, SQLite converts the +** name to a full pathname before comparing it against zPattern. zPattern +** is a glob pattern with the following matching rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. "]" can be part of the list if it is +** the first character. Within the list "X-Y" matches +** characters X or Y or any character in between the +** two. Ex: "[0-9]" matches any digit. +** +** [^...] Matches one character not in the enclosed list. +** +** / Matches either / or \. This allows glob patterns +** containing / to work on both unix and windows. +** +** Note that, unlike unix shell globbing, the directory separator "/" +** can match a wildcard. So, for example, the pattern "/abc/xyz/" "*" +** matches any files anywhere in the directory hierarchy beneath +** /abc/xyz. +** +** The glob algorithm works on bytes. Multi-byte UTF8 characters are +** matched as if each byte were a separate character. +** +** If the iLimit for a quota group is set to zero, then the quota group +** is disabled and will be deleted when the last database connection using +** the quota group is closed. +** +** Calling this routine on a zPattern that does not exist and with a +** zero iLimit is a no-op. +** +** A quota group must exist with a non-zero iLimit prior to opening +** database connections if those connections are to participate in the +** quota group. Creating a quota group does not affect database connections +** that are already open. +** +** The patterns that define the various quota groups should be distinct. +** If the same filename matches more than one quota group pattern, then +** the behavior of this package is undefined. +*/ +int sqlite3_quota_set( + const char *zPattern, /* The filename pattern */ + sqlite3_int64 iLimit, /* New quota to set for this quota group */ + void (*xCallback)( /* Callback invoked when going over quota */ + const char *zFilename, /* Name of file whose size increases */ + sqlite3_int64 *piLimit, /* IN/OUT: The current limit */ + sqlite3_int64 iSize, /* Total size of all files in the group */ + void *pArg /* Client data */ + ), + void *pArg, /* client data passed thru to callback */ + void (*xDestroy)(void*) /* Optional destructor for pArg */ +); + +/* +** Bring the named file under quota management, assuming its name matches +** the glob pattern of some quota group. Or if it is already under +** management, update its size. If zFilename does not match the glob +** pattern of any quota group, this routine is a no-op. +*/ +int sqlite3_quota_file(const char *zFilename); + +/* +** The following object serves the same role as FILE in the standard C +** library. It represents an open connection to a file on disk for I/O. +** +** A single quota_FILE should not be used by two or more threads at the +** same time. Multiple threads can be using different quota_FILE objects +** simultaneously, but not the same quota_FILE object. +*/ +typedef struct quota_FILE quota_FILE; + +/* +** Create a new quota_FILE object used to read and/or write to the +** file zFilename. The zMode parameter is as with standard library zMode. +*/ +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode); + +/* +** Perform I/O against a quota_FILE object. When doing writes, the +** quota mechanism may result in a short write, in order to prevent +** the sum of sizes of all files from going over quota. +*/ +size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*); +size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*); + +/* +** Flush all written content held in memory buffers out to disk. +** This is the equivalent of fflush() in the standard library. +** +** If the hardSync parameter is true (non-zero) then this routine +** also forces OS buffers to disk - the equivalent of fsync(). +** +** This routine return zero on success and non-zero if something goes +** wrong. +*/ +int sqlite3_quota_fflush(quota_FILE*, int hardSync); + +/* +** Close a quota_FILE object and free all associated resources. The +** file remains under quota management. +*/ +int sqlite3_quota_fclose(quota_FILE*); + +/* +** Move the read/write pointer for a quota_FILE object. Or tell the +** current location of the read/write pointer. +*/ +int sqlite3_quota_fseek(quota_FILE*, long, int); +void sqlite3_quota_rewind(quota_FILE*); +long sqlite3_quota_ftell(quota_FILE*); + +/* +** Delete a file from the disk, if that file is under quota management. +** Adjust quotas accordingly. +** +** If zFilename is the name of a directory that matches one of the +** quota glob patterns, then all files under quota management that +** are contained within that directory are deleted. +** +** A standard SQLite result code is returned (SQLITE_OK, SQLITE_NOMEM, etc.) +** When deleting a directory of files, if the deletion of any one +** file fails (for example due to an I/O error), then this routine +** returns immediately, with the error code, and does not try to +** delete any of the other files in the specified directory. +** +** All files are removed from quota management and deleted from disk. +** However, no attempt is made to remove empty directories. +** +** This routine is a no-op for files that are not under quota management. +*/ +int sqlite3_quota_remove(const char *zFilename); + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif +#endif /* _QUOTA_H_ */ diff --git a/src/test_stat.c b/src/test_stat.c index ef81769..a0893b3 100644 --- a/src/test_stat.c +++ b/src/test_stat.c @@ -369,7 +369,7 @@ static void statSizeAndOffset(StatCursor *pCsr){ /* The default page size and offset */ pCsr->szPage = sqlite3BtreeGetPageSize(pBt); - pCsr->iOffset = pCsr->szPage * (pCsr->iPageno - 1); + pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); /* If connected to a ZIPVFS backend, override the page size and ** offset with actual values obtained from ZIPVFS. diff --git a/src/test_vfs.c b/src/test_vfs.c index 546cb7c..a79407b 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -988,7 +988,7 @@ static int testvfs_obj_cmd( switch( aSubcmd[i].eCmd ){ case CMD_SHM: { Tcl_Obj *pObj; - int i; + int i, rc; TestvfsBuffer *pBuffer; char *zName; if( objc!=3 && objc!=4 ){ @@ -996,10 +996,16 @@ static int testvfs_obj_cmd( return TCL_ERROR; } zName = ckalloc(p->pParent->mxPathname); - p->pParent->xFullPathname( + rc = p->pParent->xFullPathname( p->pParent, Tcl_GetString(objv[2]), p->pParent->mxPathname, zName ); + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, "failed to get full path: ", + Tcl_GetString(objv[2]), 0); + ckfree(zName); + return TCL_ERROR; + } for(pBuffer=p->pBuffer; pBuffer; pBuffer=pBuffer->pNext){ if( 0==strcmp(pBuffer->zFile, zName) ) break; } @@ -1156,18 +1162,19 @@ static int testvfs_obj_cmd( int iValue; } aFlag[] = { { "default", -1 }, - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; Tcl_Obj *pRet; @@ -1201,7 +1208,7 @@ static int testvfs_obj_cmd( iNew |= aFlag[idx].iValue; } - p->iDevchar = iNew; + p->iDevchar = iNew| 0x10000000; } pRet = Tcl_NewObj(); diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index 5e94f5c..6257720 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -471,6 +471,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ } case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break; + case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; + case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; + case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; + case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break; default: { sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); @@ -482,6 +486,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ pInfo->zVfsName, p->zFName, zOp); rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); vfstrace_print_errcode(pInfo, " -> %s\n", rc); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", + pInfo->zVfsName, *(char**)pArg); + } return rc; } diff --git a/src/tokenize.c b/src/tokenize.c index b329892..faea5f2 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -123,7 +123,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ } case '-': { if( z[1]=='-' ){ - /* IMP: R-15891-05542 -- syntax diagram for comments */ + /* IMP: R-50417-27976 -- syntax diagram for comments */ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; @@ -156,7 +156,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_SLASH; return 1; } - /* IMP: R-15891-05542 -- syntax diagram for comments */ + /* IMP: R-50417-27976 -- syntax diagram for comments */ for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} if( c ) i++; *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ diff --git a/src/trigger.c b/src/trigger.c index 22c4877..3c4bf62 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -904,6 +904,7 @@ static TriggerPrg *codeRowTrigger( } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; + pProgram->nOnce = pSubParse->nOnce; pProgram->token = (void *)pTrigger; pPrg->aColmask[0] = pSubParse->oldmask; pPrg->aColmask[1] = pSubParse->newmask; diff --git a/src/update.c b/src/update.c index 1e30522..73d2269 100644 --- a/src/update.c +++ b/src/update.c @@ -126,8 +126,8 @@ void sqlite3Update( int regRowCount = 0; /* A count of rows changed */ int regOldRowid; /* The old rowid */ int regNewRowid; /* The new rowid */ - int regNew; - int regOld = 0; + int regNew; /* Content of the NEW.* table in triggers */ + int regOld = 0; /* Content of OLD.* table in triggers */ int regRowSet = 0; /* Rowset of rows to be updated */ memset(&sContext, 0, sizeof(sContext)); @@ -276,6 +276,7 @@ void sqlite3Update( #endif /* Allocate required registers. */ + regRowSet = ++pParse->nMem; regOldRowid = regNewRowid = ++pParse->nMem; if( pTrigger || hasFK ){ regOld = pParse->nMem + 1; @@ -310,7 +311,7 @@ void sqlite3Update( /* Begin the database scan */ - sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); pWInfo = sqlite3WhereBegin( pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED ); @@ -321,7 +322,6 @@ void sqlite3Update( */ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid); if( !okOnePass ){ - regRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); } @@ -425,9 +425,10 @@ void sqlite3Update( newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); + sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1); for(i=0; inCol; i++){ if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/ }else{ j = aXRef[i]; if( j>=0 ){ diff --git a/src/util.c b/src/util.c index 3356417..fd3c858 100644 --- a/src/util.c +++ b/src/util.c @@ -1169,18 +1169,17 @@ int sqlite3AbsInt32(int x){ ** test.db-journal => test.nal ** test.db-wal => test.wal ** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa */ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ #if SQLITE_ENABLE_8_3_NAMES<2 - const char *zOk; - zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names"); - if( zOk && sqlite3GetBoolean(zOk) ) + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) #endif { int i, sz; sz = sqlite3Strlen30(z); for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4); + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); } } #endif diff --git a/src/vdbe.c b/src/vdbe.c index 22e6d9c..52e904d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -52,7 +52,7 @@ ** not misused. */ #ifdef SQLITE_DEBUG -# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M) +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) #else # define memAboutToChange(P,M) #endif @@ -70,8 +70,8 @@ int sqlite3_search_count = 0; /* ** When this global variable is positive, it gets decremented once before -** each instruction in the VDBE. When reaches zero, the u1.isInterrupted -** field of the sqlite3 structure is set in order to simulate and interrupt. +** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate an interrupt. ** ** This facility is used for testing purposes only. It does not function ** in an ordinary build. @@ -151,12 +151,6 @@ int sqlite3_found_count = 0; if( ((P)->flags&MEM_Ephem)!=0 \ && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} -/* -** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) -** P if required. -*/ -#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) - /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ #ifdef SQLITE_OMIT_MERGE_SORT # define isSorter(x) 0 @@ -196,7 +190,7 @@ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ - int iDb, /* When database the cursor belongs to, or -1 */ + int iDb, /* Database the cursor belongs to, or -1 */ int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory @@ -478,7 +472,7 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ ** ** This macro added to every instruction that does a jump in order to ** implement a loop. This test used to be on every single instruction, -** but that meant we more testing that we needed. By only testing the +** but that meant we more testing than we needed. By only testing the ** flag on jump instructions, we get a (small) speed improvement. */ #define CHECK_FOR_INTERRUPT \ @@ -673,7 +667,7 @@ int sqlite3VdbeExec( assert( pOp->p2<=p->nMem ); pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); - MemReleaseExt(pOut); + VdbeMemRelease(pOut); pOut->flags = MEM_Int; } @@ -764,7 +758,8 @@ case OP_Goto: { /* jump */ ** Write the current address onto register P1 ** and then jump to address P2. */ -case OP_Gosub: { /* jump, in1 */ +case OP_Gosub: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=p->nMem ); pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); memAboutToChange(p, pIn1); @@ -961,12 +956,25 @@ case OP_String: { /* out2-prerelease */ break; } -/* Opcode: Null * P2 * * * +/* Opcode: Null * P2 P3 * * ** -** Write a NULL into register P2. +** Write a NULL into registers P2. If P3 greater than P2, then also write +** NULL into register P3 and ever register in between P2 and P3. If P3 +** is less than P2 (typically P3 is zero) then only register P2 is +** set to NULL */ case OP_Null: { /* out2-prerelease */ + int cnt; + cnt = pOp->p3-pOp->p2; + assert( pOp->p3<=p->nMem ); pOut->flags = MEM_Null; + while( cnt>0 ){ + pOut++; + memAboutToChange(p, pOut); + VdbeMemRelease(pOut); + pOut->flags = MEM_Null; + cnt--; + } break; } @@ -1138,7 +1146,7 @@ case OP_ResultRow: { /* Make sure the results of the current row are \000 terminated ** and have an assigned type. The results are de-ephemeralized as - ** as side effect. + ** a side effect. */ pMem = p->pResultSet = &aMem[pOp->p1]; for(i=0; ip2; i++){ @@ -2023,27 +2031,33 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** -** Jump to P2 if the value in register P1 is a not null or zero. If -** the value is NULL or zero, fall through and change the P1 register -** to an integer 1. +** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, +** set the flag and fall through to the next instruction. ** -** When P1 is not used otherwise in a program, this opcode falls through -** once and jumps on all subsequent invocations. It is the equivalent -** of "OP_If P1 P2", followed by "OP_Integer 1 P1". +** See also: JumpOnce */ +case OP_Once: { /* jump */ + assert( pOp->p1nOnceFlag ); + if( p->aOnceFlag[pOp->p1] ){ + pc = pOp->p2-1; + }else{ + p->aOnceFlag[pOp->p1] = 1; + } + break; +} + /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value ** is considered true if it is numeric and non-zero. If the value -** in P1 is NULL then take the jump if P3 is true. +** in P1 is NULL then take the jump if P3 is non-zero. */ /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value -** is considered true if it has a numeric value of zero. If the value -** in P1 is NULL then take the jump if P3 is true. +** is considered false if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if P3 is zero. */ -case OP_Once: /* jump, in1 */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ int c; @@ -2060,12 +2074,6 @@ case OP_IfNot: { /* jump, in1 */ } if( c ){ pc = pOp->p2-1; - }else if( pOp->opcode==OP_Once ){ - assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); - memAboutToChange(p, pIn1); - pIn1->flags = MEM_Int; - pIn1->u.i = 1; - REGISTER_TRACE(pOp->p1, pIn1); } break; } @@ -2361,7 +2369,7 @@ case OP_Column: { if( aOffset[p2] ){ assert( rc==SQLITE_OK ); if( zRec ){ - MemReleaseExt(pDest); + VdbeMemRelease(pDest); sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); @@ -4616,9 +4624,9 @@ case OP_IdxGE: { /* jump */ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ - r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; }else{ - r.flags = UNPACKED_IGNORE_ROWID; + r.flags = UNPACKED_PREFIX_MATCH; } r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG @@ -5071,7 +5079,6 @@ case OP_Program: { /* jump */ pProgram = pOp->p4.pProgram; pRt = &aMem[pOp->p3]; - assert( memIsValid(pRt) ); assert( pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is @@ -5110,7 +5117,8 @@ case OP_Program: { /* jump */ nMem = pProgram->nMem + pProgram->nCsr; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor *); + + pProgram->nCsr * sizeof(VdbeCursor *) + + pProgram->nOnce * sizeof(u8); pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; @@ -5130,10 +5138,12 @@ case OP_Program: { /* jump */ pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; + pFrame->aOnceFlag = p->aOnceFlag; + pFrame->nOnceFlag = p->nOnceFlag; pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ - pMem->flags = MEM_Null; + pMem->flags = MEM_Invalid; pMem->db = db; } }else{ @@ -5155,7 +5165,11 @@ case OP_Program: { /* jump */ p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; + p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; + p->nOnceFlag = pProgram->nOnce; + p->nOp = pProgram->nOp; pc = -1; + memset(p->aOnceFlag, 0, p->nOnceFlag); break; } diff --git a/src/vdbe.h b/src/vdbe.h index 948c73b..90a43ce 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -82,6 +82,7 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ + int nOnce; /* Number of OP_Once instructions */ void *token; /* id that may be used to recursive triggers */ SubProgram *pNext; /* Next sub-program already visited */ }; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 803ae16..2a96cc5 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -33,6 +33,9 @@ typedef unsigned char Bool; /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; +/* Opaque type used by the explainer */ +typedef struct Explain Explain; + /* ** A cursor is a pointer into a single BTree within a database file. ** The cursor can seek to a BTree entry with a particular key, or @@ -117,6 +120,8 @@ struct VdbeFrame { int nOp; /* Size of aOp array */ Mem *aMem; /* Array of memory cells for parent frame */ int nMem; /* Number of entries in aMem */ + u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */ + int nOnceFlag; /* Number of entries in aOnceFlag */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ u16 nCursor; /* Number of entries in apCsr */ void *token; /* Copy of SubProgram.token */ @@ -255,6 +260,18 @@ struct sqlite3_context { CollSeq *pColl; /* Collating sequence */ }; +/* +** An Explain object accumulates indented output which is helpful +** in describing recursive data structures. +*/ +struct Explain { + Vdbe *pVdbe; /* Attach the explanation to this Vdbe */ + StrAccum str; /* The string being accumulated */ + int nIndent; /* Number of elements in aIndent */ + u16 aIndent[100]; /* Levels of indentation */ + char zBase[100]; /* Initial space */ +}; + /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. @@ -320,12 +337,18 @@ struct Vdbe { void *pFree; /* Free this when deleting the vdbe */ #ifdef SQLITE_DEBUG FILE *trace; /* Write an execution trace here, if not NULL */ +#endif +#ifdef SQLITE_ENABLE_TREE_EXPLAIN + Explain *pExplain; /* The explainer */ + char *zExplain; /* Explanation of data structures */ #endif VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ + int nOnceFlag; /* Size of array aOnceFlag[] */ + u8 *aOnceFlag; /* Flags for OP_Once */ }; /* @@ -385,7 +408,7 @@ int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); -#define MemReleaseExt(X) \ +#define VdbeMemRelease(X) \ if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); @@ -424,7 +447,7 @@ int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); #endif #ifdef SQLITE_DEBUG -void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); +void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); #endif #ifndef SQLITE_OMIT_FOREIGN_KEY @@ -442,8 +465,10 @@ int sqlite3VdbeMemHandleBom(Mem *pMem); #ifndef SQLITE_OMIT_INCRBLOB int sqlite3VdbeMemExpandBlob(Mem *); + #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) #else #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK + #define ExpandBlob(P) SQLITE_OK #endif #endif /* !defined(_VDBEINT_H_) */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index adc9dba..94db205 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -354,7 +354,7 @@ static int sqlite3Step(Vdbe *p){ ** ** Nevertheless, some published applications that were originally written ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE - ** returns, and the so were broken by the automatic-reset change. As a + ** returns, and those were broken by the automatic-reset change. As a ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the ** legacy behavior of returning SQLITE_MISUSE for cases where the ** previous sqlite3_step() returned something other than a SQLITE_LOCKED @@ -700,13 +700,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ /* If the value passed as the second argument is out of range, return ** a pointer to the following static Mem object which contains the ** value SQL NULL. Even though the Mem structure contains an element - ** of type i64, on certain architecture (x86) with certain compiler + ** of type i64, on certain architectures (x86) with certain compiler ** switches (-Os), gcc may align this Mem object on a 4-byte boundary ** instead of an 8-byte one. This all works fine, except that when ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s ** that a Mem structure is located on an 8-byte boundary. To prevent - ** this assert() from failing, when building with SQLITE_DEBUG defined - ** using gcc, force nullMem to be 8-byte aligned using the magical + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) @@ -1277,6 +1277,14 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; } +/* +** Return true if the prepared statement is in need of being reset. +*/ +int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ + Vdbe *v = (Vdbe*)pStmt; + return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; +} + /* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 75250238..c1566f3 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -196,7 +196,8 @@ int sqlite3VdbeAddOp4( /* ** Add an OP_ParseSchema opcode. This routine is broken out from -** sqlite3VdbeAddOp4() since it needs to also local all btrees. +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** as having been used. ** ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. @@ -913,13 +914,14 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } case P4_MEM: { Mem *pMem = pOp->p4.pMem; - assert( (pMem->flags & MEM_Null)==0 ); if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); + }else if( pMem->flags & MEM_Null ){ + sqlite3_snprintf(nTemp, zTemp, "NULL"); }else{ assert( pMem->flags & MEM_Blob ); zP4 = "(blob)"; @@ -962,8 +964,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. ** ** The prepared statements need to know in advance the complete set of -** attached databases that they will be using. A mask of these databases -** is maintained in p->btreeMask and is used for locking and other purposes. +** attached databases that will be use. A mask of these databases +** is maintained in p->btreeMask. The p->lockMask value is the subset of +** p->btreeMask of databases that will require a lock. */ void sqlite3VdbeUsesBtree(Vdbe *p, int i){ assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); @@ -1094,7 +1097,7 @@ static void releaseMemArray(Mem *p, int N){ p->zMalloc = 0; } - p->flags = MEM_Null; + p->flags = MEM_Invalid; } db->mallocFailed = malloc_failed; } @@ -1469,6 +1472,7 @@ void sqlite3VdbeMakeReady( int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ + int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ u8 *zCsr; /* Memory available for allocation */ u8 *zEnd; /* First byte past allocated memory */ @@ -1484,6 +1488,8 @@ void sqlite3VdbeMakeReady( nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; + nOnce = pParse->nOnce; + if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by @@ -1530,6 +1536,7 @@ void sqlite3VdbeMakeReady( p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte); + p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte); if( nByte ){ p->pFree = sqlite3DbMallocZero(db, nByte); } @@ -1538,6 +1545,7 @@ void sqlite3VdbeMakeReady( }while( nByte && !db->mallocFailed ); p->nCursor = (u16)nCursor; + p->nOnceFlag = nOnce; if( p->aVar ){ p->nVar = (ynVar)nVar; for(n=0; naMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ for(n=1; n<=nMem; n++){ - p->aMem[n].flags = MEM_Null; + p->aMem[n].flags = MEM_Invalid; p->aMem[n].db = db; } } @@ -1596,6 +1604,8 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ */ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; + v->aOnceFlag = pFrame->aOnceFlag; + v->nOnceFlag = pFrame->nOnceFlag; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; @@ -1658,8 +1668,10 @@ static void Cleanup(Vdbe *p){ /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ int i; - for(i=0; inCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 ); - for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null ); + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid ); + } #endif sqlite3DbFree(db, p->zErrMsg); @@ -1824,16 +1836,31 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ sqlite3_file *pMaster = 0; i64 offset = 0; int res; + int retryCount = 0; + int nMainFile; /* Select a master journal file name */ + nMainFile = sqlite3Strlen30(zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile); + if( zMaster==0 ) return SQLITE_NOMEM; do { u32 iRandom; - sqlite3DbFree(db, zMaster); - sqlite3_randomness(sizeof(iRandom), &iRandom); - zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, iRandom&0x7fffffff); - if( !zMaster ){ - return SQLITE_NOMEM; + if( retryCount ){ + if( retryCount>100 ){ + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + break; + }else if( retryCount==1 ){ + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); + } } + retryCount++; + sqlite3_randomness(sizeof(iRandom), &iRandom); + sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", + (iRandom>>8)&0xffffff, iRandom&0xff); + /* The antipenultimate character of the master journal name must + ** be "9" to avoid name collisions when using 8+3 filenames. */ + assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' ); sqlite3FileSuffix3(zMainFile, zMaster); rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); }while( rc==SQLITE_OK && res ); @@ -2127,6 +2154,7 @@ int sqlite3VdbeHalt(Vdbe *p){ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } + if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; @@ -2464,6 +2492,10 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->pFree); +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) + sqlite3DbFree(db, p->zExplain); + sqlite3DbFree(db, p->pExplain); +#endif sqlite3DbFree(db, p); } @@ -2943,15 +2975,6 @@ void sqlite3VdbeRecordUnpack( ** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are ** equal, then the keys are considered to be equal and ** the parts beyond the common prefix are ignored. -** -** If the UNPACKED_IGNORE_ROWID flag is set, then the last byte of -** the header of pKey1 is ignored. It is assumed that pKey1 is -** an index key, and thus ends with a rowid value. The last byte -** of the header will therefore be the serial type of the rowid: -** one of 1, 2, 3, 4, 5, 6, 8, or 9 - the integer serial types. -** The serial type of the final rowid will always be a single byte. -** By ignoring this last byte of the header, we force the comparison -** to ignore the rowid at the end of key1. */ int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ @@ -2984,9 +3007,6 @@ int sqlite3VdbeRecordCompare( idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - if( pPKey2->flags & UNPACKED_IGNORE_ROWID ){ - szHdr1--; - } nField = pKeyInfo->nField; while( idx1nField ){ u32 serial_type1; @@ -3166,7 +3186,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID ); + assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH ); *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); sqlite3VdbeMemRelease(&m); return SQLITE_OK; diff --git a/src/vdbemem.c b/src/vdbemem.c index e6e9156..f8777a7 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -18,12 +18,6 @@ #include "sqliteInt.h" #include "vdbeInt.h" -/* -** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) -** P if required. -*/ -#define expandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) - /* ** If pMem is an object with a valid string representation, this routine ** ensures the internal encoding for the string representation is @@ -123,7 +117,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ int f; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( (pMem->flags&MEM_RowSet)==0 ); - expandBlob(pMem); + ExpandBlob(pMem); f = pMem->flags; if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){ if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ @@ -292,7 +286,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ ** (Mem.type==SQLITE_TEXT). */ void sqlite3VdbeMemRelease(Mem *p){ - MemReleaseExt(p); + VdbeMemRelease(p); sqlite3DbFree(p->db, p->zMalloc); p->z = 0; p->zMalloc = 0; @@ -588,7 +582,7 @@ int sqlite3VdbeMemTooBig(Mem *p){ ** This is used for testing and debugging only - to make sure shallow ** copies are not misused. */ -void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){ +void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ @@ -614,7 +608,7 @@ void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){ */ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); - MemReleaseExt(pTo); + VdbeMemRelease(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->xDel = 0; if( (pFrom->flags&MEM_Static)==0 ){ @@ -632,7 +626,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; assert( (pFrom->flags & MEM_RowSet)==0 ); - MemReleaseExt(pTo); + VdbeMemRelease(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; @@ -960,7 +954,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ } assert( (MEM_Blob>>3) == MEM_Str ); pVal->flags |= (pVal->flags & MEM_Blob)>>3; - expandBlob(pVal); + ExpandBlob(pVal); if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ @@ -969,7 +963,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ return 0; } } - sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */ + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); diff --git a/src/vdbetrace.c b/src/vdbetrace.c index de123b5..4c4be13 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -12,6 +12,8 @@ ** ** This file contains code used to insert the values of host parameters ** (aka "wildcards") into the SQL text output by sqlite3_trace(). +** +** The Vdbe parse-tree explainer is also found here. */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -152,3 +154,118 @@ char *sqlite3VdbeExpandSql( } #endif /* #ifndef SQLITE_OMIT_TRACE */ + +/***************************************************************************** +** The following code implements the data-structure explaining logic +** for the Vdbe. +*/ + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) + +/* +** Allocate a new Explain object +*/ +void sqlite3ExplainBegin(Vdbe *pVdbe){ + if( pVdbe ){ + sqlite3BeginBenignMalloc(); + Explain *p = sqlite3_malloc( sizeof(Explain) ); + if( p ){ + memset(p, 0, sizeof(*p)); + p->pVdbe = pVdbe; + sqlite3_free(pVdbe->pExplain); + pVdbe->pExplain = p; + sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase), + SQLITE_MAX_LENGTH); + p->str.useMalloc = 2; + }else{ + sqlite3EndBenignMalloc(); + } + } +} + +/* +** Return true if the Explain ends with a new-line. +*/ +static int endsWithNL(Explain *p){ + return p && p->str.zText && p->str.nChar + && p->str.zText[p->str.nChar-1]=='\n'; +} + +/* +** Append text to the indentation +*/ +void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 ){ + va_list ap; + if( p->nIndent && endsWithNL(p) ){ + int n = p->nIndent; + if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent); + sqlite3AppendSpace(&p->str, p->aIndent[n-1]); + } + va_start(ap, zFormat); + sqlite3VXPrintf(&p->str, 1, zFormat, ap); + va_end(ap); + } +} + +/* +** Append a '\n' if there is not already one. +*/ +void sqlite3ExplainNL(Vdbe *pVdbe){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){ + sqlite3StrAccumAppend(&p->str, "\n", 1); + } +} + +/* +** Push a new indentation level. Subsequent lines will be indented +** so that they begin at the current cursor position. +*/ +void sqlite3ExplainPush(Vdbe *pVdbe){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 ){ + if( p->str.zText && p->nIndentaIndent) ){ + const char *z = p->str.zText; + int i = p->str.nChar-1; + int x; + while( i>=0 && z[i]!='\n' ){ i--; } + x = (p->str.nChar - 1) - i; + if( p->nIndent && xaIndent[p->nIndent-1] ){ + x = p->aIndent[p->nIndent-1]; + } + p->aIndent[p->nIndent] = x; + } + p->nIndent++; + } +} + +/* +** Pop the indentation stack by one level. +*/ +void sqlite3ExplainPop(Vdbe *p){ + if( p && p->pExplain ) p->pExplain->nIndent--; +} + +/* +** Free the indentation structure +*/ +void sqlite3ExplainFinish(Vdbe *pVdbe){ + if( pVdbe && pVdbe->pExplain ){ + sqlite3_free(pVdbe->zExplain); + sqlite3ExplainNL(pVdbe); + pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str); + sqlite3_free(pVdbe->pExplain); + pVdbe->pExplain = 0; + sqlite3EndBenignMalloc(); + } +} + +/* +** Return the explanation of a virtual machine. +*/ +const char *sqlite3VdbeExplanation(Vdbe *pVdbe){ + return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0; +} +#endif /* defined(SQLITE_DEBUG) */ diff --git a/src/wal.c b/src/wal.c index f2b3187..db9ce51 100644 --- a/src/wal.c +++ b/src/wal.c @@ -414,13 +414,18 @@ struct Wal { u32 iCallback; /* Value to pass to log callback (or 0) */ i64 mxWalSize; /* Truncate WAL to this size upon reset */ int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ + u8 syncFlags; /* Flags to use to sync header writes */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + u8 truncateOnCommit; /* True to truncate WAL file on commit */ + u8 syncHeader; /* Fsync the WAL header if true */ + u8 padToSectorBoundary; /* Pad transactions out to the next sector */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -1093,6 +1098,7 @@ static int walIndexRecover(Wal *pWal){ int szPage; /* Page size according to the log */ u32 magic; /* Magic value read from WAL header */ u32 version; /* Magic value read from WAL header */ + int isValid; /* True if this frame is valid */ /* Read in the WAL header. */ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); @@ -1151,14 +1157,14 @@ static int walIndexRecover(Wal *pWal){ for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ u32 pgno; /* Database page number for frame */ u32 nTruncate; /* dbsize field from frame header */ - int isValid; /* True if this frame is valid */ /* Read and decode the next log frame. */ + iFrame++; rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); if( !isValid ) break; - rc = walIndexAppend(pWal, ++iFrame, pgno); + rc = walIndexAppend(pWal, iFrame, pgno); if( rc!=SQLITE_OK ) break; /* If nTruncate is non-zero, this is a commit record. */ @@ -1281,6 +1287,8 @@ int sqlite3WalOpen( pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; + pRet->syncHeader = 1; + pRet->padToSectorBoundary = 1; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ @@ -1295,6 +1303,11 @@ int sqlite3WalOpen( sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ + int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -1714,7 +1727,7 @@ static int walCheckpoint( i64 nReq = ((i64)mxPage * szPage); rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); } } @@ -1781,6 +1794,24 @@ static int walCheckpoint( return rc; } +/* +** If the WAL file is currently larger than nMax bytes in size, truncate +** it to exactly nMax bytes. If an error occurs while doing so, ignore it. +*/ +static void walLimitSize(Wal *pWal, i64 nMax){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > nMax ) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + } +} + /* ** Close a connection to a log file. */ @@ -1804,23 +1835,40 @@ int sqlite3WalClose( */ rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); if( rc==SQLITE_OK ){ - int bPersistWal = -1; if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } rc = sqlite3WalCheckpoint( pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal); - if( rc==SQLITE_OK && bPersistWal!=1 ){ - isDelete = 1; + if( rc==SQLITE_OK ){ + int bPersist = -1; + sqlite3OsFileControlHint( + pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist + ); + if( bPersist!=1 ){ + /* Try to delete the WAL file if the checkpoint completed and + ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal + ** mode (!bPersist) */ + isDelete = 1; + }else if( pWal->mxWalSize>=0 ){ + /* Try to truncate the WAL file to zero bytes if the checkpoint + ** completed and fsynced (rc==SQLITE_OK) and we are in persistent + ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a + ** non-negative value (pWal->mxWalSize>=0). Note that we truncate + ** to zero bytes as truncating to the journal_size_limit might + ** leave a corrupt WAL file on disk. */ + walLimitSize(pWal, 0); + } } } walIndexClose(pWal, isDelete); sqlite3OsClose(pWal->pWalFd); if( isDelete ){ + sqlite3BeginBenignMalloc(); sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + sqlite3EndBenignMalloc(); } WALTRACE(("WAL%p: closed\n", pWal)); sqlite3_free((void *)pWal->apWiData); @@ -2310,7 +2358,7 @@ int sqlite3WalRead( for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ u32 iFrame = aHash[iKey] + iZero; if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){ - assert( iFrame>iRead ); + /* assert( iFrame>iRead ); -- not true if there is corruption */ iRead = iFrame; } if( (nCollide--)==0 ){ @@ -2422,6 +2470,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){ if( pWal->writeLock ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; + pWal->truncateOnCommit = 0; } return SQLITE_OK; } @@ -2518,6 +2567,7 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ return rc; } + /* ** This function is called just before writing a set of frames to the log ** file (see sqlite3WalFrames()). It checks to see if, instead of appending @@ -2555,23 +2605,6 @@ static int walRestartLog(Wal *pWal){ int i; /* Loop counter */ u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ - /* Limit the size of WAL file if the journal_size_limit PRAGMA is - ** set to a non-negative value. Log errors encountered - ** during the truncation attempt. */ - if( pWal->mxWalSize>=0 ){ - i64 sz; - int rx; - sqlite3BeginBenignMalloc(); - rx = sqlite3OsFileSize(pWal->pWalFd, &sz); - if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ - rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); - } - sqlite3EndBenignMalloc(); - if( rx ){ - sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); - } - } - pWal->nCkpt++; pWal->hdr.mxFrame = 0; sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); @@ -2600,6 +2633,74 @@ static int walRestartLog(Wal *pWal){ return rc; } +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + +/* +** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. +** +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. +*/ +static int walWriteToLog( + WalWriter *p, /* WAL to write to */ + void *pContent, /* Content to be written */ + int iAmt, /* Number of bytes to write */ + sqlite3_int64 iOffset /* Start writing at this offset */ +){ + int rc; + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); + if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; + pContent = (void*)(iFirstAmt + (char*)pContent); + assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); + rc = sqlite3OsSync(p->pFd, p->syncFlags); + if( iAmt==0 || rc ) return rc; + } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM; +#else + pData = pPage->pData; +#endif + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); + return rc; +} + /* ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). @@ -2614,14 +2715,20 @@ int sqlite3WalFrames( ){ int rc; /* Used to catch return codes */ u32 iFrame; /* Next frame address */ - u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ PgHdr *p; /* Iterator to run through pList with. */ PgHdr *pLast = 0; /* Last frame in list */ - int nLast = 0; /* Number of extra copies of last page */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ assert( pList ); assert( pWal->writeLock ); + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", @@ -2649,7 +2756,7 @@ int sqlite3WalFrames( sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); sqlite3Put4byte(&aWalHdr[8], szPage); sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); - sqlite3_randomness(8, pWal->hdr.aSalt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]); @@ -2659,77 +2766,89 @@ int sqlite3WalFrames( pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; pWal->hdr.aFrameCksum[0] = aCksum[0]; pWal->hdr.aFrameCksum[1] = aCksum[1]; + pWal->truncateOnCommit = 1; rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); if( rc!=SQLITE_OK ){ return rc; } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** http://localhost:591/sqlite/info/ff5be73dee + */ + if( pWal->syncHeader && sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( rc ) return rc; + } } assert( (int)pWal->szPage==szPage ); - /* Write the log file. */ - for(p=pList; p; p=p->pDirty){ - u32 nDbsize; /* Db-size field for frame header */ - i64 iOffset; /* Write offset in log file */ - void *pData; - - iOffset = walFrameOffset(++iFrame, szPage); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - - /* Populate and write the frame header */ - nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; -#else - pData = p->pData; -#endif - walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame); - rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; - /* Write the page data */ - rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset+sizeof(aFrame)); - if( rc!=SQLITE_OK ){ - return rc; - } + /* Write all frames into the log file exactly once */ + for(p=pList; p; p=p->pDirty){ + int nDbSize; /* 0 normally. Positive == commit flag */ + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; pLast = p; + iOffset += szFrame; } - /* Sync the log file if the 'isSync' flag was specified. */ - if( sync_flags ){ - i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); - i64 iOffset = walFrameOffset(iFrame+1, szPage); - - assert( isCommit ); - assert( iSegment>0 ); - - iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); - while( iOffsetpData; -#endif - walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchonous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ + if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ + if( pWal->padToSectorBoundary ){ + int sectorSize = sqlite3OsSectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + while( iOffsetpWalFd, pData, szPage, iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - nLast++; - iOffset += szPage; + }else{ + rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } + } - rc = sqlite3OsSync(pWal->pWalFd, sync_flags); + /* If this frame set completes the first transaction in the WAL and + ** if PRAGMA journal_size_limit is set, then truncate the WAL to the + ** journal size limit, if possible. + */ + if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ + i64 sz = pWal->mxWalSize; + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); + } + walLimitSize(pWal, sz); + pWal->truncateOnCommit = 0; } /* Append data to the wal-index. It is not necessary to lock the @@ -2742,9 +2861,9 @@ int sqlite3WalFrames( iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } - while( nLast>0 && rc==SQLITE_OK ){ + while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; - nLast--; + nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); } diff --git a/src/wal.h b/src/wal.h index a62b23b..fac762e 100644 --- a/src/wal.h +++ b/src/wal.h @@ -19,6 +19,12 @@ #include "sqliteInt.h" +/* Additional values that can be added to the sync_flags argument of +** sqlite3WalFrames(): +*/ +#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ +#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ + #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalLimit(x,y) diff --git a/src/where.c b/src/where.c index 05414da..78efbf9 100644 --- a/src/where.c +++ b/src/where.c @@ -604,7 +604,7 @@ static WhereTerm *findTerm( && pTerm->u.leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ - if( pIdx && pTerm->eOperator!=WO_ISNULL ){ + if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; @@ -2005,7 +2005,6 @@ static void constructAutomaticIndex( int nByte; /* Byte of memory needed for pIdx */ Index *pIdx; /* Object describing the transient index */ Vdbe *v; /* Prepared statement under construction */ - int regIsInit; /* Register set by initialization */ int addrInit; /* Address of the initialization bypass jump */ Table *pTable; /* The table being indexed */ KeyInfo *pKeyinfo; /* Key information for the index */ @@ -2022,8 +2021,7 @@ static void constructAutomaticIndex( ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); - regIsInit = ++pParse->nMem; - addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); + addrInit = sqlite3CodeOnce(pParse); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ @@ -3052,10 +3050,24 @@ static void bestBtreeIndex( #endif used |= pTerm->prereqRight; } - - /* Determine the value of rangeDiv */ - if( nEqnColumn && pProbe->bUnordered==0 ){ - int j = pProbe->aiColumn[nEq]; + + /* If the index being considered is UNIQUE, and there is an equality + ** constraint for all columns in the index, then this search will find + ** at most a single row. In this case set the WHERE_UNIQUE flag to + ** indicate this to the caller. + ** + ** Otherwise, if the search may find more than one row, test to see if + ** there is a range constraint on indexed column (nEq+1) that can be + ** optimized using the index. + */ + if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){ + testcase( wsFlags & WHERE_COLUMN_IN ); + testcase( wsFlags & WHERE_COLUMN_NULL ); + if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ + wsFlags |= WHERE_UNIQUE; + } + }else if( pProbe->bUnordered==0 ){ + int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]); if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); @@ -3074,12 +3086,6 @@ static void bestBtreeIndex( } wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); } - }else if( pProbe->onError!=OE_None ){ - testcase( wsFlags & WHERE_COLUMN_IN ); - testcase( wsFlags & WHERE_COLUMN_NULL ); - if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ - wsFlags |= WHERE_UNIQUE; - } } /* If there is an ORDER BY clause and the index being considered will @@ -3690,10 +3696,12 @@ static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ j = i; if( pPlan->wsFlags&WHERE_BTM_LIMIT ){ - explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">"); + char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(&txt, i++, z, ">"); } if( pPlan->wsFlags&WHERE_TOP_LIMIT ){ - explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<"); + char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(&txt, i, z, "<"); } sqlite3StrAccumAppend(&txt, ")", 1); return sqlite3StrAccumFinish(&txt); @@ -4051,7 +4059,7 @@ static Bitmask codeOneLoopStart( pIdx = pLevel->plan.u.pIdx; iIdxCur = pLevel->iIdxCur; - k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */ + k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]); /* If this loop satisfies a sort order (pOrderBy) request that ** was passed to this function to implement a "SELECT min(x) ..." @@ -4097,7 +4105,9 @@ static Bitmask codeOneLoopStart( ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ - if( nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ + if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) + || (bRev && pIdx->nColumn==nEq) + ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); } diff --git a/test/attach.test b/test/attach.test index d57f5bf..be5f988 100644 --- a/test/attach.test +++ b/test/attach.test @@ -51,6 +51,25 @@ do_test attach-1.3 { SELECT * FROM two.t2; } } {1 x 2 y} + +# Tests for the sqlite3_db_filename interface +# +do_test attach-1.3.1 { + file tail [sqlite3_db_filename db main] +} {test.db} +do_test attach-1.3.2 { + file tail [sqlite3_db_filename db MAIN] +} {test.db} +do_test attach-1.3.3 { + file tail [sqlite3_db_filename db temp] +} {} +do_test attach-1.3.4 { + file tail [sqlite3_db_filename db two] +} {test2.db} +do_test attach-1.3.5 { + file tail [sqlite3_db_filename db three] +} {} + do_test attach-1.4 { execsql { SELECT * FROM t2; diff --git a/test/backup2.test b/test/backup2.test index 34924b0..9893199 100644 --- a/test/backup2.test +++ b/test/backup2.test @@ -142,21 +142,18 @@ do_test backup2-9 { # Try to restore from an unreadable file. # if {$tcl_platform(platform)=="windows"} { - do_test backup2-10 { - forcedelete bu3.db - file mkdir bu3.db - set rc [catch {db restore temp bu3.db} res] - lappend rc $res - } {1 {cannot open source database: unable to open database file}} -} -if {$tcl_platform(platform)!="windows"} { - do_test backup2-10 { - forcedelete bu3.db - file mkdir bu3.db - set rc [catch {db restore temp bu3.db} res] - lappend rc $res - } {1 {cannot open source database: disk I/O error}} + set msg {cannot open source database: unable to open database file} +} elseif {$tcl_platform(os)=="OpenBSD"} { + set msg {restore failed: file is encrypted or is not a database} +} else { + set msg {cannot open source database: disk I/O error} } +do_test backup2-10 { + forcedelete bu3.db + file mkdir bu3.db + set rc [catch {db restore temp bu3.db} res] + lappend rc $res +} [list 1 $msg] # Try to restore from something that is not a database file. # diff --git a/test/bigfile2.test b/test/bigfile2.test new file mode 100644 index 0000000..9810d3a --- /dev/null +++ b/test/bigfile2.test @@ -0,0 +1,59 @@ +# 2011 December 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this script testing the ability of SQLite to handle database +# files larger than 4GB. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bigfile2 + +# Create a small database. +# +do_execsql_test 1.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); +} + +# Pad the file out to 4GB in size. Then clear the file-size field in the +# db header. This will cause SQLite to assume that the first 4GB of pages +# are actually in use and new pages will be appended to the file. +# +db close +if {[catch {fake_big_file 4096 [pwd]/test.db} msg]} { + puts "**** Unable to create a file larger than 4096 MB. *****" + finish_test + return +} +hexio_write test.db 28 00000000 + +do_test 1.2 { + file size test.db +} [expr 14 + 4096 * (1<<20)] + +# Now insert a large row. The overflow pages will be located past the 4GB +# boundary. Then, after opening and closing the database, test that the row +# can be read back in. +# +set str [string repeat k 30000] +do_test 1.3 { + sqlite3 db test.db + execsql { INSERT INTO t1 VALUES(3, $str) } + db close + sqlite3 db test.db + db one { SELECT b FROM t1 WHERE a = 3 } +} $str + +db close +file delete test.db + +finish_test diff --git a/test/capi3d.test b/test/capi3d.test index 49e6447..746ec20 100644 --- a/test/capi3d.test +++ b/test/capi3d.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. # # This file is devoted to testing the sqlite3_next_stmt and -# sqlite3_stmt_readonly interfaces. +# sqlite3_stmt_readonly and sqlite3_stmt_busy interfaces. # # $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $ # @@ -112,5 +112,29 @@ do_test capi3-2.99 { sqlite3_stmt_readonly 0 } 1 +# Tests for sqlite3_stmt_busy +# +do_test capi3d-3.1 { + db eval {INSERT INTO t1 VALUES(6); INSERT INTO t1 VALUES(7);} + set STMT [sqlite3_prepare db {SELECT * FROM t1} -1 TAIL] + sqlite3_stmt_busy $STMT +} {0} +do_test capi3d-3.2 { + sqlite3_step $STMT + sqlite3_stmt_busy $STMT +} {1} +do_test capi3d-3.3 { + sqlite3_step $STMT + sqlite3_stmt_busy $STMT +} {1} +do_test capi3d-3.4 { + sqlite3_reset $STMT + sqlite3_stmt_busy $STMT +} {0} + +do_test capi3d-3.99 { + sqlite3_finalize $STMT + sqlite3_stmt_busy 0 +} {0} finish_test diff --git a/test/corruptF.test b/test/corruptF.test new file mode 100644 index 0000000..33eef39 --- /dev/null +++ b/test/corruptF.test @@ -0,0 +1,150 @@ +# 2012 January 12 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix corruptF + +# Do not use a codec for tests in this file, as the database file is +# manipulated directly using tcl scripts (using the [hexio_write] command). +# +do_not_use_codec + +proc str {i} { format %08d $i } + +# Create a 6 page database containing a single table - t1. Table t1 +# consists of page 2 (the root page) and pages 5 and 6 (leaf pages). +# Database pages 3 and 4 are on the free list. +# +proc create_test_db {} { + catch { db close } + forcedelete test.db + sqlite3 db test.db + db func str str + execsql { + PRAGMA auto_vacuum = 0; + PRAGMA page_size = 1024; + CREATE TABLE t1(x); /* root page = 2 */ + CREATE TABLE t2(x); /* root page = 3 */ + CREATE TABLE t3(x); /* root page = 4 */ + + INSERT INTO t1 VALUES(str(1)); + INSERT INTO t1 SELECT str(rowid+1) FROM t1; + INSERT INTO t1 SELECT str(rowid+2) FROM t1; + INSERT INTO t1 SELECT str(rowid+4) FROM t1; + INSERT INTO t1 SELECT str(rowid+8) FROM t1; + INSERT INTO t1 SELECT str(rowid+16) FROM t1; + INSERT INTO t1 SELECT str(rowid+32) FROM t1; + INSERT INTO t1 SELECT str(rowid+64) FROM t1; + DROP TABLE t2; + DROP TABLE t3; + } + db close +} + +do_test 1.1 { create_test_db } {} + +# Check the db is as we expect. 6 pages in total, with 3 and 4 on the free +# list. Page 3 is the free list trunk and page 4 is a leaf. +# +do_test 1.2 { file size test.db } [expr 6*1024] +do_test 1.3 { hexio_read test.db 32 4 } 00000003 +do_test 1.4 { hexio_read test.db [expr 2*1024] 12 } 000000000000000100000004 + +# Change the free-list entry to page 6 and reopen the db file. +do_test 1.5 { + hexio_write test.db [expr 2*1024 + 8] 00000006 + sqlite3 db test.db +} {} + +# Now create a new table in the database file. The root of the new table +# is page 6, which is also the right-most leaf page in table t1. +# +do_execsql_test 1.6 { + CREATE TABLE t4(x); + SELECT * FROM sqlite_master; +} { + table t1 t1 2 {CREATE TABLE t1(x)} + table t4 t4 6 {CREATE TABLE t4(x)} +} + +# At one point this was causing an assert to fail. +# +# This statement opens a cursor on table t1 and does a full table scan. As +# each row is visited, it is copied into table t4. There is no temporary +# table. +# +# When the t1 cursor reaches page 6 (which is both the right-most leaf of +# t1 and the root of t4), it continues to iterate through the keys within +# it (which at this point are keys that have been inserted into t4). And +# for each row visited, another row is inserted into page 6 - it being the +# root page of t4. Eventually, page 6 becomes full and the height of the +# b-tree for table t4 increased. From the point of view of the t1 cursor, +# this unexpectedly reduces the number of keys on page 6 in the middle of +# its iteration, which causes an assert() to fail. +# +db_save_and_close +if 1 { +for {set i 0} {$i < 128} {incr i} { + db_restore_and_reopen + do_test 1.7.$i { + set res [ + catchsql { INSERT INTO t4 SELECT x FROM t1 WHERE rowid>$i } + ] + if {$res == "0 {}" || $res == "1 {database disk image is malformed}"} { + set res "" + } + set res + } {} +} +} + +do_test 2.1 { create_test_db } {} +do_test 2.2 { file size test.db } [expr 6*1024] +do_test 2.3 { hexio_read test.db 32 4 } 00000003 +do_test 2.4 { hexio_read test.db [expr 2*1024] 12 } 000000000000000100000004 + +# Change the free-list entry to page 5 and reopen the db file. +do_test 2.5 { + hexio_write test.db [expr 2*1024 + 8] 00000005 + sqlite3 db test.db +} {} + +# Now create a new table in the database file. The root of the new table +# is page 5, which is also the right-most leaf page in table t1. +# +do_execsql_test 2.6 { + CREATE TABLE t4(x); + SELECT * FROM sqlite_master; +} { + table t1 t1 2 {CREATE TABLE t1(x)} + table t4 t4 5 {CREATE TABLE t4(x)} +} + +db_save_and_close +for {set i 127} {$i >= 0} {incr i -1} { + db_restore_and_reopen + do_test 2.7.$i { + set res [ + catchsql { + INSERT INTO t4 SELECT x FROM t1 WHERE rowid<$i ORDER BY rowid DESC + } + ] + if {$res == "0 {}" || $res == "1 {database disk image is malformed}"} { + set res "" + } + set res + } {} +} + +finish_test + diff --git a/test/crypto.test b/test/crypto.test index aabb481..7824056 100644 --- a/test/crypto.test +++ b/test/crypto.test @@ -1145,4 +1145,64 @@ do_test cipher-options-before-keys { db close file delete -force test.db +# open a 1.1.8 database (no HMAC), then +# try to open another 1.1.8 database. The +# attached database should have the same hmac +# setting as the original +do_test default-use-hmac-attach { + file copy -force sqlcipher-1.1.8-testkey.db test.db + sqlite_orig db test.db + execsql { + PRAGMA cipher_default_use_hmac = OFF; + PRAGMA key = 'testkey'; + SELECT count(*) FROM t1; + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + SELECT count(*) from db2.t1; + PRAGMA cipher_default_use_hmac = ON; + } +} {4 4} +db close +file delete -force test.db + +# open a 2.0 database (with HMAC), then +# try to a 1.1.8 database. this should +# fail because the hmac setting for the +# attached database is not compatible +do_test attach-1.1.8-database-from-2.0-fails { + sqlite_orig db test.db + catchsql { + PRAGMA key = 'testkey'; + CREATE table t1(a,b); + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + } +} {1 {file is encrypted or is not a database}} +db close +file delete -force test.db + +# open a 2.0 database (with HMAC), then +# set the default hmac setting to OFF. +# try to a 1.1.8 database. this should +# succeed now that hmac is off by default +# before the attach +do_test change-default-use-hmac-attach { + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + CREATE table t1(a,b); + INSERT INTO t1(a,b) VALUES (1,2); + } + db close + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + SELECT count(*) FROM t1; + PRAGMA cipher_default_use_hmac = OFF; + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + SELECT count(*) from db2.t1; + PRAGMA cipher_default_use_hmac = ON; + } +} {1 4} +db close +file delete -force test.db + finish_test diff --git a/test/dbstatus.test b/test/dbstatus.test index e1c8f3e..5fc8be0 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -62,6 +62,11 @@ ifcapable stat3 { set STAT3 0 } +ifcapable malloc_usable_size { + finish_test + return +} + #--------------------------------------------------------------------------- # Run the dbstatus-2 and dbstatus-3 tests with several of different # lookaside buffer sizes. @@ -207,8 +212,13 @@ foreach ::lookaside_buffer_size {0 64 120} { # Some of the memory used for sqlite_stat3 is unaccounted for by # dbstatus. # + # Finally, on osx the estimate of memory used by the schema may be + # slightly low. + # if {[string match *x $tn] || $AUTOVACUUM - || ([string match *y $tn] && $STAT3)} { + || ([string match *y $tn] && $STAT3) + || ($::tcl_platform(os) == "Darwin") + } { do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1 } else { do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree diff --git a/test/e_createtable.test b/test/e_createtable.test index f61db1c..8221828 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -58,7 +58,7 @@ proc table_list {} { } -# EVIDENCE-OF: R-25262-01881 -- syntax diagram type-name +# EVIDENCE-OF: R-47266-09114 -- syntax diagram type-name # do_createtable_tests 0.1.1 -repair { drop_all_tables @@ -79,12 +79,7 @@ do_createtable_tests 0.1.2 -error { } -# EVIDENCE-OF: R-18762-12428 -- syntax diagram column-constraint -# -# Note: Not shown in the syntax diagram is the "NULL" constraint. This -# is the opposite of "NOT NULL" - it implies that the column may -# take a NULL value. This is the default anyway, so this type of -# constraint is rarely used. +# EVIDENCE-OF: R-60689-48779 -- syntax diagram column-constraint # do_createtable_tests 0.2.1 -repair { drop_all_tables @@ -131,7 +126,7 @@ do_createtable_tests 0.2.1 -repair { } {} } -# EVIDENCE-OF: R-17905-31923 -- syntax diagram table-constraint +# EVIDENCE-OF: R-58169-51804 -- syntax diagram table-constraint # do_createtable_tests 0.3.1 -repair { drop_all_tables @@ -150,7 +145,7 @@ do_createtable_tests 0.3.1 -repair { 4.1 "CREATE TABLE t1(c1, c2, FOREIGN KEY(c1) REFERENCES t2)" {} } -# EVIDENCE-OF: R-18765-31171 -- syntax diagram column-def +# EVIDENCE-OF: R-44826-22243 -- syntax diagram column-def # do_createtable_tests 0.4.1 -repair { drop_all_tables @@ -165,7 +160,7 @@ do_createtable_tests 0.4.1 -repair { } {} } -# EVIDENCE-OF: R-59573-11075 -- syntax diagram create-table-stmt +# EVIDENCE-OF: R-45698-45677 -- syntax diagram create-table-stmt # do_createtable_tests 0.5.1 -repair { drop_all_tables @@ -190,7 +185,7 @@ do_createtable_tests 0.5.1 -repair { 15 "CREATE TABLE t1 AS SELECT count(*), max(b), min(a) FROM t2" {} } -# EVIDENCE-OF: R-32138-02228 -- syntax diagram foreign-key-clause +# EVIDENCE-OF: R-24369-11919 -- syntax diagram foreign-key-clause # # 1: Explicit parent-key columns. # 2: Implicit child-key columns. diff --git a/test/e_delete.test b/test/e_delete.test index c77d444..9145981 100644 --- a/test/e_delete.test +++ b/test/e_delete.test @@ -24,9 +24,9 @@ do_execsql_test e_delete-0.0 { CREATE INDEX i1 ON t1(a); } {} -# EVIDENCE-OF: R-24177-52883 -- syntax diagram delete-stmt +# EVIDENCE-OF: R-62077-19799 -- syntax diagram delete-stmt # -# EVIDENCE-OF: R-12802-60464 -- syntax diagram qualified-table-name +# EVIDENCE-OF: R-60796-31013 -- syntax diagram qualified-table-name # do_delete_tests e_delete-0.1 { 1 "DELETE FROM t1" {} @@ -287,7 +287,7 @@ do_delete_tests e_delete-2.5 -error { near "%s": syntax error } { # of the DELETE statement is extended by the addition of optional ORDER # BY and LIMIT clauses: # -# EVIDENCE-OF: R-45897-01670 -- syntax diagram delete-stmt-limited +# EVIDENCE-OF: R-52694-53361 -- syntax diagram delete-stmt-limited # do_delete_tests e_delete-3.1 { 1 "DELETE FROM t1 LIMIT 5" {} diff --git a/test/e_droptrigger.test b/test/e_droptrigger.test index 0c14831..fe96104 100644 --- a/test/e_droptrigger.test +++ b/test/e_droptrigger.test @@ -69,7 +69,7 @@ proc droptrigger_reopen_db {{event INSERT}} { } -# EVIDENCE-OF: R-52650-16855 -- syntax diagram drop-trigger-stmt +# EVIDENCE-OF: R-27975-10951 -- syntax diagram drop-trigger-stmt # do_droptrigger_tests 1.1 -repair { droptrigger_reopen_db diff --git a/test/e_dropview.test b/test/e_dropview.test index 447e5c3..4a4b9c3 100644 --- a/test/e_dropview.test +++ b/test/e_dropview.test @@ -70,7 +70,7 @@ proc do_dropview_tests {nm args} { uplevel do_select_tests $nm $args } -# EVIDENCE-OF: R-21739-51207 -- syntax diagram drop-view-stmt +# EVIDENCE-OF: R-53136-36436 -- syntax diagram drop-view-stmt # # All paths in the syntax diagram for DROP VIEW are tested by tests 1.*. # diff --git a/test/e_expr.test b/test/e_expr.test index 3c9678c..c770f1c 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -627,7 +627,7 @@ do_test e_expr-11.7.1 { sqlite3_finalize $stmt } SQLITE_OK #------------------------------------------------------------------------- # "Test" the syntax diagrams in lang_expr.html. # -# EVIDENCE-OF: R-62067-43884 -- syntax diagram signed-number +# EVIDENCE-OF: R-02989-21050 -- syntax diagram signed-number # do_execsql_test e_expr-12.1.1 { SELECT 0, +0, -0 } {0 0 0} do_execsql_test e_expr-12.1.2 { SELECT 1, +1, -1 } {1 1 -1} @@ -642,7 +642,7 @@ do_execsql_test e_expr-12.1.6 { SELECT 0.0001, +0.0001, -0.0001 } {0.0001 0.0001 -0.0001} -# EVIDENCE-OF: R-21258-25489 -- syntax diagram literal-value +# EVIDENCE-OF: R-43188-60852 -- syntax diagram literal-value # set sqlite_current_time 1 do_execsql_test e_expr-12.2.1 {SELECT 123} {123} @@ -655,7 +655,7 @@ do_execsql_test e_expr-12.2.7 {SELECT CURRENT_DATE} {1970-01-01} do_execsql_test e_expr-12.2.8 {SELECT CURRENT_TIMESTAMP} {{1970-01-01 00:00:01}} set sqlite_current_time 0 -# EVIDENCE-OF: R-57598-59332 -- syntax diagram expr +# EVIDENCE-OF: R-50544-32159 -- syntax diagram expr # forcedelete test.db2 execsql { @@ -812,7 +812,7 @@ foreach {tn expr} { } } -# EVIDENCE-OF: R-49462-56079 -- syntax diagram raise-function +# EVIDENCE-OF: R-39820-63916 -- syntax diagram raise-function # foreach {tn raiseexpr} { 1 "RAISE(IGNORE)" diff --git a/test/e_insert.test b/test/e_insert.test index fe8bfcf..e96b1a6 100644 --- a/test/e_insert.test +++ b/test/e_insert.test @@ -45,7 +45,7 @@ proc do_insert_tests {args} { uplevel do_select_tests $args } -# EVIDENCE-OF: R-41448-54465 -- syntax diagram insert-stmt +# EVIDENCE-OF: R-55375-41353 -- syntax diagram insert-stmt # do_insert_tests e_insert-0 { 1 "INSERT INTO a1 DEFAULT VALUES" {} diff --git a/test/e_reindex.test b/test/e_reindex.test index e9419df..b39f37e 100644 --- a/test/e_reindex.test +++ b/test/e_reindex.test @@ -26,7 +26,7 @@ do_execsql_test e_reindex-0.0 { CREATE INDEX i2 ON t1(b, a); } {} -# EVIDENCE-OF: R-57021-15304 -- syntax diagram reindex-stmt +# EVIDENCE-OF: R-51477-38549 -- syntax diagram reindex-stmt # do_reindex_tests e_reindex-0.1 { 1 "REINDEX" {} @@ -34,8 +34,8 @@ do_reindex_tests e_reindex-0.1 { 3 "REINDEX binary" {} 4 "REINDEX t1" {} 5 "REINDEX main.t1" {} - 4 "REINDEX i1" {} - 5 "REINDEX main.i1" {} + 6 "REINDEX i1" {} + 7 "REINDEX main.i1" {} } # EVIDENCE-OF: R-52173-44778 The REINDEX command is used to delete and diff --git a/test/e_select.test b/test/e_select.test index e0f5f0f..39a74cc 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -78,7 +78,7 @@ proc do_join_test {tn select res} { # The following tests check that all paths on the syntax diagrams on # the lang_select.html page may be taken. # -# EVIDENCE-OF: R-18428-22111 -- syntax diagram join-constraint +# EVIDENCE-OF: R-11353-33501 -- syntax diagram join-constraint # do_join_test e_select-0.1.1 { SELECT count(*) FROM t1 %JOIN% t2 ON (t1.a=t2.a) @@ -96,7 +96,7 @@ do_catchsql_test e_select-0.1.5 { SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a) } {1 {near "ON": syntax error}} -# EVIDENCE-OF: R-44854-11739 -- syntax diagram select-core +# EVIDENCE-OF: R-40919-40941 -- syntax diagram select-core # # 0: SELECT ... # 1: SELECT DISTINCT ... @@ -221,7 +221,7 @@ do_select_tests e_select-0.2 { } -# EVIDENCE-OF: R-23316-20169 -- syntax diagram result-column +# EVIDENCE-OF: R-41378-26734 -- syntax diagram result-column # do_select_tests e_select-0.3 { 1 "SELECT * FROM t1" {a one b two c three} @@ -231,9 +231,9 @@ do_select_tests e_select-0.3 { 5 "SELECT 'x'||a||'x' AS alias FROM t1" {xax xbx xcx} } -# EVIDENCE-OF: R-41233-21397 -- syntax diagram join-source +# EVIDENCE-OF: R-43129-35648 -- syntax diagram join-source # -# EVIDENCE-OF: R-45040-11121 -- syntax diagram join-op +# EVIDENCE-OF: R-36683-37460 -- syntax diagram join-op # do_select_tests e_select-0.4 { 1 "SELECT t1.rowid FROM t1" {1 2 3} @@ -258,7 +258,7 @@ do_select_tests e_select-0.4 { 16 "SELECT t1.rowid FROM t1 CROSS JOIN t3" {1 1 2 2 3 3} } -# EVIDENCE-OF: R-56911-63533 -- syntax diagram compound-operator +# EVIDENCE-OF: R-28308-37813 -- syntax diagram compound-operator # do_select_tests e_select-0.5 { 1 "SELECT rowid FROM t1 UNION ALL SELECT rowid+2 FROM t4" {1 2 3 3 4} @@ -267,7 +267,7 @@ do_select_tests e_select-0.5 { 4 "SELECT rowid FROM t1 EXCEPT SELECT rowid+2 FROM t4" {1 2} } -# EVIDENCE-OF: R-60388-27458 -- syntax diagram ordering-term +# EVIDENCE-OF: R-06480-34950 -- syntax diagram ordering-term # do_select_tests e_select-0.6 { 1 "SELECT b||a FROM t1 ORDER BY b||a" {onea threec twob} @@ -276,7 +276,7 @@ do_select_tests e_select-0.6 { 4 "SELECT b||a FROM t1 ORDER BY (b||a) DESC" {twob threec onea} } -# EVIDENCE-OF: R-36494-33519 -- syntax diagram select-stmt +# EVIDENCE-OF: R-23926-36668 -- syntax diagram select-stmt # do_select_tests e_select-0.7 { 1 "SELECT * FROM t1" {a one b two c three} diff --git a/test/e_update.test b/test/e_update.test index c14b845..6c0e5f8 100644 --- a/test/e_update.test +++ b/test/e_update.test @@ -49,7 +49,7 @@ proc do_update_tests {args} { uplevel do_select_tests $args } -# EVIDENCE-OF: R-05685-44205 -- syntax diagram update-stmt +# EVIDENCE-OF: R-62337-45828 -- syntax diagram update-stmt # do_update_tests e_update-0 { 1 "UPDATE t1 SET a=10" {} @@ -495,7 +495,7 @@ do_update_tests e_update-2.5 -error { # of the UPDATE statement is extended with optional ORDER BY and LIMIT # clauses # -# EVIDENCE-OF: R-08948-01887 -- syntax diagram update-stmt-limited +# EVIDENCE-OF: R-45169-39597 -- syntax diagram update-stmt-limited # do_update_tests e_update-3.0 { 1 "UPDATE t1 SET a=b LIMIT 5" {} diff --git a/test/e_vacuum.test b/test/e_vacuum.test index 414c854..aa7870f 100644 --- a/test/e_vacuum.test +++ b/test/e_vacuum.test @@ -65,7 +65,7 @@ proc fragment_count {name} { } -# EVIDENCE-OF: R-63707-33375 -- syntax diagram vacuum-stmt +# EVIDENCE-OF: R-45173-45977 -- syntax diagram vacuum-stmt # do_execsql_test e_vacuum-0.1 { VACUUM } {} diff --git a/test/incrvacuum2.test b/test/incrvacuum2.test index e67a086..6e8e1be 100644 --- a/test/incrvacuum2.test +++ b/test/incrvacuum2.test @@ -191,7 +191,7 @@ ifcapable wal { PRAGMA wal_checkpoint; } file size test.db-wal - } {1640} + } [expr {32+2*(512+24)}] do_test 4.3 { db close @@ -205,7 +205,7 @@ ifcapable wal { if {$newsz>$maxsz} {set maxsz $newsz} } set maxsz - } {2176} + } [expr {32+3*(512+24)}] } finish_test diff --git a/test/insert4.test b/test/insert4.test index cb02b9d..f4a45c1 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -386,4 +386,179 @@ ifcapable foreignkey { } {1} } +# Ticket [676bc02b87176125635cb174d110b431581912bb] +# Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer +# optimization. +# +do_test insert4-8.1 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.2 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.3 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.4 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.5 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.6 { + execsql { + SELECT * FROM t1; + } +} {-99 100 1 2} +do_test insert4-8.7 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.8 { + execsql { + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.9 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + BEGIN; + INSERT INTO t1 VALUES(2,3); + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.10 { + catchsql {COMMIT} +} {1 {cannot commit - no transaction is active}} +do_test insert4-8.11 { + execsql { + SELECT * FROM t1; + } +} {1 2} + +do_test insert4-8.21 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.22 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.23 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.24 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.25 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} + + finish_test diff --git a/test/journal2.test b/test/journal2.test index 25ce941..8f9b4d0 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -34,7 +34,7 @@ proc a_string {n} { # characteristics flags to "SAFE_DELETE". # testvfs tvfs -default 1 -tvfs devchar undeletable_when_open +tvfs devchar {undeletable_when_open powersafe_overwrite} # Set up a hook so that each time a journal file is opened, closed or # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final @@ -231,4 +231,3 @@ ifcapable wal { tvfs delete finish_test - diff --git a/test/malloc5.test b/test/malloc5.test index 71f56bb..c02f65e 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -352,7 +352,7 @@ do_test malloc5-6.3.1 { do_test malloc5-6.3.2 { # Try to release 7700 bytes. This should release all the # non-dirty pages held by db2. - sqlite3_release_memory [expr 7*1100] + sqlite3_release_memory [expr 7*1132] list [nPage db] [nPage db2] } {10 3} do_test malloc5-6.3.3 { @@ -366,7 +366,7 @@ do_test malloc5-6.3.4 { # the rest of the db cache. But the db2 cache remains intact, because # SQLite tries to avoid calling sync(). if {$::tcl_platform(wordSize)==8} { - sqlite3_release_memory 10177 + sqlite3_release_memory 10500 } else { sqlite3_release_memory 9900 } diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 7eecf08..e14a1b3 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -68,7 +68,7 @@ proc reset_highwater_marks {} { sqlite3_status SQLITE_STATUS_PARSER_STACK 1 } -set xtra_size 256 +set xtra_size 290 # Test 1: Both PAGECACHE and SCRATCH are shut down. # @@ -97,9 +97,11 @@ reset_highwater_marks build_test_db memsubsys1-2 {PRAGMA page_size=1024} #show_memstats set MEMORY_MANAGEMENT $sqlite_options(memorymanage) -do_test memsubsys1-2.3 { - set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] -} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] +ifcapable !malloc_usable_size { + do_test memsubsys1-2.3 { + set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] + } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] +} do_test memsubsys1-2.4 { set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] } 20 diff --git a/test/multiplex.test b/test/multiplex.test index 3abdcf4..32c87d9 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -14,6 +14,16 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl +# The tests in this file assume that SQLite is compiled without +# ENABLE_8_3_NAMES. +# +ifcapable 8_3_names { + puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. " + puts "Skipping tests multiplex-*." + finish_test + return +} + set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_max_chunks 32 @@ -24,7 +34,7 @@ set g_max_chunks 32 # file name with the chunk number. proc multiplex_name {name chunk} { if {$chunk==0} { return $name } - set num [format "%02d" $chunk] + set num [format "%03d" $chunk] ifcapable {multiplex_ext_overwrite} { set name [string range $name 0 [expr [string length $name]-2-1]] } @@ -146,6 +156,9 @@ sqlite3_multiplex_initialize "" 1 multiplex_set db main 32768 16 forcedelete test.x +foreach f [glob -nocomplain {test.x*[0-9][0-9][0-9]}] { + forcedelete $f +} do_test multiplex-2.1.2 { sqlite3 db test.x execsql { @@ -182,12 +195,17 @@ do_test multiplex-2.4.2 { execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) } } {} do_test multiplex-2.4.4 { file size [multiplex_name test.x 0] } {7168} -do_test multiplex-2.4.99 { +do_test multiplex-2.4.5 { db close + sqlite3 db test.x + db eval vacuum + db close + glob test.x* +} {test.x} +do_test multiplex-2.4.99 { sqlite3_multiplex_shutdown } {SQLITE_OK} - do_test multiplex-2.5.1 { multiplex_delete test.x sqlite3_multiplex_initialize "" 1 diff --git a/test/multiplex2.test b/test/multiplex2.test new file mode 100644 index 0000000..bdfc05b --- /dev/null +++ b/test/multiplex2.test @@ -0,0 +1,70 @@ +# 2010 October 29 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +source $testdir/lock_common.tcl + + +do_multiclient_test tn { + code1 { catch { sqlite3_multiplex_initialize "" 0 } } + code2 { catch { sqlite3_multiplex_initialize "" 0 } } + + code1 { db close } + code2 { db2 close } + + code1 { sqlite3 db test.db -vfs multiplex } + code2 { sqlite3 db2 test.db -vfs multiplex } + + code1 { sqlite3_multiplex_control db main chunk_size [expr 1024*1024] } + code2 { sqlite3_multiplex_control db2 main chunk_size [expr 1024*1024] } + + sql1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 + do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 + sql2 { DELETE FROM t1 ; VACUUM } + do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 + + sql1 { + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 +} + +catch { sqlite3_multiplex_shutdown } +finish_test diff --git a/test/multiplex3.test b/test/multiplex3.test new file mode 100644 index 0000000..0f52d76 --- /dev/null +++ b/test/multiplex3.test @@ -0,0 +1,133 @@ + +# 2011 December 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for error (IO, OOM etc.) handling when using +# the multiplexor extension with 8.3 filenames. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix multiplex3 + +ifcapable !8_3_names { + puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. " + puts "Skipping tests multiplex3-*." + finish_test + return +} + +db close +sqlite3_shutdown +sqlite3_config_uri 1 +autoinstall_test_functions + +sqlite3_multiplex_initialize "" 1 + +proc destroy_vfs_stack {} { + generic_unregister stack + sqlite3_multiplex_shutdown +} + +proc multiplex_delete_db {} { + forcedelete test.db + for {set i 1} {$i <= 1000} {incr i} { + forcedelete test.[format %03d $i] + } +} + +# Procs to save and restore the current muliplexed database. +# +proc multiplex_save_db {} { + foreach f [glob -nocomplain sv_test.*] { forcedelete $f } + foreach f [glob -nocomplain test.*] { forcecopy $f "sv_$f" } +} +proc multiplex_restore_db {} { + foreach f [glob -nocomplain test.*] {forcedelete $f} + foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} } + +proc setup_and_save_db {} { + multiplex_delete_db + sqlite3 db file:test.db?8_3_names=1 + sqlite3_multiplex_control db main chunk_size [expr 256*1024] + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(randomblob(15), randomblob(2000)); + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 512 + } + set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}] + db close + multiplex_save_db +} + +do_test 1.0 { setup_and_save_db } {} +do_faultsim_test 1 -prep { + multiplex_restore_db + sqlite3 db file:test.db?8_3_names=1 + sqlite3_multiplex_control db main chunk_size [expr 256*1024] +} -body { + execsql { + UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0 + } +} -test { + faultsim_test_result {0 {}} + if {$testrc!=0} { + set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}] + if {$cksum2 != $::cksum1} { error "data mismatch" } + } +} + +#------------------------------------------------------------------------- +# The following tests verify that hot-journal rollback works. As follows: +# +# 1. Create a large database. +# 2. Set the pager cache to be very small. +# 3. Open a transaction. +# 4. Run the following 100 times: +# a. Update a row. +# b. Copy all files on disk to a new db location, including the journal. +# c. Verify that the new db can be opened and that the content matches +# the database created in step 1 (proving the journal was rolled +# back). + +do_test 2.0 { + setup_and_save_db + multiplex_restore_db + sqlite3 db file:test.db?8_3_names=1 + execsql { PRAGMA cache_size = 10 } + execsql { BEGIN } +} {} + +for {set iTest 1} {$iTest<=100} {incr iTest} { + do_test 2.$iTest { + execsql { + UPDATE t1 SET a=randomblob(12), b=randomblob(1400) WHERE rowid=5*$iTest + } + foreach f [glob -nocomplain test.*] {forcecopy $f "xx_$f"} + sqlite3 db2 file:xx_test.db?8_3_names=1 + execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2 + } $::cksum1 + + db2 close +} + +catch { db close } +sqlite3_multiplex_shutdown +finish_test diff --git a/test/pager1.test b/test/pager1.test index 0226fe4..99b25bd 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -990,8 +990,19 @@ do_test pager1-5.4.1 { INSERT INTO t2 VALUES(85, 'Gorbachev'); COMMIT; } - set ::max_journal -} [expr 2615+[string length [pwd]]] + + # The size of the journal file is now: + # + # 1) 512 byte header + + # 2) 2 * (1024+8) byte records + + # 3) 20+N bytes of master-journal pointer, where N is the size of + # the master-journal name encoded as utf-8 with no nul term. + # + set mj_pointer [expr { + 20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"] + }] + expr {$::max_journal==(512+2*(1024+8)+$mj_pointer)} +} 1 do_test pager1-5.4.2 { set ::max_journal 0 execsql { @@ -1001,8 +1012,16 @@ do_test pager1-5.4.2 { DELETE FROM t2 WHERE b = 'Lenin'; COMMIT; } - set ::max_journal -} [expr 3111+[string length [pwd]]] + + # In synchronous=full mode, the master-journal pointer is not written + # directly after the last record in the journal file. Instead, it is + # written starting at the next (in this case 512 byte) sector boundary. + # + set mj_pointer [expr { + 20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"] + }] + expr {$::max_journal==(((512+2*(1024+8)+511)/512)*512 + $mj_pointer)} +} 1 db close tv delete @@ -1312,6 +1331,7 @@ foreach sectorsize { 4096 8192 16384 32768 65536 131072 262144 } { tv sectorsize $sectorsize + tv devchar {} set eff $sectorsize if {$sectorsize < 512} { set eff 512 } if {$sectorsize > 65536} { set eff 65536 } diff --git a/test/permutations.test b/test/permutations.test index 7c3b026..f55db1b 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -110,8 +110,8 @@ set allquicktests [test_set $alltests -exclude { speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test thread003.test thread004.test thread005.test trans2.test vacuum3.test incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test - vtab_err.test walslow.test walcrash.test - walthread.test rtree3.test indexfault.test + vtab_err.test walslow.test walcrash.test walcrash3.test + walthread.test rtree3.test indexfault.test }] if {[info exists ::env(QUICKTEST_INCLUDE)]} { set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)] @@ -142,7 +142,7 @@ test_suite "valgrind" -prefix "" -description { Run the "veryquick" test suite with a couple of multi-process tests (that fail under valgrind) omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* + test_set $allquicktests -exclude *malloc* *ioerr* *fault* wal.test ] -initialize { set ::G(valgrind) 1 } -shutdown { @@ -530,6 +530,8 @@ test_suite "inmemory_journal" -description { # Exclude stmt.test, which expects sub-journals to use temporary files. stmt.test + zerodamage.test + # WAL mode is different. wal* tkt-2d1a5c67d.test backcompat.test }] diff --git a/test/pragma.test b/test/pragma.test index 0cad25a..cbe35ea 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -99,7 +99,7 @@ do_test pragma-1.5 { PRAGMA default_cache_size; PRAGMA synchronous; } -} [list 4321 $DFLT_CACHE_SZ 0] +} [list -4321 $DFLT_CACHE_SZ 0] do_test pragma-1.6 { execsql { PRAGMA synchronous=ON; @@ -107,7 +107,7 @@ do_test pragma-1.6 { PRAGMA default_cache_size; PRAGMA synchronous; } -} [list 4321 $DFLT_CACHE_SZ 1] +} [list -4321 $DFLT_CACHE_SZ 1] do_test pragma-1.7 { db close sqlite3 db test.db diff --git a/test/quota-glob.test b/test/quota-glob.test new file mode 100644 index 0000000..28c813c --- /dev/null +++ b/test/quota-glob.test @@ -0,0 +1,87 @@ +# 2011 December 1 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests for the glob-style string compare operator embedded in the +# quota shim. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +catch { unset testnum } +catch { unset pattern } +catch { unset text } +catch { unset ans } + +foreach {testnum pattern text ans} { + 1 abcdefg abcdefg 1 + 2 abcdefG abcdefg 0 + 3 abcdef abcdefg 0 + 4 abcdefgh abcdefg 0 + 5 abcdef? abcdefg 1 + 6 abcdef? abcdef 0 + 7 abcdef? abcdefgh 0 + 8 abcdefg abcdef? 0 + 9 abcdef? abcdef? 1 + 10 abc/def abc/def 1 + 11 abc//def abc/def 0 + 12 */abc/* x/abc/y 1 + 13 */abc/* /abc/ 1 + 16 */abc/* x///a/ab/abc 0 + 17 */abc/* x//a/ab/abc/ 1 + 16 */abc/* x///a/ab/abc 0 + 17 */abc/* x//a/ab/abc/ 1 + 18 **/abc/** x//a/ab/abc/ 1 + 19 *?/abc/*? x//a/ab/abc/y 1 + 20 ?*/abc/?* x//a/ab/abc/y 1 + 21 {abc[cde]efg} abcbefg 0 + 22 {abc[cde]efg} abccefg 1 + 23 {abc[cde]efg} abcdefg 1 + 24 {abc[cde]efg} abceefg 1 + 25 {abc[cde]efg} abcfefg 0 + 26 {abc[^cde]efg} abcbefg 1 + 27 {abc[^cde]efg} abccefg 0 + 28 {abc[^cde]efg} abcdefg 0 + 29 {abc[^cde]efg} abceefg 0 + 30 {abc[^cde]efg} abcfefg 1 + 31 {abc[c-e]efg} abcbefg 0 + 32 {abc[c-e]efg} abccefg 1 + 33 {abc[c-e]efg} abcdefg 1 + 34 {abc[c-e]efg} abceefg 1 + 35 {abc[c-e]efg} abcfefg 0 + 36 {abc[^c-e]efg} abcbefg 1 + 37 {abc[^c-e]efg} abccefg 0 + 38 {abc[^c-e]efg} abcdefg 0 + 39 {abc[^c-e]efg} abceefg 0 + 40 {abc[^c-e]efg} abcfefg 1 + 41 {abc[c-e]efg} abc-efg 0 + 42 {abc[-ce]efg} abc-efg 1 + 43 {abc[ce-]efg} abc-efg 1 + 44 {abc[][*?]efg} {abc]efg} 1 + 45 {abc[][*?]efg} {abc*efg} 1 + 46 {abc[][*?]efg} {abc?efg} 1 + 47 {abc[][*?]efg} {abc[efg} 1 + 48 {abc[^][*?]efg} {abc]efg} 0 + 49 {abc[^][*?]efg} {abc*efg} 0 + 50 {abc[^][*?]efg} {abc?efg} 0 + 51 {abc[^][*?]efg} {abc[efg} 0 + 52 {abc[^][*?]efg} {abcdefg} 1 + 53 {*[xyz]efg} {abcxefg} 1 + 54 {*[xyz]efg} {abcwefg} 0 +} { + do_test quota-glob-$testnum.1 { + sqlite3_quota_glob $::pattern $::text + } $::ans + do_test quota-glob-$testnum.2 { + sqlite3_quota_glob $::pattern [string map {/ \\} $::text] + } $::ans +} +finish_test diff --git a/test/quota.test b/test/quota.test index 49b403f..e12b83a 100644 --- a/test/quota.test +++ b/test/quota.test @@ -14,6 +14,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl +unset -nocomplain defaultVfs +set defaultVfs [file_control_vfsname db] db close do_test quota-1.1 { sqlite3_quota_initialize nosuchvfs 1 } {SQLITE_ERROR} @@ -48,6 +50,7 @@ do_test quota-1.8 { sqlite3_quota_shutdown } {SQLITE_OK} # sqlite3_quota_initialize "" 1 +unset -nocomplain quota_request_ok proc quota_check {filename limitvar size} { upvar $limitvar limit @@ -73,6 +76,9 @@ do_test quota-2.1.2 { } set ::quota } {} +do_test quota-2.1.2.1 { + file_control_vfsname db +} quota/$defaultVfs do_test quota-2.1.3 { file size test.db } {4096} do_test quota-2.1.4 { catchsql { INSERT INTO t1 VALUES(3, randomblob(1100)) } diff --git a/test/quota2.test b/test/quota2.test new file mode 100644 index 0000000..cf3449d --- /dev/null +++ b/test/quota2.test @@ -0,0 +1,236 @@ +# 2011 December 1 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl + +db close +sqlite3_quota_initialize "" 1 + +foreach dir {quota2a/x1 quota2a/x2 quota2a quota2b quota2c} { + file delete -force $dir +} +foreach dir {quota2a quota2a/x1 quota2a/x2 quota2b quota2c} { + file mkdir $dir +} + +# The standard_path procedure converts a pathname into a standard format +# that is the same across platforms. +# +unset -nocomplain ::quota_pwd ::quota_mapping +set ::quota_pwd [string map {\\ /} [pwd]] +set ::quota_mapping [list $::quota_pwd PWD] +proc standard_path {x} { + set x [string map {\\ /} $x] + return [string map $::quota_mapping $x] +} + +# The quota_check procedure is a callback from the quota handler. +# It has three arguments which are (1) the full pathname of the file +# that has gone over quota, (2) the quota limit, (3) the requested +# new quota size to cover the last write. These three values are +# appended to the global variable $::quota. The filename is processed +# to convert every \ character into / and to change the name of the +# working directory to PWD. +# +# The quota is increased to the request if the ::quota_request_ok +# global variable is true. +# +set ::quota {} +set ::quota_request_ok 0 + +proc quota_check {filename limitvar size} { + upvar $limitvar limit + lappend ::quota [standard_path $filename] [set limit] $size + if {$::quota_request_ok} {set limit $size} +} + +sqlite3_quota_set */quota2a/* 4000 quota_check +sqlite3_quota_set */quota2b/* 5000 quota_check + +unset -nocomplain bigtext +for {set i 1} {$i<=1000} {incr i} { + if {$i%10==0} { + append bigtext [format "%06d\n" $i] + } else { + append bigtext [format "%06d " $i] + } +} + +catch { unset h1 } +catch { unset x } +do_test quota2-1.1 { + set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+b] + sqlite3_quota_fwrite $::h1 1 7000 $bigtext +} {4000} +do_test quota2-1.2 { + set ::quota +} {PWD/quota2a/xyz.txt 4000 7000} +do_test quota2-1.3 { + sqlite3_quota_rewind $::h1 + set ::x [sqlite3_quota_fread $::h1 1001 7] + string length $::x +} {3003} +do_test quota2-1.4 { + string match $::x [string range $::bigtext 0 3002] +} {1} +do_test quota2-1.5 { + sqlite3_quota_fseek $::h1 0 SEEK_END + sqlite3_quota_ftell $::h1 +} {4000} +do_test quota2-1.6 { + sqlite3_quota_fseek $::h1 -100 SEEK_END + sqlite3_quota_ftell $::h1 +} {3900} +do_test quota2-1.7 { + sqlite3_quota_fseek $::h1 -100 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {3800} +do_test quota2-1.8 { + sqlite3_quota_fseek $::h1 50 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {3850} +do_test quota2-1.9 { + sqlite3_quota_fseek $::h1 50 SEEK_SET + sqlite3_quota_ftell $::h1 +} {50} +do_test quota2-1.10 { + sqlite3_quota_rewind $::h1 + sqlite3_quota_ftell $::h1 +} {0} +do_test quota2-1.11 { + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}} +do_test quota2-1.12 { + sqlite3_quota_fclose $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}} +do_test quota2-1.13 { + sqlite3_quota_remove quota2a/xyz.txt + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} + + +set quota {} +do_test quota2-2.1 { + set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b] + sqlite3_quota_fwrite $::h1 1 7000 $bigtext +} {7000} +do_test quota2-2.2 { + set ::quota +} {} +do_test quota2-2.3 { + sqlite3_quota_rewind $::h1 + set ::x [sqlite3_quota_fread $::h1 1001 7] + string length $::x +} {6006} +do_test quota2-2.4 { + string match $::x [string range $::bigtext 0 6005] +} {1} +do_test quota2-2.5 { + sqlite3_quota_fseek $::h1 0 SEEK_END + sqlite3_quota_ftell $::h1 +} {7000} +do_test quota2-2.6 { + sqlite3_quota_fseek $::h1 -100 SEEK_END + sqlite3_quota_ftell $::h1 +} {6900} +do_test quota2-2.7 { + sqlite3_quota_fseek $::h1 -100 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {6800} +do_test quota2-2.8 { + sqlite3_quota_fseek $::h1 50 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {6850} +do_test quota2-2.9 { + sqlite3_quota_fseek $::h1 50 SEEK_SET + sqlite3_quota_ftell $::h1 +} {50} +do_test quota2-2.10 { + sqlite3_quota_rewind $::h1 + sqlite3_quota_ftell $::h1 +} {0} +do_test quota2-2.11 { + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} +do_test quota2-2.12 { + sqlite3_quota_fclose $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} + +do_test quota2-3.1 { + sqlite3_quota_set */quota2b/* 0 quota_check + set ::h1 [sqlite3_quota_fopen quota2a/x1/a.txt a] + sqlite3_quota_fwrite $::h1 10 10 $bigtext +} {10} +do_test quota2-3.2 { + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3a { + sqlite3_quota_fflush $::h1 0 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3b { + sqlite3_quota_fflush $::h1 1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3c { + sqlite3_quota_fflush $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.4 { + sqlite3_quota_fclose $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.5 { + set ::h2 [sqlite3_quota_fopen quota2a/x2/b.txt a] + sqlite3_quota_fwrite $::h2 10 20 $bigtext + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 300 {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.6 { + set ::h3 [sqlite3_quota_fopen quota2a/x1/c.txt a] + sqlite3_quota_fwrite $::h3 10 50 $bigtext + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 800 {PWD/quota2a/x1/c.txt 500 1 0} {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.7 { + file exists quota2a/x1/a.txt +} {1} +do_test quota2-3.8 { + file exists quota2a/x2/b.txt +} {1} +do_test quota2-3.9 { + file exists quota2a/x1/c.txt +} {1} +do_test quota2-3.10 { + sqlite3_quota_remove quota2a/x1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 700 {PWD/quota2a/x1/c.txt 500 1 1} {PWD/quota2a/x2/b.txt 200 1 0}}} +do_test quota2-3.11 { + sqlite3_quota_fclose $::h2 + sqlite3_quota_fclose $::h3 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 200 {PWD/quota2a/x2/b.txt 200 0 0}}} +do_test quota2-3.12 { + file exists quota2a/x1/a.txt +} {0} +do_test quota2-3.13 { + file exists quota2a/x2/b.txt +} {1} +do_test quota2-3.14 { + file exists quota2a/x1/c.txt +} {0} + +catch { sqlite3_quota_shutdown } +catch { unset quota_request_ok } +finish_test diff --git a/test/selectB.test b/test/selectB.test index b9d979a..05ec9c6 100644 --- a/test/selectB.test +++ b/test/selectB.test @@ -194,19 +194,28 @@ do_test selectB-3.0 { } } {} -for {set ii 3} {$ii <= 4} {incr ii} { +for {set ii 3} {$ii <= 6} {incr ii} { - if {$ii == 4} { - do_test selectB-4.0 { - execsql { - CREATE INDEX i1 ON t1(a); - CREATE INDEX i2 ON t1(b); - CREATE INDEX i3 ON t1(c); - CREATE INDEX i4 ON t2(d); - CREATE INDEX i5 ON t2(e); - CREATE INDEX i6 ON t2(f); - } - } {} + switch $ii { + 4 { + optimization_control db query-flattener off + } + 5 { + optimization_control db query-flattener on + do_test selectB-5.0 { + execsql { + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + CREATE INDEX i3 ON t1(c); + CREATE INDEX i4 ON t2(d); + CREATE INDEX i5 ON t2(e); + CREATE INDEX i6 ON t2(f); + } + } {} + } + 6 { + optimization_control db query-flattener off + } } do_test selectB-$ii.1 { @@ -371,11 +380,47 @@ for {set ii 3} {$ii <= 4} {incr ii} { } } {2 4 6 3 6 9 8 10 12 12 15 18 14 16 18 21 24 27} - do_test selectB-$ii.21 { + do_test selectB-$ii.22 { execsql { SELECT * FROM (SELECT 345 UNION ALL SELECT d FROM t2) ORDER BY 1; } } {3 12 21 345} + + do_test selectB-$ii.23 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 80.1 180.1 200 400 800 1000 1400 1600} + + do_test selectB-$ii.24 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 20.1 {} 80.1 180.1 140.1 {} 200 400 800 1000 1400 1600} + + do_test selectB-$ii.25 { + execsql { + SELECT x+y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) WHERE y+x NOT NULL ORDER BY 1; + } + } {6 18 30 260.2 600 1800 3000} } finish_test diff --git a/test/shrink.test b/test/shrink.test new file mode 100644 index 0000000..e03ebee --- /dev/null +++ b/test/shrink.test @@ -0,0 +1,43 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains test cases for sqlite3_db_release_memory and +# the PRAGMA shrink_memory statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +unset -nocomplain baseline +do_test shrink-1.1 { + db eval { + PRAGMA cache_size = 2000; + CREATE TABLE t1(x,y); + INSERT INTO t1 VALUES(randomblob(1000000),1); + } + set ::baseline sqlite3_memory_used + sqlite3_db_release_memory db + expr {$::baseline > [sqlite3_memory_used]+500000} +} {1} +do_test shrink-1.2 { + set baseline [sqlite3_memory_used] + db eval { + UPDATE t1 SET y=y+1; + } + expr {$::baseline+500000 < [sqlite3_memory_used]} +} {1} +do_test shrink-1.3 { + set baseline [sqlite3_memory_used] + db eval {PRAGMA shrink_memory} + expr {$::baseline > [sqlite3_memory_used]+500000} +} {1} + +finish_test diff --git a/test/superlock.test b/test/superlock.test index 8155d92..8199d52 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -76,7 +76,10 @@ do_catchsql_test 3.4 { INSERT INTO t1 VALUES(5, 6)} {1 {database is locked}} do_catchsql_test 3.5 { PRAGMA wal_checkpoint } {0 {1 -1 -1}} do_test 3.6 { unlock } {} -do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 2 2} +# At this point the WAL file consists of a single frame only - written +# by test case 3.1. If the ZERO_DAMAGE flag were not set, it would consist +# of two frames - the frame written by 3.1 and a padding frame. +do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 1 1} do_test 4.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 4.3 { SELECT * FROM t1 } {1 {database is locked}} diff --git a/test/syscall.test b/test/syscall.test index 201bd63..dde4b46 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -59,7 +59,8 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0 foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate - pread64 pwrite64 unlink openDirectory + pread64 pwrite64 unlink openDirectory mkdir rmdir + statvfs } { if {[test_syscall exists $s]} {lappend syscall_list $s} } diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 0ed0602..c8b0303 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -25,7 +25,7 @@ source $testdir/tester.tcl if {[sqlite3 -has-codec]} { set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?" } else { - set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" + set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" } do_test tcl-1.1 { set v [catch {sqlite3 bogus} msg] diff --git a/test/tester.tcl b/test/tester.tcl index 3c34b45..e27a483 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -57,7 +57,7 @@ # Commands providing a lower level interface to the global test counters: # # set_test_counter COUNTER ?VALUE? -# omit_test TESTNAME REASON +# omit_test TESTNAME REASON ?APPEND? # fail_test TESTNAME # incr_ntest # @@ -274,6 +274,7 @@ if {[info exists cmdlinearg]==0} { # --file-retries=N # --file-retry-delay=N # --start=[$permutation:]$testfile + # --match=$pattern # set cmdlinearg(soft-heap-limit) 0 set cmdlinearg(maxerror) 1000 @@ -283,7 +284,8 @@ if {[info exists cmdlinearg]==0} { set cmdlinearg(soak) 0 set cmdlinearg(file-retries) 0 set cmdlinearg(file-retry-delay) 0 - set cmdlinearg(start) "" + set cmdlinearg(start) "" + set cmdlinearg(match) "" set leftover [list] foreach a $argv { @@ -336,6 +338,12 @@ if {[info exists cmdlinearg]==0} { } if {$::G(start:file) == ""} {unset ::G(start:file)} } + {^-+match=.+$} { + foreach {dummy cmdlinearg(match)} [split $a =] break + + set ::G(match) $cmdlinearg(match) + if {$::G(match) == ""} {unset ::G(match)} + } default { lappend leftover $a } @@ -414,9 +422,11 @@ if {0==[info exists ::SLAVE]} { # Record the fact that a sequence of tests were omitted. # -proc omit_test {name reason} { +proc omit_test {name reason {append 1}} { set omitList [set_test_counter omit_list] - lappend omitList [list $name $reason] + if {$append} { + lappend omitList [list $name $reason] + } set_test_counter omit_list $omitList } @@ -471,14 +481,20 @@ proc do_test {name cmd expected} { incr_ntest puts -nonewline $name... flush stdout - if {[catch {uplevel #0 "$cmd;\n"} result]} { - puts "\nError: $result" - fail_test $name - } elseif {[string compare $result $expected]} { - puts "\nExpected: \[$expected\]\n Got: \[$result\]" - fail_test $name + + if {![info exists ::G(match)] || [string match $::G(match) $name]} { + if {[catch {uplevel #0 "$cmd;\n"} result]} { + puts "\nError: $result" + fail_test $name + } elseif {[string compare $result $expected]} { + puts "\nExpected: \[$expected\]\n Got: \[$result\]" + fail_test $name + } else { + puts " Ok" + } } else { - puts " Ok" + puts " Omitted" + omit_test $name "pattern mismatch" 0 } flush stdout } diff --git a/test/tkt-3a77c9714e.test b/test/tkt-3a77c9714e.test new file mode 100644 index 0000000..d77ee42 --- /dev/null +++ b/test/tkt-3a77c9714e.test @@ -0,0 +1,68 @@ +# 2011 December 06 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to verify that ticket [3a77c9714e] has been +# fixed. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix "tkt-3a77c9714e" + +do_execsql_test 1.1 { + CREATE TABLE t1(t1_id INTEGER PRIMARY KEY, t1_title TEXT); + CREATE TABLE t2(t2_id INTEGER PRIMARY KEY, t2_title TEXT); + CREATE TABLE t3(t3_id INTEGER PRIMARY KEY, t3_title TEXT); + + INSERT INTO t1 (t1_id, t1_title) VALUES (888, 'ABCDEF'); + INSERT INTO t2 (t2_id, t2_title) VALUES (999, 'ABCDEF'); + INSERT INTO t3 (t3_id, t3_title) VALUES (999, 'ABCDEF'); +} + +do_execsql_test 1.2 { + SELECT t1_title, t2_title + FROM t1 LEFT JOIN t2 + WHERE + t2_id = (SELECT t3_id FROM + ( SELECT t3_id FROM t3 WHERE t3_title=t1_title LIMIT 500 ) + ) +} {ABCDEF ABCDEF} + +do_execsql_test 2.1 { + CREATE TABLE [Beginnings] ( + [Id] INTEGER PRIMARY KEY AUTOINCREMENT,[Title] TEXT, [EndingId] INTEGER + ); + CREATE TABLE [Endings] (Id INT,Title TEXT,EndingId INT); + INSERT INTO Beginnings (Id, Title, EndingId) VALUES (1, 'FACTOR', 18); + INSERT INTO Beginnings (Id, Title, EndingId) VALUES (2, 'SWIMM', 18); + INSERT INTO Endings (Id, Title, EndingId) VALUES (1, 'ING', 18); +} + +do_execsql_test 2.2 { + SELECT + SrcWord, Beginnings.Title + FROM + (SELECT 'FACTORING' AS SrcWord UNION SELECT 'SWIMMING' AS SrcWord ) + LEFT JOIN + Beginnings + WHERE Beginnings.Id= ( + SELECT BeginningId FROM ( + SELECT SrcWord, B.Id as BeginningId, B.Title || E.Title As Connected + FROM Beginnings B LEFT JOIN Endings E ON B.EndingId=E.EndingId + WHERE Connected=SrcWord LIMIT 1 + ) + ) +} {FACTORING FACTOR SWIMMING SWIMM} + + +finish_test + diff --git a/test/tkt-7bbfb7d442.test b/test/tkt-7bbfb7d442.test new file mode 100644 index 0000000..e560a0d --- /dev/null +++ b/test/tkt-7bbfb7d442.test @@ -0,0 +1,154 @@ +# 2011 December 9 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to verify that ticket [7bbfb7d442] has been +# fixed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tkt-7bbfb7d442 + +do_execsql_test 1.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + + CREATE TABLE t2(c, d); + INSERT INTO t2 VALUES('one', 'I'); + INSERT INTO t2 VALUES('two', 'II'); + INSERT INTO t2 VALUES('three', 'III'); + + CREATE TABLE t3(t3_a PRIMARY KEY, t3_d); + CREATE TRIGGER t3t AFTER INSERT ON t3 WHEN new.t3_d IS NULL BEGIN + UPDATE t3 SET t3_d = ( + SELECT d FROM + (SELECT * FROM t2 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10), + (SELECT * FROM t1 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10) + WHERE a = new.t3_a AND b = c + ) WHERE t3_a = new.t3_a; + END; +} + +do_execsql_test 1.2 { + INSERT INTO t3(t3_a) VALUES(1); + INSERT INTO t3(t3_a) VALUES(2); + INSERT INTO t3(t3_a) VALUES(3); + SELECT * FROM t3; +} {1 I 2 II 3 III} + +do_execsql_test 1.3 { DELETE FROM t3 } + +do_execsql_test 1.4 { + INSERT INTO t3(t3_a) SELECT 1 UNION SELECT 2 UNION SELECT 3; + SELECT * FROM t3; +} {1 I 2 II 3 III} + + + +#------------------------------------------------------------------------- +# The following test case - 2.* - is from the original bug report as +# posted to the mailing list. +# +do_execsql_test 2.1 { + CREATE TABLE InventoryControl ( + InventoryControlId INTEGER PRIMARY KEY AUTOINCREMENT, + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + ControlDate DATE NOT NULL, + ControlState INTEGER NOT NULL DEFAULT -1, + DeliveredQty VARCHAR(30) + ); + + CREATE TRIGGER TGR_InventoryControl_AfterInsert + AFTER INSERT ON InventoryControl + FOR EACH ROW WHEN NEW.ControlState=-1 BEGIN + + INSERT OR REPLACE INTO InventoryControl( + InventoryControlId,SKU,Variant,ControlDate,ControlState,DeliveredQty + ) SELECT + T1.InventoryControlId AS InventoryControlId, + T1.SKU AS SKU, + T1.Variant AS Variant, + T1.ControlDate AS ControlDate, + 1 AS ControlState, + COALESCE(T2.DeliveredQty,0) AS DeliveredQty + FROM ( + SELECT + NEW.InventoryControlId AS InventoryControlId, + II.SKU AS SKU, + II.Variant AS Variant, + COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS ControlDate + FROM + InventoryItem II + LEFT JOIN + InventoryControl LastClosedIC + ON LastClosedIC.InventoryControlId IN ( SELECT 99999 ) + WHERE + II.SKU=NEW.SKU AND + II.Variant=NEW.Variant + ) T1 + LEFT JOIN ( + SELECT + TD.SKU AS SKU, + TD.Variant AS Variant, + 10 AS DeliveredQty + FROM + TransactionDetail TD + WHERE + TD.SKU=NEW.SKU AND + TD.Variant=NEW.Variant + ) T2 + ON T2.SKU=T1.SKU AND + T2.Variant=T1.Variant; + END; + + CREATE TABLE InventoryItem ( + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + DeptCode INTEGER NOT NULL, + GroupCode INTEGER NOT NULL, + ItemDescription VARCHAR(120) NOT NULL, + PRIMARY KEY(SKU, Variant) + ); + + INSERT INTO InventoryItem VALUES(220,0,1,170,'Scoth Tampon Recurer'); + INSERT INTO InventoryItem VALUES(31,0,1,110,'Fromage'); + + CREATE TABLE TransactionDetail ( + TransactionId INTEGER NOT NULL, + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY(TransactionId, SKU, Variant) + ); + INSERT INTO TransactionDetail(TransactionId, SKU, Variant) VALUES(44, 31, 0); + + + INSERT INTO InventoryControl(SKU, Variant, ControlDate) SELECT + II.SKU AS SKU, II.Variant AS Variant, '2011-08-30' AS ControlDate + FROM InventoryItem II; +} + +do_execsql_test 2.2 { + SELECT SKU, DeliveredQty FROM InventoryControl WHERE SKU=31 +} {31 10} + +do_execsql_test 2.3 { + SELECT CASE WHEN DeliveredQty=10 THEN "TEST PASSED!" ELSE "TEST FAILED!" END + FROM InventoryControl WHERE SKU=31; +} {{TEST PASSED!}} + + +finish_test + + diff --git a/test/unixexcl.test b/test/unixexcl.test index 057ae0a..0147e6b 100644 --- a/test/unixexcl.test +++ b/test/unixexcl.test @@ -80,4 +80,49 @@ do_multiclient_test tn { } {0 {hello world}} } +do_multiclient_test tn { + do_test unixexcl-3.$tn.1 { + code1 { db close; sqlite3 db file:test.db?psow=0 -vfs unix-excl -uri 1 } + code2 { db2 close; sqlite3 db2 file:test.db?psow=0 -vfs unix-excl -uri 1 } + sql1 { + PRAGMA auto_vacuum = 0; + PRAGMA journal_mode = WAL; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + } + } {wal} + + if {$tn==1} { + do_test unixexcl-3.$tn.1.multiproc { + csql2 { SELECT * FROM t1; } + } {1 {database is locked}} + } else { + do_test unixexcl-3.$tn.1.singleproc { + sql2 { SELECT * FROM t1; } + } {1 2} + + do_test unixexcl-3.$tn.2 { + sql2 { + BEGIN; + SELECT * FROM t1; + } + } {1 2} + do_test unixexcl-3.$tn.3 { + sql1 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(3, 4); } + } {0 3 3} + do_test unixexcl-3.$tn.4 { + sql2 { SELECT * FROM t1; } + } {1 2} + do_test unixexcl-3.$tn.5 { + sql1 { SELECT * FROM t1; } + } {1 2 3 4} + do_test unixexcl-3.$tn.6 { + sql2 { COMMIT; SELECT * FROM t1; } + } {1 2 3 4} + do_test unixexcl-3.$tn.7 { + sql1 { PRAGMA wal_checkpoint; } + } {0 4 4} + } +} + finish_test diff --git a/test/wal.test b/test/wal.test index 056becf..3b63d3e 100644 --- a/test/wal.test +++ b/test/wal.test @@ -416,6 +416,7 @@ do_test wal-8.3 { do_test wal-9.1 { reopen_db execsql { + PRAGMA cache_size=2000; CREATE TABLE t1(x PRIMARY KEY); INSERT INTO t1 VALUES(blob(900)); INSERT INTO t1 VALUES(blob(900)); @@ -545,7 +546,7 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10} do_test wal-10.$tn.12 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 13 13}} ;# Reader no longer block checkpoints + } {0 {0 7 7}} ;# Reader no longer block checkpoints do_test wal-10.$tn.13 { execsql { INSERT INTO t1 VALUES(11, 12) } sql2 {SELECT * FROM t1} @@ -555,7 +556,7 @@ do_multiclient_test tn { # do_test wal-10.$tn.14 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 13}} + } {0 {0 8 7}} # The following series of test cases used to verify another blocking # case in WAL - a case which no longer blocks. @@ -565,10 +566,10 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10 11 12} do_test wal-10.$tn.16 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 15}} + } {0 {0 8 8}} do_test wal-10.$tn.17 { execsql { PRAGMA wal_checkpoint } - } {0 15 15} + } {0 8 8} do_test wal-10.$tn.18 { sql3 { BEGIN; SELECT * FROM t1 } } {1 2 3 4 5 6 7 8 9 10 11 12} @@ -591,13 +592,13 @@ do_multiclient_test tn { # do_test wal-10.$tn.23 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.24 { sql2 { BEGIN; SELECT * FROM t1; } } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} do_test wal-10.$tn.25 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.26 { catchsql { INSERT INTO t1 VALUES(15, 16) } } {0 {}} @@ -614,11 +615,11 @@ do_multiclient_test tn { do_test wal-10.$tn.29 { execsql { INSERT INTO t1 VALUES(19, 20) } catchsql { PRAGMA wal_checkpoint } - } {0 {0 6 0}} + } {0 {0 3 0}} do_test wal-10.$tn.30 { code3 { sqlite3_finalize $::STMT } execsql { PRAGMA wal_checkpoint } - } {0 6 0} + } {0 3 0} # At one point, if a reader failed to upgrade to a writer because it # was reading an old snapshot, the write-locks were not being released. @@ -657,7 +658,7 @@ do_multiclient_test tn { } {a b c d} do_test wal-10.$tn.36 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 16 16}} + } {0 {0 8 8}} do_test wal-10.$tn.36 { sql3 { INSERT INTO t1 VALUES('e', 'f') } sql2 { SELECT * FROM t1 } @@ -665,7 +666,7 @@ do_multiclient_test tn { do_test wal-10.$tn.37 { sql2 COMMIT execsql { PRAGMA wal_checkpoint } - } {0 18 18} + } {0 9 9} } #------------------------------------------------------------------------- @@ -1039,7 +1040,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 7 {db eval "PRAGMA main.wal_checkpoint"} {0 10 10} 1 0 - 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 16 16} 0 1 + 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 13 13} 0 1 9 {db eval "PRAGMA temp.wal_checkpoint"} {0 -1 -1} 0 0 } { do_test wal-16.$tn.1 { @@ -1053,7 +1054,8 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { PRAGMA aux.auto_vacuum = 0; PRAGMA main.journal_mode = WAL; PRAGMA aux.journal_mode = WAL; - PRAGMA synchronous = NORMAL; + PRAGMA main.synchronous = NORMAL; + PRAGMA aux.synchronous = NORMAL; } } {wal wal} @@ -1071,7 +1073,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { } [list [expr 1*1024] [wal_file_size 10 1024]] do_test wal-16.$tn.3 { list [file size test2.db] [file size test2.db-wal] - } [list [expr 1*1024] [wal_file_size 16 1024]] + } [list [expr 1*1024] [wal_file_size 13 1024]] do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res @@ -1081,7 +1083,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { do_test wal-16.$tn.6 { list [file size test2.db] [file size test2.db-wal] - } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 16 1024]] + } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 13 1024]] catch { db close } } @@ -1124,6 +1126,7 @@ foreach {tn sectorsize logsize} " execsql { PRAGMA auto_vacuum = 0; PRAGMA page_size = 512; + PRAGMA cache_size = -2000; PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL; } @@ -1550,9 +1553,13 @@ ifcapable autovacuum { } file size test.db } [expr 3 * 1024] + + # WAL file now contains a single frame - the new root page for table t1. + # It would be two frames (the new root page and a padding frame) if the + # ZERO_DAMAGE flag were not set. do_test 24.5 { file size test.db-wal - } 2128 + } [wal_file_size 1 1024] } db close diff --git a/test/wal2.test b/test/wal2.test index f488706..c7f00ea 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -361,7 +361,9 @@ do_test wal2-4.1 { INSERT INTO data VALUES('need xShmOpen to see this'); PRAGMA wal_checkpoint; } -} {wal 0 5 5} + # Three pages in the WAL file at this point: One copy of page 1 and two + # of the root page for table "data". +} {wal 0 3 3} do_test wal2-4.2 { db close testvfs tvfs -noshm 1 @@ -730,7 +732,7 @@ do_test wal2-6.5.1 { INSERT INTO t2 VALUES('I', 'II'); PRAGMA journal_mode; } -} {wal exclusive 0 3 3 wal} +} {wal exclusive 0 2 2 wal} do_test wal2-6.5.2 { execsql { PRAGMA locking_mode = normal; @@ -741,7 +743,7 @@ do_test wal2-6.5.2 { } {normal exclusive I II III IV} do_test wal2-6.5.3 { execsql { PRAGMA wal_checkpoint } -} {0 4 4} +} {0 2 2} db close proc lock_control {method filename handle spec} { @@ -1176,14 +1178,15 @@ if {$::tcl_platform(platform) == "unix"} { # Test that "PRAGMA checkpoint_fullsync" appears to be working. # foreach {tn sql reslist} { - 1 { } {8 0 3 0 5 0} - 2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2} - 3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0} + 1 { } {10 0 4 0 6 0} + 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} + 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { faultsim_delete_and_reopen execsql {PRAGMA auto_vacuum = 0} execsql $sql + do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 @@ -1192,14 +1195,14 @@ foreach {tn sql reslist} { do_execsql_test wal2-14.$tn.2 { PRAGMA wal_autocheckpoint = 10; CREATE TABLE t1(a, b); -- 2 wal syncs - INSERT INTO t1 VALUES(1, 2); -- 1 wal sync + INSERT INTO t1 VALUES(1, 2); -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync BEGIN; INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); - COMMIT; -- 1 wal sync + COMMIT; -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync - } {10 0 5 5 0 2 2} + } {10 0 3 3 0 1 1} do_test wal2-14.$tn.3 { cond_incr_sync_count 1 @@ -1233,22 +1236,22 @@ catch { db close } # PRAGMA fullfsync # PRAGMA synchronous # -foreach {tn settings commit_sync ckpt_sync} { - 1 {0 0 off} {0 0} {0 0} - 2 {0 0 normal} {0 0} {2 0} - 3 {0 0 full} {1 0} {2 0} +foreach {tn settings restart_sync commit_sync ckpt_sync} { + 1 {0 0 off} {0 0} {0 0} {0 0} + 2 {0 0 normal} {1 0} {0 0} {2 0} + 3 {0 0 full} {2 0} {1 0} {2 0} - 4 {0 1 off} {0 0} {0 0} - 5 {0 1 normal} {0 0} {0 2} - 6 {0 1 full} {0 1} {0 2} + 4 {0 1 off} {0 0} {0 0} {0 0} + 5 {0 1 normal} {0 1} {0 0} {0 2} + 6 {0 1 full} {0 2} {0 1} {0 2} - 7 {1 0 off} {0 0} {0 0} - 8 {1 0 normal} {0 0} {0 2} - 9 {1 0 full} {1 0} {0 2} + 7 {1 0 off} {0 0} {0 0} {0 0} + 8 {1 0 normal} {1 0} {0 0} {0 2} + 9 {1 0 full} {2 0} {1 0} {0 2} - 10 {1 1 off} {0 0} {0 0} - 11 {1 1 normal} {0 0} {0 2} - 12 {1 1 full} {0 1} {0 2} + 10 {1 1 off} {0 0} {0 0} {0 0} + 11 {1 1 normal} {0 1} {0 0} {0 2} + 12 {1 1 full} {0 2} {0 1} {0 2} } { forcedelete test.db @@ -1261,28 +1264,38 @@ foreach {tn settings commit_sync ckpt_sync} { sqlite3 db test.db do_execsql_test 15.$tn.1 " + PRAGMA page_size = 4096; CREATE TABLE t1(x); + PRAGMA wal_autocheckpoint = OFF; PRAGMA journal_mode = WAL; PRAGMA checkpoint_fullfsync = [lindex $settings 0]; PRAGMA fullfsync = [lindex $settings 1]; PRAGMA synchronous = [lindex $settings 2]; - " {wal} + " {0 wal} +if { $tn==2} breakpoint do_test 15.$tn.2 { set sync(normal) 0 set sync(full) 0 execsql { INSERT INTO t1 VALUES('abc') } list $::sync(normal) $::sync(full) + } $restart_sync + + do_test 15.$tn.3 { + set sync(normal) 0 + set sync(full) 0 + execsql { INSERT INTO t1 VALUES('abc') } + list $::sync(normal) $::sync(full) } $commit_sync - do_test 15.$tn.3 { + do_test 15.$tn.4 { set sync(normal) 0 set sync(full) 0 execsql { INSERT INTO t1 VALUES('def') } list $::sync(normal) $::sync(full) } $commit_sync - do_test 15.$tn.4 { + do_test 15.$tn.5 { set sync(normal) 0 set sync(full) 0 execsql { PRAGMA wal_checkpoint } diff --git a/test/wal3.test b/test/wal3.test index ea5e705..ccab93e 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -217,6 +217,7 @@ foreach {tn syncmode synccount} { execsql "PRAGMA synchronous = $syncmode" execsql { PRAGMA journal_mode = WAL } + execsql { CREATE TABLE filler(a,b,c); } set ::syncs [list] T filter xSync @@ -428,7 +429,7 @@ do_test wal3-6.1.2 { } {o t t f} do_test wal3-6.1.3 { execsql { PRAGMA wal_checkpoint } db2 -} {0 7 7} +} {0 4 4} # At this point the log file has been fully checkpointed. However, # connection [db3] holds a lock that prevents the log from being wrapped. @@ -517,7 +518,7 @@ proc lock_callback {method file handle spec} { } do_test wal3-6.2.2 { execsql { PRAGMA wal_checkpoint } -} {0 7 7} +} {0 4 4} do_test wal3-6.2.3 { set ::R } {h h l b} @@ -627,7 +628,7 @@ do_test wal3-8.1 { INSERT INTO b VALUES('Markazi'); PRAGMA wal_checkpoint; } -} {wal 0 9 9} +} {wal 0 5 5} do_test wal3-8.2 { execsql { SELECT * FROM b } } {Tehran Qom Markazi} diff --git a/test/wal5.test b/test/wal5.test index ad6bcfc..6eceed5 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -197,9 +197,9 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 5} - do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 5 5} - do_test 2.1.$tn.4 { file_page_counts } {2 5 2 5} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 3} + do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 3 3} + do_test 2.1.$tn.4 { file_page_counts } {2 3 2 3} } do_multiclient_test tn { @@ -213,10 +213,10 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(3, 4); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 7} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 4} do_test 2.2.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} - do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 5 5} - do_test 2.2.$tn.5 { file_page_counts } {2 5 2 7} + do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 3 3} + do_test 2.2.$tn.5 { file_page_counts } {2 3 2 4} } do_multiclient_test tn { @@ -229,13 +229,13 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.3.$tn.2 { file_page_counts } {1 5 1 5} + do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3} do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {} do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {} - do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7} - do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5} - do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7} + do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4} + do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3} + do_test 2.3.$tn.8 { file_page_counts } {1 4 2 4} } # Check that checkpoints block on the correct locks. And respond correctly @@ -256,18 +256,18 @@ foreach {testprefix do_wal_checkpoint} { # processes holding all three types of locks. # foreach {tn1 checkpoint busy_on ckpt_expected expected} { - 1 PASSIVE - {0 5 5} - - 2 TYPO - {0 5 5} - + 1 PASSIVE - {0 3 3} - + 2 TYPO - {0 3 3} - - 3 FULL - {0 7 7} 2 - 4 FULL 1 {1 5 5} 1 - 5 FULL 2 {1 7 5} 2 - 6 FULL 3 {0 7 7} 2 + 3 FULL - {0 4 4} 2 + 4 FULL 1 {1 3 3} 1 + 5 FULL 2 {1 4 3} 2 + 6 FULL 3 {0 4 4} 2 - 7 RESTART - {0 7 7} 3 - 8 RESTART 1 {1 5 5} 1 - 9 RESTART 2 {1 7 5} 2 - 10 RESTART 3 {1 7 7} 3 + 7 RESTART - {0 4 4} 3 + 8 RESTART 1 {1 3 3} 1 + 9 RESTART 2 {1 4 3} 2 + 10 RESTART 3 {1 4 4} 3 } { do_multiclient_test tn { diff --git a/test/walcrash.test b/test/walcrash.test index cfce5fe..adc4841 100644 --- a/test/walcrash.test +++ b/test/walcrash.test @@ -76,7 +76,7 @@ for {set i 1} {$i < $REPEATS} {incr i} { for {set i 1} {$i < $REPEATS} {incr i} { forcedelete test.db test.db-wal do_test walcrash-2.$i.1 { - crashsql -delay 4 -file test.db-wal -seed [incr seed] { + crashsql -delay 5 -file test.db-wal -seed [incr seed] { PRAGMA journal_mode = WAL; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, 2); @@ -147,7 +147,7 @@ for {set i 1} {$i < $REPEATS} {incr i} { forcedelete test2.db test2.db-wal do_test walcrash-4.$i.1 { - crashsql -delay 3 -file test.db-wal -seed [incr seed] -blocksize 4096 { + crashsql -delay 4 -file test.db-wal -seed [incr seed] -blocksize 4096 { PRAGMA journal_mode = WAL; PRAGMA page_size = 1024; CREATE TABLE t1(a PRIMARY KEY, b); @@ -175,7 +175,7 @@ for {set i 1} {$i < $REPEATS} {incr i} { forcedelete test2.db test2.db-wal do_test walcrash-5.$i.1 { - crashsql -delay 11 -file test.db-wal -seed [incr seed] -blocksize 4096 { + crashsql -delay 13 -file test.db-wal -seed [incr seed] -blocksize 4096 { PRAGMA journal_mode = WAL; PRAGMA page_size = 1024; BEGIN; @@ -216,7 +216,7 @@ for {set i 1} {$i < $REPEATS} {incr i} { forcedelete test2.db test2.db-wal do_test walcrash-6.$i.1 { - crashsql -delay 12 -file test.db-wal -seed [incr seed] -blocksize 512 { + crashsql -delay 14 -file test.db-wal -seed [incr seed] -blocksize 512 { PRAGMA journal_mode = WAL; PRAGMA page_size = 1024; BEGIN; @@ -234,9 +234,9 @@ for {set i 1} {$i < $REPEATS} {incr i} { INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 32 */ PRAGMA wal_checkpoint; - INSERT INTO t1 VALUES(randomblob(900)); - INSERT INTO t1 VALUES(randomblob(900)); - INSERT INTO t1 VALUES(randomblob(900)); + INSERT INTO t1 VALUES(randomblob(9000)); + INSERT INTO t1 VALUES(randomblob(9000)); + INSERT INTO t1 VALUES(randomblob(9000)); } } {1 {child process exited abnormally}} diff --git a/test/walcrash3.test b/test/walcrash3.test new file mode 100644 index 0000000..c2c9a6d --- /dev/null +++ b/test/walcrash3.test @@ -0,0 +1,129 @@ +# 2011 December 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This test simulates an application crash immediately following a +# system call to truncate a file. Specifically, the system call that +# truncates the WAL file if "PRAGMA journal_size_limit" is configured. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !wal {finish_test ; return } +set testprefix walcrash3 + +db close +testvfs tvfs +tvfs filter {xTruncate xWrite} +tvfs script tvfs_callback +proc tvfs_callback {args} {} + +sqlite3 db test.db -vfs tvfs +do_execsql_test 1.1 { + PRAGMA page_size = 1024; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint = 128; + PRAGMA journal_size_limit = 16384; + + CREATE TABLE t1(a BLOB, b BLOB, UNIQUE(a, b)); + INSERT INTO t1 VALUES(randomblob(10), randomblob(1000)); +} {wal 128 16384} + +proc tvfs_callback {method file arglist} { + if {$::state==1} { + foreach f [glob -nocomplain xx_test.*] { forcedelete $f } + foreach f [glob -nocomplain test.*] { forcecopy $f "xx_$f" } + set ::state 2 + } + if {$::state==0 && $method=="xTruncate" && [file tail $file]=="test.db-wal"} { + set ::state 1 + } +} + +for {set i 2} {$i<1000} {incr i} { + + # If the WAL file is truncated within the following, within the following + # xWrite call the [tvfs_callback] makes a copy of the database and WAL + # files set sets $::state to 2. So that the copied files are in the same + # state as the real database and WAL files would be if an application crash + # occurred immediately following the xTruncate(). + # + set ::state 0 + do_execsql_test 1.$i.1 { + INSERT INTO t1 VALUES(randomblob(10), randomblob(1000)); + } + + # If a copy was made, open it and run the integrity-check. + # + if {$::state==2} { + sqlite3 db2 xx_test.db + do_test 1.$i.2 { execsql { PRAGMA integrity_check } db2 } "ok" + do_test 1.$i.3 { execsql { SELECT count(*) FROM t1 } db2 } [expr $i-1] + db2 close + } +} +catch { db close } +tvfs delete + +#-------------------------------------------------------------------------- +# +catch { db close } +forcedelete test.db + +do_test 2.1 { + sqlite3 db test.db + execsql { + PRAGMA page_size = 512; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint = 128; + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(randomblob(25), randomblob(200)); + } + + for {set i 0} {$i < 1500} {incr i} { + execsql { INSERT INTO t1 VALUES(randomblob(25), randomblob(200)) } + } + + db_save + db close +} {} + +set nInitialErr [set_test_counter errors] +for {set i 2} {$i<10000 && [set_test_counter errors]==$nInitialErr} {incr i} { + + do_test 2.$i.1 { + catch { db close } + db_restore + crashsql -delay 2 -file test.db-wal -seed $i { + SELECT * FROM sqlite_master; + PRAGMA synchronous = full; + PRAGMA wal_checkpoint; + BEGIN; + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + COMMIT; + } + } {1 {child process exited abnormally}} + + do_test 2.$i.2 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } + } {ok} +} + +finish_test + diff --git a/test/walfault.test b/test/walfault.test index 1b71d78..6f9aedd 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -123,7 +123,6 @@ do_faultsim_test walfault-3 -prep { faultsim_test_result {0 {}} } - #-------------------------------------------------------------------------- # if {[permutation] != "inmemory_journal"} { @@ -141,7 +140,9 @@ if {[permutation] != "inmemory_journal"} { SELECT * FROM t1; } } -test { - faultsim_test_result {0 {wal 0 7 7 a b}} + # Update: The following changed from {0 {wal 0 7 7 a b}} as a result + # of PSOW being set by default. + faultsim_test_result {0 {wal 0 5 5 a b}} faultsim_integrity_check } } @@ -542,10 +543,11 @@ do_faultsim_test walfault-14 -prep { INSERT INTO abc VALUES(randomblob(1500)); } } -test { - faultsim_test_result {0 {0 10 10}} + faultsim_test_result {0 {0 9 9}} faultsim_integrity_check set nRow [db eval {SELECT count(*) FROM abc}] if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" } } +finish_test finish_test diff --git a/test/walpersist.test b/test/walpersist.test index 175dcbf..692728d 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -67,7 +67,60 @@ do_test walpersist-1.11 { list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] } {1 1 1} - +# Make sure the journal_size_limit works to limit the size of the +# persisted wal file. In persistent-wal mode, any non-negative +# journal_size_limit causes the WAL file to be truncated to zero bytes +# when closing. +# +forcedelete test.db test.db-shm test.db-wal +do_test walpersist-2.1 { + sqlite3 db test.db + db eval { + PRAGMA journal_mode=WAL; + PRAGMA wal_autocheckpoint=OFF; + PRAGMA journal_size_limit=12000; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(randomblob(50000)); + UPDATE t1 SET x=randomblob(50000); + } + expr {[file size test.db-wal]>100000} +} {1} +do_test walpersist-2.2 { + file_control_persist_wal db 1 + db close + concat [file exists test.db-wal] [file size test.db-wal] +} {1 0} +do_test walpersist-2.3 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } +} {ok} +do_test 3.1 { + catch {db close} + forcedelete test.db test.db-shm test.db-wal + sqlite3 db test.db + execsql { + PRAGMA page_size = 1024; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint=128; + PRAGMA journal_size_limit=16384; + CREATE TABLE t1(a, b, PRIMARY KEY(a, b)); + } +} {wal 128 16384} +do_test 3.2 { + for {set i 0} {$i<200} {incr i} { + execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } + } + file_control_persist_wal db 1 + db close +} {} +do_test walpersist-3.3 { + file size test.db-wal +} {0} +do_test walpersist-3.4 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } +} {ok} + finish_test diff --git a/test/whereC.test b/test/whereC.test new file mode 100644 index 0000000..9fa1bba --- /dev/null +++ b/test/whereC.test @@ -0,0 +1,70 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix whereC + +do_execsql_test 1.0 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b INTEGER); + + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 1, 1); + INSERT INTO t1 VALUES(3, 1, 2); + INSERT INTO t1 VALUES(4, 1, 2); + INSERT INTO t1 VALUES(5, 1, 2); + INSERT INTO t1 VALUES(6, 1, 3); + INSERT INTO t1 VALUES(7, 1, 3); + + INSERT INTO t1 VALUES(8, 2, 1); + INSERT INTO t1 VALUES(9, 2, 1); + INSERT INTO t1 VALUES(10, 2, 2); + INSERT INTO t1 VALUES(11, 2, 2); + INSERT INTO t1 VALUES(12, 2, 2); + INSERT INTO t1 VALUES(13, 2, 3); + INSERT INTO t1 VALUES(14, 2, 3); + + INSERT INTO t1 VALUES(15, 2, 1); + INSERT INTO t1 VALUES(16, 2, 1); + INSERT INTO t1 VALUES(17, 2, 2); + INSERT INTO t1 VALUES(18, 2, 2); + INSERT INTO t1 VALUES(19, 2, 2); + INSERT INTO t1 VALUES(20, 2, 3); + INSERT INTO t1 VALUES(21, 2, 3); + + CREATE INDEX i1 ON t1(a, b); +} + +foreach {tn sql res} { + 1 "SELECT i FROM t1 WHERE a=1 AND b=2 AND i>3" {4 5} + 2 "SELECT i FROM t1 WHERE rowid='12'" {12} + 3 "SELECT i FROM t1 WHERE a=1 AND b='2'" {3 4 5} + 4 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i>'3'" {4 5} + 5 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<5" {3 4} + 6 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<12" {10 11} + 7 "SELECT i FROM t1 WHERE a IN(1, 2) AND b=2 AND i<11" {3 4 5 10} + 8 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 12" {10 11 12} + 9 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 11 AND 12" {11 12} + 10 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 11" {10 11} + 11 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 12 AND 10" {} + 12 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i=NULL" {} + 14 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5" {3 4} +} { + do_execsql_test 1.$tn.1 $sql $res + do_execsql_test 1.$tn.2 "$sql ORDER BY i ASC" [lsort -integer -inc $res] + do_execsql_test 1.$tn.3 "$sql ORDER BY i DESC" [lsort -integer -dec $res] +} + + +finish_test + diff --git a/test/zerodamage.test b/test/zerodamage.test new file mode 100644 index 0000000..3d18c8d --- /dev/null +++ b/test/zerodamage.test @@ -0,0 +1,119 @@ +# 2011 December 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests of the SQLITE_IOCAP_POWERSAFE_OVERWRITE property +# and the SQLITE_FCNTL_POWERSAFE_OVERWRITE file-control for manipulating it. +# +# The name of this file comes from the fact that we used to call the +# POWERSAFE_OVERWRITE property ZERO_DAMAGE. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix wal5 + +ifcapable !vtab { + finish_test + return +} + +# POWERSAFE_OVERWRITE defaults to true +# +do_test zerodamage-1.0 { + file_control_powersafe_overwrite db -1 +} {0 1} + +# Check the ability to turn zero-damage on and off. +# +do_test zerodamage-1.1 { + file_control_powersafe_overwrite db 0 + file_control_powersafe_overwrite db -1 +} {0 0} +do_test zerodamage-1.2 { + file_control_powersafe_overwrite db 1 + file_control_powersafe_overwrite db -1 +} {0 1} + +# Run a transaction with zero-damage on, a small page size and a much larger +# sectorsize. Verify that the maximum journal size is small - that the +# rollback journal is not being padded. +# +do_test zerodamage-2.0 { + db close + testvfs tv -default 1 + tv sectorsize 8192 + sqlite3 db file:test.db?psow=TRUE -uri 1 + unset -nocomplain ::max_journal_size + set ::max_journal_size 0 + proc xDeleteCallback {method file args} { + set sz [file size $file] + if {$sz>$::max_journal_size} {set ::max_journal_size $sz} + } + tv filter xDelete + tv script xDeleteCallback + register_wholenumber_module db + db eval { + PRAGMA page_size=1024; + PRAGMA journal_mode=DELETE; + PRAGMA cache_size=5; + CREATE VIRTUAL TABLE nums USING wholenumber; + CREATE TABLE t1(x, y); + INSERT INTO t1 SELECT value, randomblob(100) FROM nums + WHERE value BETWEEN 1 AND 400; + } + set ::max_journal_size 0 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=123; + } + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] +} {0 1 2576} + +# Repeat the previous step with zero-damage turned off. This time the +# maximum rollback journal size should be much larger. +# +do_test zerodamage-2.1 { + set ::max_journal_size 0 + db close + sqlite3 db file:test.db?psow=FALSE -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] +} {0 0 24704} + +# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the +# WAL file does not get too big. +# +do_test zerodamage-3.0 { + db eval { + PRAGMA journal_mode=WAL; + } + db close + sqlite3 db file:test.db?psow=TRUE -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {1080} + +# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file +# is padded. +# +do_test zerodamage-3.1 { + db close + sqlite3 db file:test.db?psow=FALSE -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {8416} + +finish_test diff --git a/tool/lemon.c b/tool/lemon.c index 1fb0308..c3e612b 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -117,8 +117,6 @@ void ResortStates(struct lemon *); void SetSize(int); /* All sets will be of size N */ char *SetNew(void); /* A new set for element 0..N */ void SetFree(char*); /* Deallocate a set */ - -char *SetNew(void); /* A new set for element 0..N */ int SetAdd(char*,int); /* Add element to a set */ int SetUnion(char *,char *); /* A <- A U B, thru element N */ #define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ @@ -686,8 +684,9 @@ void FindFirstSets(struct lemon *lemp) for(rp=lemp->rule; rp; rp=rp->next){ if( rp->lhs->lambda ) continue; for(i=0; inrhs; i++){ - struct symbol *sp = rp->rhs[i]; - if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; + struct symbol *sp = rp->rhs[i]; + assert( sp->type==NONTERMINAL || sp->lambda==LEMON_FALSE ); + if( sp->lambda==LEMON_FALSE ) break; } if( i==rp->nrhs ){ rp->lhs->lambda = LEMON_TRUE; @@ -968,7 +967,7 @@ void FindFollowSets(struct lemon *lemp) }while( progress ); } -static int resolve_conflict(struct action *,struct action *, struct symbol *); +static int resolve_conflict(struct action *,struct action *); /* Compute the reduce actions, and resolve conflicts. */ @@ -1022,7 +1021,7 @@ void FindActions(struct lemon *lemp) for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ /* The two actions "ap" and "nap" have the same lookahead. ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); + lemp->nconflict += resolve_conflict(ap,nap); } } } @@ -1057,8 +1056,7 @@ void FindActions(struct lemon *lemp) */ static int resolve_conflict( struct action *apx, - struct action *apy, - struct symbol *errsym /* The error symbol (if defined. NULL otherwise) */ + struct action *apy ){ struct symbol *spx, *spy; int errcnt = 0; @@ -1995,7 +1993,7 @@ static void parseonetoken(struct pstate *psp) }else if( x[0]=='{' ){ if( psp->prevrule==0 ){ ErrorMsg(psp->filename,psp->tokenlineno, -"There is no prior rule opon which to attach the code \ +"There is no prior rule upon which to attach the code \ fragment which begins on this line."); psp->errorcnt++; }else if( psp->prevrule->code!=0 ){